Spaces:
Sleeping
Sleeping
File size: 4,532 Bytes
61b1da1 a5d1c1b 071f828 61b1da1 071f828 a5d1c1b 071f828 61b1da1 a5d1c1b 071f828 61b1da1 a5d1c1b 071f828 61b1da1 a5d1c1b 61b1da1 a5d1c1b 071f828 61b1da1 a5d1c1b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | import { RepoMetadata, FilesResponse, SearchResponse } from '@ever-brain/api/contract';
export class CliApiClient {
constructor(private baseUrl: string) {}
setBaseUrl(url: string): void {
this.baseUrl = url;
}
private cleanUrl(endpoint: string): string {
return `${this.baseUrl.replace(/\/+$/, '')}${endpoint}`;
}
private async safeFetch(url: string, init?: RequestInit): Promise<Response> {
try {
return await fetch(url, init);
} catch (err: unknown) {
const errorMsg = err instanceof Error ? err.message : String(err);
throw new Error(
`Cannot connect to Ever-Brain API at ${this.baseUrl} (${errorMsg}).\n` +
`Is the Ever-Brain server running? Start it with 'pnpm dev' (or configure --api-url / EVB_API_URL).`
);
}
}
async getRepoMetadata(owner: string, repo: string): Promise<RepoMetadata> {
const url = this.cleanUrl(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`);
const res = await this.safeFetch(url, {
headers: { 'User-Agent': 'Ever-Brain-CLI/1.0', Accept: 'application/json' },
});
if (!res.ok) {
let message = `Failed to resolve repository ${owner}/${repo} (${res.status})`;
try {
const body = (await res.json()) as { error?: string };
if (body.error) message = body.error;
} catch {}
throw new Error(message);
}
return (await res.json()) as RepoMetadata;
}
async getFiles(
owner: string,
repo: string,
prefix?: string,
fresh?: boolean,
branch?: string
): Promise<FilesResponse> {
const params = new URLSearchParams();
if (prefix) params.set('prefix', prefix);
if (fresh) params.set('fresh', 'true');
if (branch) params.set('branch', branch);
const queryString = params.toString() ? `?${params.toString()}` : '';
const url = this.cleanUrl(
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/files${queryString}`
);
const res = await this.safeFetch(url, {
headers: { 'User-Agent': 'Ever-Brain-CLI/1.0', Accept: 'application/json' },
});
if (!res.ok) {
let message = `Failed to fetch files for ${owner}/${repo} (${res.status})`;
try {
const body = (await res.json()) as { error?: string };
if (body.error) message = body.error;
} catch {}
throw new Error(message);
}
return (await res.json()) as FilesResponse;
}
async getFileContent(
owner: string,
repo: string,
filePath: string,
branch?: string
): Promise<{ content: string; exactPath: string; branch: string }> {
const cleanPath = filePath.replace(/^\/+/, '');
const params = new URLSearchParams();
if (branch) params.set('branch', branch);
const queryString = params.toString() ? `?${params.toString()}` : '';
const url = this.cleanUrl(
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/file/${cleanPath}${queryString}`
);
const res = await this.safeFetch(url, {
headers: { 'User-Agent': 'Ever-Brain-CLI/1.0' },
});
if (!res.ok) {
let message = `File '${cleanPath}' not found in ${owner}/${repo}`;
try {
const body = (await res.json()) as { error?: string };
if (body.error) message = body.error;
} catch {}
throw new Error(message);
}
const content = await res.text();
const exactPath = res.headers.get('x-ever-brain-path') || cleanPath;
const resolvedBranch = res.headers.get('x-ever-brain-branch') || branch || 'main';
return {
content,
exactPath,
branch: resolvedBranch,
};
}
async searchFiles(
owner: string,
repo: string,
query: string,
prefix?: string,
branch?: string
): Promise<SearchResponse> {
const params = new URLSearchParams({ q: query });
if (prefix) params.set('prefix', prefix);
if (branch) params.set('branch', branch);
const url = this.cleanUrl(
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/search?${params.toString()}`
);
const res = await this.safeFetch(url, {
headers: { 'User-Agent': 'Ever-Brain-CLI/1.0', Accept: 'application/json' },
});
if (!res.ok) {
let message = `Search failed for ${owner}/${repo} (${res.status})`;
try {
const body = (await res.json()) as { error?: string };
if (body.error) message = body.error;
} catch {}
throw new Error(message);
}
return (await res.json()) as SearchResponse;
}
}
|