feat(ext/sw): GitHost.lastCommit() for vault-presence metadata

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-27 17:48:24 -04:00
parent 7588a75bdc
commit 2c94dfaf90
4 changed files with 103 additions and 2 deletions

View File

@@ -16,14 +16,17 @@ import { uint8ArrayToBase64, base64ToUint8Array, BLOB_THRESHOLD_BYTES } from './
export class GiteaHost implements GitHost {
private baseUrl: string;
private gitApiBase: string;
private commitsUrl: string;
private branch: string = 'main';
private headers: Record<string, string>;
constructor(hostUrl: string, repoPath: string, apiToken: string) {
// Remove trailing slash from hostUrl
const host = hostUrl.replace(/\/+$/, '');
this.baseUrl = `${host}/api/v1/repos/${repoPath}/contents`;
this.gitApiBase = `${host}/api/v1/repos/${repoPath}/git`;
const apiUrl = `${host}/api/v1`;
this.baseUrl = `${apiUrl}/repos/${repoPath}/contents`;
this.gitApiBase = `${apiUrl}/repos/${repoPath}/git`;
this.commitsUrl = `${apiUrl}/repos/${repoPath}/commits`;
this.headers = {
'Authorization': `token ${apiToken}`,
'Content-Type': 'application/json',
@@ -115,6 +118,24 @@ export class GiteaHost implements GitHost {
return json.map((item: { name: string }) => item.name);
}
async lastCommit(path: string): Promise<{ sha: string; author: string; date: string } | null> {
try {
const url = `${this.commitsUrl}?path=${encodeURIComponent(path)}&limit=1`;
const resp = await fetch(url, { headers: this.headers });
if (!resp.ok) return null;
const json = await resp.json();
if (!Array.isArray(json) || json.length === 0) return null;
const c = json[0];
return {
sha: String(c.sha).slice(0, 7),
author: c.commit?.author?.name ?? 'unknown',
date: c.commit?.author?.date ?? '',
};
} catch {
return null;
}
}
async putBlob(path: string, content: Uint8Array, message: string): Promise<string> {
if (content.length <= BLOB_THRESHOLD_BYTES) {
await this.writeFile(path, content, message);