Files
codexbar-mobile/lib/api/claudeApi.ts
T
space ba7d957155
CodexBar Mobile Build / build-android (push) Failing after 1m38s
CodexBar Mobile Build / release (push) Has been skipped
Maximus upgradus
2026-06-24 20:16:34 +02:00

54 lines
1.7 KiB
TypeScript

import type { ClaudeAuth, ClaudeOrg, ClaudeUsageResponse } from "@/types/claude";
const BASE_URL = "https://claude.ai/api";
const BROWSER_UA =
"Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36";
function buildHeaders(auth: ClaudeAuth): Record<string, string> {
const cookies = [`sessionKey=${auth.sessionKey}`];
if (auth.lastActiveOrg) cookies.push(`lastActiveOrg=${auth.lastActiveOrg}`);
return {
Cookie: cookies.join("; "),
Accept: "application/json, text/plain, */*",
"Accept-Language": "en-US,en;q=0.9",
"User-Agent": BROWSER_UA,
Referer: "https://claude.ai/",
Origin: "https://claude.ai",
"anthropic-client-platform": "web_claude_to_cc_migration",
};
}
export async function fetchClaudeOrgs(auth: ClaudeAuth): Promise<ClaudeOrg[]> {
const response = await fetch(`${BASE_URL}/organizations`, {
headers: buildHeaders(auth),
credentials: "omit",
});
if (!response.ok) {
await response.text().catch(() => null);
if (response.status === 401 || response.status === 403) throw new Error("TOKEN_EXPIRED");
throw new Error(`HTTP_ERROR_${response.status}`);
}
return response.json() as Promise<ClaudeOrg[]>;
}
export async function fetchClaudeUsage(
auth: ClaudeAuth,
orgUuid: string
): Promise<ClaudeUsageResponse> {
const response = await fetch(`${BASE_URL}/organizations/${orgUuid}/usage`, {
headers: buildHeaders(auth),
credentials: "omit",
});
if (!response.ok) {
await response.text().catch(() => null);
if (response.status === 401 || response.status === 403) throw new Error("TOKEN_EXPIRED");
throw new Error(`HTTP_ERROR_${response.status}`);
}
return response.json() as Promise<ClaudeUsageResponse>;
}