Files
gems/opal-web/src/lib/api/client.js
T
joakim 8693681660 refactor: clean up opal-web duplication, dead code, and comment noise
- Deduplicate API_BASE (was defined in both client.js and endpoints.js)
- Extract EMPTY_STATE and persist() helper in auth store (DRY)
- Extract updateByUuid() in tasks store, normalize to .map() pattern
- Remove unused getQueueSize(), Select.svelte, and lib/index.js
- Modernize uuid.js to prefer crypto.randomUUID()
- Strip ~60 redundant comments that restated self-evident code

No behavior changes. Build passes, pre-existing type errors unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:03:08 +01:00

87 lines
1.9 KiB
JavaScript

import { authStore } from '$lib/stores/auth.js';
import { get } from 'svelte/store';
/**
* @typedef {import('./types.js').APIResponse} APIResponse
* @typedef {import('./types.js').AuthTokens} AuthTokens
*/
export const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:8080';
/**
* Make authenticated API request
* @template T
* @param {string} endpoint
* @param {RequestInit} [options]
* @returns {Promise<T>}
*/
export async function apiRequest(endpoint, options = {}) {
const auth = get(authStore);
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (auth.accessToken) {
headers['Authorization'] = `Bearer ${auth.accessToken}`;
}
try {
const response = await fetch(`${API_BASE}${endpoint}`, {
...options,
headers
});
if (response.status === 401 && auth.refreshToken) {
const refreshed = await refreshAccessToken(auth.refreshToken);
if (refreshed) {
headers['Authorization'] = `Bearer ${refreshed.access_token}`;
return apiRequest(endpoint, { ...options, headers });
}
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (!result.success) {
throw new Error(result.error || 'Unknown error');
}
return result.data;
} catch (error) {
console.error(`API Error [${endpoint}]:`, error);
throw error;
}
}
/**
* Refresh access token
* @param {string} refreshToken
* @returns {Promise<AuthTokens|null>}
*/
async function refreshAccessToken(refreshToken) {
try {
const response = await fetch(`${API_BASE}/auth/refresh`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: refreshToken })
});
if (!response.ok) return null;
const result = await response.json();
if (result.success) {
authStore.setTokens(result.data);
return result.data;
}
return null;
} catch {
return null;
}
}