mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
refactor(ui): unify api base path for cursor and copilot hooks
- add withApiBase helper and use it across fetch calls - remove duplicated API base literals in cursor/copilot hooks - expose cursor default port from shared ui defaults module
This commit is contained in:
+12
-13
@@ -6,8 +6,7 @@
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
const API_BASE = '/api';
|
||||
import { withApiBase } from '@/lib/api-client';
|
||||
|
||||
// Types
|
||||
export interface CopilotStatus {
|
||||
@@ -80,31 +79,31 @@ export interface CopilotRawSettings {
|
||||
|
||||
// API functions
|
||||
async function fetchCopilotStatus(): Promise<CopilotStatus> {
|
||||
const res = await fetch(`${API_BASE}/copilot/status`);
|
||||
const res = await fetch(withApiBase('/copilot/status'));
|
||||
if (!res.ok) throw new Error('Failed to fetch copilot status');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCopilotConfig(): Promise<CopilotConfig> {
|
||||
const res = await fetch(`${API_BASE}/copilot/config`);
|
||||
const res = await fetch(withApiBase('/copilot/config'));
|
||||
if (!res.ok) throw new Error('Failed to fetch copilot config');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCopilotModels(): Promise<{ models: CopilotModel[]; current: string }> {
|
||||
const res = await fetch(`${API_BASE}/copilot/models`);
|
||||
const res = await fetch(withApiBase('/copilot/models'));
|
||||
if (!res.ok) throw new Error('Failed to fetch copilot models');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCopilotRawSettings(): Promise<CopilotRawSettings> {
|
||||
const res = await fetch(`${API_BASE}/copilot/settings/raw`);
|
||||
const res = await fetch(withApiBase('/copilot/settings/raw'));
|
||||
if (!res.ok) throw new Error('Failed to fetch copilot raw settings');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function updateCopilotConfig(config: Partial<CopilotConfig>): Promise<{ success: boolean }> {
|
||||
const res = await fetch(`${API_BASE}/copilot/config`, {
|
||||
const res = await fetch(withApiBase('/copilot/config'), {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config),
|
||||
@@ -117,7 +116,7 @@ async function saveCopilotRawSettings(data: {
|
||||
settings: CopilotRawSettings['settings'];
|
||||
expectedMtime?: number;
|
||||
}): Promise<{ success: boolean; mtime: number }> {
|
||||
const res = await fetch(`${API_BASE}/copilot/settings/raw`, {
|
||||
const res = await fetch(withApiBase('/copilot/settings/raw'), {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
@@ -135,31 +134,31 @@ export interface CopilotAuthResult {
|
||||
}
|
||||
|
||||
async function startCopilotAuth(): Promise<CopilotAuthResult> {
|
||||
const res = await fetch(`${API_BASE}/copilot/auth/start`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/copilot/auth/start'), { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Failed to start auth');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function startCopilotDaemon(): Promise<{ success: boolean; pid?: number; error?: string }> {
|
||||
const res = await fetch(`${API_BASE}/copilot/daemon/start`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/copilot/daemon/start'), { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Failed to start daemon');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function stopCopilotDaemon(): Promise<{ success: boolean; error?: string }> {
|
||||
const res = await fetch(`${API_BASE}/copilot/daemon/stop`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/copilot/daemon/stop'), { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Failed to stop daemon');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCopilotInfo(): Promise<CopilotInfo> {
|
||||
const res = await fetch(`${API_BASE}/copilot/info`);
|
||||
const res = await fetch(withApiBase('/copilot/info'));
|
||||
if (!res.ok) throw new Error('Failed to fetch copilot info');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function installCopilotApi(version?: string): Promise<CopilotInstallResult> {
|
||||
const res = await fetch(`${API_BASE}/copilot/install`, {
|
||||
const res = await fetch(withApiBase('/copilot/install'), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(version ? { version } : {}),
|
||||
|
||||
+12
-11
@@ -6,8 +6,9 @@
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { withApiBase } from '@/lib/api-client';
|
||||
|
||||
const API_BASE = '/api';
|
||||
export { DEFAULT_CURSOR_PORT } from '@/lib/default-ports';
|
||||
|
||||
export interface CursorStatus {
|
||||
enabled: boolean;
|
||||
@@ -59,25 +60,25 @@ interface CursorAuthResult {
|
||||
}
|
||||
|
||||
async function fetchCursorStatus(): Promise<CursorStatus> {
|
||||
const res = await fetch(`${API_BASE}/cursor/status`);
|
||||
const res = await fetch(withApiBase('/cursor/status'));
|
||||
if (!res.ok) throw new Error('Failed to fetch cursor status');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCursorConfig(): Promise<CursorConfig> {
|
||||
const res = await fetch(`${API_BASE}/cursor/settings`);
|
||||
const res = await fetch(withApiBase('/cursor/settings'));
|
||||
if (!res.ok) throw new Error('Failed to fetch cursor config');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCursorModels(): Promise<CursorModelsResponse> {
|
||||
const res = await fetch(`${API_BASE}/cursor/models`);
|
||||
const res = await fetch(withApiBase('/cursor/models'));
|
||||
if (!res.ok) throw new Error('Failed to fetch cursor models');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function fetchCursorRawSettings(): Promise<CursorRawSettings> {
|
||||
const res = await fetch(`${API_BASE}/cursor/settings/raw`);
|
||||
const res = await fetch(withApiBase('/cursor/settings/raw'));
|
||||
if (!res.ok) throw new Error('Failed to fetch cursor raw settings');
|
||||
return res.json();
|
||||
}
|
||||
@@ -85,7 +86,7 @@ async function fetchCursorRawSettings(): Promise<CursorRawSettings> {
|
||||
async function updateCursorConfig(
|
||||
updates: Partial<CursorConfig>
|
||||
): Promise<{ success: boolean; cursor: CursorConfig }> {
|
||||
const res = await fetch(`${API_BASE}/cursor/settings`, {
|
||||
const res = await fetch(withApiBase('/cursor/settings'), {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(updates),
|
||||
@@ -98,7 +99,7 @@ async function saveCursorRawSettings(data: {
|
||||
settings: CursorRawSettings['settings'];
|
||||
expectedMtime?: number;
|
||||
}): Promise<{ success: boolean; mtime: number }> {
|
||||
const res = await fetch(`${API_BASE}/cursor/settings/raw`, {
|
||||
const res = await fetch(withApiBase('/cursor/settings/raw'), {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
@@ -109,7 +110,7 @@ async function saveCursorRawSettings(data: {
|
||||
}
|
||||
|
||||
async function autoDetectCursorAuth(): Promise<CursorAuthResult> {
|
||||
const res = await fetch(`${API_BASE}/cursor/auth/auto-detect`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/cursor/auth/auto-detect'), { method: 'POST' });
|
||||
if (!res.ok) {
|
||||
const error = await res.json().catch(() => ({ error: 'Auto-detect failed' }));
|
||||
throw new Error(error.error || 'Auto-detect failed');
|
||||
@@ -121,7 +122,7 @@ async function importCursorAuthManual(data: {
|
||||
accessToken: string;
|
||||
machineId: string;
|
||||
}): Promise<CursorAuthResult> {
|
||||
const res = await fetch(`${API_BASE}/cursor/auth/import`, {
|
||||
const res = await fetch(withApiBase('/cursor/auth/import'), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
@@ -134,13 +135,13 @@ async function importCursorAuthManual(data: {
|
||||
}
|
||||
|
||||
async function startCursorDaemon(): Promise<{ success: boolean; pid?: number; error?: string }> {
|
||||
const res = await fetch(`${API_BASE}/cursor/daemon/start`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/cursor/daemon/start'), { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Failed to start cursor daemon');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function stopCursorDaemon(): Promise<{ success: boolean; error?: string }> {
|
||||
const res = await fetch(`${API_BASE}/cursor/daemon/stop`, { method: 'POST' });
|
||||
const res = await fetch(withApiBase('/cursor/daemon/stop'), { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Failed to stop cursor daemon');
|
||||
return res.json();
|
||||
}
|
||||
|
||||
@@ -5,10 +5,14 @@
|
||||
|
||||
import type { CLIProxyProvider } from './provider-config';
|
||||
|
||||
const BASE_URL = '/api';
|
||||
export const API_BASE_URL = '/api';
|
||||
|
||||
export function withApiBase(path: string): string {
|
||||
return `${API_BASE_URL}${path}`;
|
||||
}
|
||||
|
||||
async function request<T>(url: string, options?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${BASE_URL}${url}`, {
|
||||
const res = await fetch(withApiBase(url), {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
...options,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user