|
import { HUB_URL } from "../consts"; |
|
import { createApiError } from "../error"; |
|
import type { ApiCommitData } from "../types/api/api-commit"; |
|
import type { CredentialsParams, RepoDesignation } from "../types/public"; |
|
import { checkCredentials } from "../utils/checkCredentials"; |
|
import { parseLinkHeader } from "../utils/parseLinkHeader"; |
|
import { toRepoId } from "../utils/toRepoId"; |
|
|
|
export interface CommitData { |
|
oid: string; |
|
title: string; |
|
message: string; |
|
authors: Array<{ username: string; avatarUrl: string }>; |
|
date: Date; |
|
} |
|
|
|
export async function* listCommits( |
|
params: { |
|
repo: RepoDesignation; |
|
|
|
|
|
|
|
revision?: string; |
|
hubUrl?: string; |
|
|
|
|
|
|
|
batchSize?: number; |
|
|
|
|
|
|
|
fetch?: typeof fetch; |
|
} & Partial<CredentialsParams> |
|
): AsyncGenerator<CommitData> { |
|
const accessToken = checkCredentials(params); |
|
const repoId = toRepoId(params.repo); |
|
|
|
|
|
let url: string | undefined = `${params.hubUrl ?? HUB_URL}/api/${repoId.type}s/${repoId.name}/commits/${ |
|
params.revision ?? "main" |
|
}?limit=${params.batchSize ?? 100}`; |
|
|
|
while (url) { |
|
const res: Response = await (params.fetch ?? fetch)(url, { |
|
headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {}, |
|
}); |
|
|
|
if (!res.ok) { |
|
throw await createApiError(res); |
|
} |
|
|
|
const resJson: ApiCommitData[] = await res.json(); |
|
for (const commit of resJson) { |
|
yield { |
|
oid: commit.id, |
|
title: commit.title, |
|
message: commit.message, |
|
authors: commit.authors.map((author) => ({ |
|
username: author.user, |
|
avatarUrl: author.avatar, |
|
})), |
|
date: new Date(commit.date), |
|
}; |
|
} |
|
|
|
const linkHeader = res.headers.get("Link"); |
|
|
|
url = linkHeader ? parseLinkHeader(linkHeader).next : undefined; |
|
} |
|
} |
|
|