Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
delegator
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi committed Mar 20, 2023
1 parent f2f8861 commit 138fe69
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
6 changes: 4 additions & 2 deletions server/PathInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export function parsePathInfo(src: string): PathInfo | undefined {
export function fromPathInfo(
{ vCapi, generatorId, providerId, target, vRuntime, filePath }: PathInfo,
): string {
let src = vCapi ? `/@${vCapi}/` : "/"
src += [generatorId, providerId].join("/")
let src = ""
if (vCapi) src += `/@${vCapi}`
src += `/${generatorId}`
src += `/${providerId}`
if (target) src += `/${target}`
if (vRuntime) src += `/@${vRuntime}`
if (filePath) src += `/${filePath}`
Expand Down
79 changes: 78 additions & 1 deletion server/capi.dev/delegator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,80 @@
import { serve } from "../../deps/std/http.ts"
import { TimedMemo } from "../../util/memo.ts"
import { f, handleErrors } from "../mod.ts"

serve(() => new Response("delegator"))
serve(handleErrors(handler))

const delegateeProjectId = "70eddd08-c9b0-4cb3-b100-8c6facf52f1e"

const shaAbbrevLength = 8

const GITHUB_API_REPO = "https://api.github.com/repos/paritytech/capi"

const rTagVersion = /^v(\d+\.\d+\.\d+(?:-.+)?)$/
const rPrVersion = /^pr:(\d+)$/

const rVersionedUrl = /^(?:\/@(.+?))?(\/.*)?$/

const { signal } = new AbortController()

async function handler(request: Request) {
const url = new URL(request.url)
const [, version, path = "/"] = rVersionedUrl.exec(url.pathname)!
if (!version) throw f.notFound()
const sha = await getSha(version)
let normalizedVersion
if (rTagVersion.test(version)) {
normalizedVersion = version.replace(rTagVersion, "v$1")
} else {
normalizedVersion = sha.slice(0, shaAbbrevLength)
}
if (version !== normalizedVersion) {
return f.redirect(`/@${normalizedVersion}${path}`)
}
const deploymentUrl = await getDeployment(sha)
return await fetch(new URL(path, deploymentUrl))
}

const shaTtl = 60_000
const shaMemo = new TimedMemo<string, string>(shaTtl, signal)
async function getSha(version: string): Promise<string> {
const ref = version
.replace(rPrVersion, "pull/$1/head")
.replace(rTagVersion, "v$1")
.replace(/:/g, "/")
return await shaMemo.run(
ref,
async () => (await json(`${GITHUB_API_REPO}/commits/${ref}`)).sha,
)
}

const deploymentTtl = 60_000
const deploymentMemo = new TimedMemo<string, string>(deploymentTtl, signal)
async function getDeployment(sha: string) {
return await deploymentMemo.run(sha, async () => {
const deployments: GithubDeployment[] = await json(
`${GITHUB_API_REPO}/deployments?sha=${sha}`,
)
const deployment = deployments.find((x) => x.payload.project_id === delegateeProjectId)
if (!deployment) throw f.notFound()
const statuses: GithubStatus[] = await json(deployment.statuses_url)
const url = statuses.map((x) => x.environment_url).find((x) => x)
if (!url) throw f.notFound()
return url
})
}

async function json(url: string) {
const response = await fetch(url)
if (!response.ok) throw new Error(`${url}: invalid response`)
return await response.json()
}

interface GithubDeployment {
statuses_url: string
payload: { project_id: string }
}

interface GithubStatus {
environment_url?: string
}
12 changes: 12 additions & 0 deletions server/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ export function handler(env: Env): Handler {
}

const staticDirs = ["../", "./static/"].map((p) => import.meta.resolve(p))

export function handleErrors(handler: (request: Request) => Promise<Response>) {
return async (request: Request) => {
try {
return await handler(request)
} catch (e) {
if (e instanceof Response) return e.clone()
console.error(e)
return f.serverError(Deno.inspect(e))
}
}
}
1 change: 1 addition & 0 deletions server/mod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./Env.ts"
export * as f from "./factories.ts"
export * from "./handler.ts"
export * from "./PathInfo.ts"
export * from "./Provider.ts"

0 comments on commit 138fe69

Please sign in to comment.