/ src / http.ts
http.ts
 1  import fetch from 'node-fetch';
 2  import { getBaseUrl, getToken } from './config.js';
 3  
 4  export interface HttpOptions {
 5    method?: string;
 6    body?: unknown;
 7    headers?: Record<string, string>;
 8  }
 9  
10  export async function request(path: string, options: HttpOptions = {}) {
11    const baseUrl = getBaseUrl();
12    const token = getToken();
13    
14    // Ensure path starts with /api/v5 if not already present
15    let apiPath = path;
16    if (!path.startsWith('/api/')) {
17      apiPath = `/api/v5${path.startsWith('/') ? '' : '/'}${path}`;
18    }
19    
20    const url = `${baseUrl.replace(/\/$/, '')}${apiPath}`;
21  
22    const headers: Record<string, string> = {
23      'Accept': 'application/json',
24      'User-Agent': 'atomgit-cli/0.1.0',
25      ...options.headers,
26    };
27  
28    if (token) {
29      headers['Authorization'] = `Bearer ${token}`;
30    }
31  
32    if (options.body) {
33      headers['Content-Type'] = 'application/json';
34    }
35  
36    const response = await fetch(url, {
37      method: options.method || 'GET',
38      headers,
39      body: options.body ? JSON.stringify(options.body) : undefined,
40    });
41  
42    return response;
43  }
44  
45  export async function get(path: string) {
46    const response = await request(path);
47    if (!response.ok) {
48      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
49    }
50    return response.json();
51  }
52  
53  export async function post(path: string, body: unknown) {
54    const response = await request(path, { method: 'POST', body });
55    if (!response.ok) {
56      const text = await response.text();
57      throw new Error(`HTTP ${response.status}: ${response.statusText}\n${text}`);
58    }
59    return response.json();
60  }
61  
62  export async function del(path: string) {
63    const response = await request(path, { method: 'DELETE' });
64    if (!response.ok && response.status !== 204) {
65      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
66    }
67    return response.status === 204 ? null : response.json();
68  }