48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
import { isRecord } from '@/lib/guards'
|
|
import type { GitRemoteConfig } from './types'
|
|
|
|
export class GitApiError extends Error {
|
|
constructor(message: string, public status: number) {
|
|
super(message)
|
|
}
|
|
}
|
|
|
|
export function isHttpError(err: unknown): err is { status: number } {
|
|
return isRecord(err) && typeof err.status === 'number'
|
|
}
|
|
|
|
export function encodePath(path: string) {
|
|
return path.split('/').map(encodeURIComponent).join('/')
|
|
}
|
|
|
|
export function getRepoApiPath(remote: GitRemoteConfig) {
|
|
return `/repos/${encodeURIComponent(remote.owner)}/${encodeURIComponent(remote.repo)}`
|
|
}
|
|
|
|
export function decodeBase64Content(content: string) {
|
|
return Buffer.from(content.replace(/\s/g, ''), 'base64').toString('utf-8')
|
|
}
|
|
|
|
export async function requestGitJson(
|
|
remote: GitRemoteConfig,
|
|
path: string,
|
|
init: { method?: string; body?: unknown } = {},
|
|
): Promise<unknown> {
|
|
const res = await fetch(`${remote.apiBaseUrl}${path}`, {
|
|
method: init.method ?? 'GET',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `token ${remote.token}`,
|
|
},
|
|
body: init.body === undefined ? undefined : JSON.stringify(init.body),
|
|
})
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text()
|
|
throw new GitApiError(text || `Git API request failed (${res.status})`, res.status)
|
|
}
|
|
|
|
return res.json()
|
|
}
|