mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
import { raiseError } from 'analytics'
|
|
import { errors } from 'platforms'
|
|
import { is } from 'utils/is'
|
|
import { gitakoServiceHost } from 'utils/networkService'
|
|
|
|
function isEmptyProject(content: JSONValue) {
|
|
return is.JSON.object(content) && content?.['message'] === 'Git Repository is empty.'
|
|
}
|
|
|
|
function isBlockedProject(content: JSONValue) {
|
|
return is.JSON.object(content) && content?.['message'] === 'Repository access blocked'
|
|
}
|
|
|
|
async function request(
|
|
url: string,
|
|
{
|
|
accessToken,
|
|
}: {
|
|
accessToken?: string
|
|
} = {},
|
|
) {
|
|
const headers: HeadersInit & {
|
|
Authorization?: string
|
|
} = {}
|
|
if (accessToken) {
|
|
headers.Authorization = `token ${accessToken}`
|
|
}
|
|
|
|
let res: Response
|
|
try {
|
|
res = await fetch(url, { headers })
|
|
} catch (err) {
|
|
throw new Error(errors.CONNECTION_BLOCKED)
|
|
}
|
|
|
|
const contentType = res.headers.get('Content-Type') || res.headers.get('content-type')
|
|
if (!contentType) {
|
|
throw new Error(`Response has no content type`)
|
|
} else if (!contentType.includes('application/json')) {
|
|
throw new Error(`Response content type is ${contentType}`)
|
|
}
|
|
|
|
// About res.ok:
|
|
// True if res.status between 200~299
|
|
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/Response/ok
|
|
if (res.ok) {
|
|
return res.json()
|
|
} else {
|
|
if (res.status === 404 || res.status === 401) throw new Error(errors.NOT_FOUND)
|
|
else if (res.status === 500) throw new Error(errors.SERVER_FAULT)
|
|
else {
|
|
const content = await res.json()
|
|
if (isEmptyProject(content)) throw new Error(errors.EMPTY_PROJECT)
|
|
if (isBlockedProject(content)) throw new Error(errors.BLOCKED_PROJECT)
|
|
// Unknown type of error, report it!
|
|
raiseError(new Error(res.statusText))
|
|
throw new Error(content && content.message)
|
|
}
|
|
}
|
|
}
|
|
|
|
export const API_ENDPOINT = `${window.location.origin}/api/v1`
|
|
|
|
export async function getRepoMeta(
|
|
userName: string,
|
|
repoName: string,
|
|
accessToken?: string,
|
|
): Promise<GiteaAPI.MetaData> {
|
|
const url = `${API_ENDPOINT}/repos/${userName}/${repoName}`
|
|
return await request(url, { accessToken })
|
|
}
|
|
|
|
export async function getTreeData(
|
|
userName: string,
|
|
repoName: string,
|
|
branchName: string,
|
|
recursive?: boolean,
|
|
accessToken?: string,
|
|
): Promise<GiteaAPI.TreeData> {
|
|
const search = new URLSearchParams()
|
|
if (recursive) search.set('recursive', '1')
|
|
const url = `${API_ENDPOINT}/repos/${userName}/${repoName}/git/trees/${branchName}?${search}`
|
|
return await request(url, { accessToken })
|
|
}
|
|
|
|
export async function getBlobData(
|
|
userName: string,
|
|
repoName: string,
|
|
sha: string,
|
|
accessToken?: string,
|
|
): Promise<GitHubAPI.BlobData> {
|
|
const url = `${API_ENDPOINT}/repos/${userName}/${repoName}/git/blobs/${sha}`
|
|
return await request(url, { accessToken })
|
|
}
|
|
|
|
export async function OAuth(code: string): Promise<string | null> {
|
|
const endpoint = `https://${gitakoServiceHost}/oauth/gitea?${new URLSearchParams({ code })}`
|
|
const res = await fetch(endpoint, {
|
|
method: 'post',
|
|
})
|
|
|
|
if (res.ok) {
|
|
const body = await res.json()
|
|
const accessToken = body?.accessToken
|
|
if (typeof accessToken === 'string') return accessToken
|
|
}
|
|
return null
|
|
}
|