Zachary Shilton a906a1b426
docs: Enable docs from remote plugin (#10656)
* Add local components to build on new DocsPage functionality.

* Add new nav-data format, and placeholder remote-plugins config

* Bump to pre-release components and implement remote loading

- Migrates /docs to new DocsPage API, and adds remote plugin loading functionality
- Migrates /guides and /intro to new DocsPage API

* Remove now unused JS nav config

* Cut empty comment line
2021-03-03 10:13:50 -05:00

72 lines
1.9 KiB
JavaScript

const fetch = require('isomorphic-unfetch')
const GITHUB_API_TOKEN = process.env.GITHUB_API_TOKEN
async function githubQuery(body, token) {
const result = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
Authorization: `bearer ${token}`,
ContentType: 'application/json',
},
body: JSON.stringify(body),
})
return await result.json()
}
// Fetch a file from GitHub using the GraphQL API
async function getGithubFile({ repo, branch, filePath }) {
const [repo_owner, repo_name] = repo.split('/')
// Set up the GraphQL query
// (usually we can keep this in a separate file, and rely on a
// plaintext loader we've set up in our NextJS config, but we need
// to fetch remote content when indexing it, which happens outside
// NextJS, so unfortunately it seems this has to be inlined)
const query = `
query($repo_name: String!, $repo_owner: String!, $object_expression: String!) {
repository(name: $repo_name, owner: $repo_owner) {
object(expression: $object_expression) {
... on Blob {
text
}
}
}
}
`
// Set variables
const variables = {
repo_name,
repo_owner,
object_expression: `${branch}:${filePath}`,
}
// Query the GitHub API, and parse the navigation data
const result = await githubQuery({ query, variables }, GITHUB_API_TOKEN)
try {
const fileText = result.data.repository.object.text
return [null, fileText]
} catch (e) {
const errorMsg = `Could not fetch remote file text from "${
variables.object_expression
}" in "${repo_owner}/${repo_name}". Received instead:\n\n${JSON.stringify(
result,
null,
2
)}`
return [errorMsg, null]
}
}
function memoize(method) {
let cache = {}
return async function () {
let args = JSON.stringify(arguments[0])
if (!cache[args]) {
cache[args] = method.apply(this, arguments)
}
return cache[args]
}
}
module.exports = memoize(getGithubFile)