/** * DSS API Client * * Communicates with the DSS server. */ import { getConfig } from './config.js'; export interface ApiOptions { port?: number; baseUrl?: string; } export class DSSApiClient { private baseUrl: string; constructor(options: ApiOptions = {}) { const config = getConfig(); const port = options.port || config.port || 3456; this.baseUrl = options.baseUrl || `http://localhost:${port}/api`; } private async request( endpoint: string, options: RequestInit = {} ): Promise { const url = `${this.baseUrl}${endpoint}`; const response = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...options.headers, }, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ message: response.statusText })) as { message?: string }; throw new Error(errorData.message || `Request failed: ${response.status}`); } const text = await response.text(); return text ? JSON.parse(text) as T : {} as T; } async health(): Promise<{ status: string; figma_mode: string }> { // Health endpoint is at root, not under /api const url = this.baseUrl.replace('/api', '') + '/health'; const response = await fetch(url); return response.json() as Promise<{ status: string; figma_mode: string }>; } async getConfig(): Promise> { return this.request('/config'); } async setFigmaToken(token: string): Promise { await this.request('/config', { method: 'PUT', body: JSON.stringify({ figma_token: token }), }); } async testFigmaConnection(): Promise<{ success: boolean; user?: string; error?: string }> { return this.request('/config/figma/test', { method: 'POST' }); } async extractTokens(fileKey: string, format: string = 'css'): Promise<{ success: boolean; tokens_count: number; tokens: Array<{ name: string; value: string; type: string; category: string }>; formatted_output: string; output_path: string; }> { return this.request('/figma/extract-variables', { method: 'POST', body: JSON.stringify({ file_key: fileKey, format }), }); } async extractComponents(fileKey: string): Promise<{ success: boolean; components_count: number; components: Array<{ name: string; key: string; description: string; variants: string[] }>; output_path: string; }> { return this.request('/figma/extract-components', { method: 'POST', body: JSON.stringify({ file_key: fileKey }), }); } async syncTokens(fileKey: string, targetPath: string, format: string = 'css'): Promise<{ success: boolean; tokens_synced: number; output_file: string; }> { return this.request('/figma/sync-tokens', { method: 'POST', body: JSON.stringify({ file_key: fileKey, target_path: targetPath, format }), }); } async generateCode(fileKey: string, componentName: string, framework: string = 'react'): Promise<{ success: boolean; component: string; framework: string; code: string; }> { return this.request('/figma/generate-code', { method: 'POST', body: JSON.stringify({ file_key: fileKey, component_name: componentName, framework }), }); } async getProjects(): Promise> { return this.request('/projects'); } async createProject(data: { name: string; description?: string; figma_file_key?: string; }): Promise<{ id: string; name: string }> { return this.request('/projects', { method: 'POST', body: JSON.stringify(data), }); } } // Singleton instance let apiClient: DSSApiClient | null = null; export function getApiClient(options?: ApiOptions): DSSApiClient { if (!apiClient || options) { apiClient = new DSSApiClient(options); } return apiClient; }