项目文件夹

文件
wehub-resource-sync 98e40dac97
CLI Smoke Test / smoke-test-linux (20) (push) Has been cancelled
CLI Smoke Test / smoke-test-linux (24) (push) Has been cancelled
CLI Smoke Test / smoke-test-windows (20) (push) Has been cancelled
CLI Smoke Test / smoke-test-windows (24) (push) Has been cancelled
Expo App TypeScript typecheck / typecheck (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:40:49 +08:00

106 行
3.2 KiB
TypeScript

import { AuthCredentials } from '@/auth/tokenStorage';
import { backoff } from '@/utils/time';
import { getServerUrl } from './serverConfig';
import { getHappyClientId } from './apiSocket';
export interface GitHubOAuthParams {
url: string;
}
export interface GitHubProfile {
id: number;
login: string;
name: string;
avatar_url: string;
email?: string;
}
export interface AccountProfile {
id: string;
timestamp: number;
github: GitHubProfile | null;
}
/**
* Get GitHub OAuth parameters from the server
*/
export async function getGitHubOAuthParams(credentials: AuthCredentials): Promise<GitHubOAuthParams> {
const API_ENDPOINT = getServerUrl();
return await backoff(async () => {
const response = await fetch(`${API_ENDPOINT}/v1/connect/github/params`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${credentials.token}`,
'Content-Type': 'application/json',
'X-Happy-Client': getHappyClientId(),
}
});
if (!response.ok) {
if (response.status === 400) {
const error = await response.json();
throw new Error(error.error || 'GitHub OAuth not configured');
}
throw new Error(`Failed to get GitHub OAuth params: ${response.status}`);
}
const data = await response.json() as GitHubOAuthParams;
return data;
});
}
/**
* Get account profile including GitHub connection status
*/
export async function getAccountProfile(credentials: AuthCredentials): Promise<AccountProfile> {
const API_ENDPOINT = getServerUrl();
return await backoff(async () => {
const response = await fetch(`${API_ENDPOINT}/v1/account/profile`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${credentials.token}`,
'Content-Type': 'application/json',
'X-Happy-Client': getHappyClientId(),
}
});
if (!response.ok) {
throw new Error(`Failed to get account profile: ${response.status}`);
}
const data = await response.json() as AccountProfile;
return data;
});
}
/**
* Disconnect GitHub account from the user's profile
*/
export async function disconnectGitHub(credentials: AuthCredentials): Promise<void> {
const API_ENDPOINT = getServerUrl();
return await backoff(async () => {
const response = await fetch(`${API_ENDPOINT}/v1/connect/github`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${credentials.token}`,
'X-Happy-Client': getHappyClientId(),
}
});
if (!response.ok) {
if (response.status === 404) {
const error = await response.json();
throw new Error(error.error || 'GitHub account not connected');
}
throw new Error(`Failed to disconnect GitHub: ${response.status}`);
}
const data = await response.json() as { success: true };
if (!data.success) {
throw new Error('Failed to disconnect GitHub account');
}
});
}