Files
Project-Monitor/frontend/src/lib/api.ts
2025-11-01 16:05:52 +01:00

383 lines
9.7 KiB
TypeScript

import { env } from '$env/dynamic/public';
export const API_URL = env.PUBLIC_API_URL || 'http://localhost:8000';
// Helper to get token from localStorage
export function getToken(): string | null {
return localStorage.getItem('token');
}
// Helper to add Authorization header if token exists
export function authHeaders(headers: Record<string, string> = {}): Record<string, string> {
const token = getToken();
return token ? { ...headers, Authorization: `Bearer ${token}` } : headers;
}
/**
* Login and Register API
*/
export interface AuthResponse {
access_token: string;
token_type: string;
}
export async function login(username: string, password: string): Promise<AuthResponse> {
const form = new FormData();
form.append('username', username);
form.append('password', password);
const response = await fetch(`${API_URL}/login`, {
method: 'POST',
body: form
});
if (!response.ok) {
const data = await response.json();
throw new Error(data.detail || 'Login failed');
}
return response.json();
}
export async function register(username: string, password: string): Promise<AuthResponse> {
const response = await fetch(`${API_URL}/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
});
if (!response.ok) {
const data = await response.json();
throw new Error(data.detail || 'Registration failed');
}
return response.json();
}
/**
* Type definitions for Subscriptions and Notifications
*/
export interface Subscription {
id: number;
topic: string;
created_at: string;
has_unread: boolean;
}
export interface Notification {
id: number;
subscription_id: number;
title: string;
message: string;
priority: number;
created_at: string;
viewed: boolean;
}
/**
* Type definitions for Settings
*/
export interface Settings {
id: number;
requirements: string;
environment: string;
user: string;
ntfy_url?: string;
}
export async function checkHealth(): Promise<'healthy' | 'unhealthy'> {
try {
const response = await fetch(`${API_URL}/health`);
if (response.ok) {
return 'healthy';
} else {
return 'unhealthy';
}
} catch {
return 'unhealthy';
}
}
/**
* Type definitions for Script and Log
*/
export interface Log {
id: number;
script_id: number;
message: string;
error_message: string;
error_code: number;
created_at?: string;
}
export interface Script {
id: number;
name: string;
script_content?: string;
created_at?: string;
enabled: boolean;
}
// Fetch all scripts
export async function fetchScripts(): Promise<Script[]> {
const response = await fetch(`${API_URL}/script`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch scripts ' + response.statusText);
}
return response.json();
}
// Add a new script
export async function addScript(
script: Omit<Script, 'id' | 'created_at' | 'enabled'>
): Promise<Script> {
const response = await fetch(`${API_URL}/script`, {
method: 'POST',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify(script)
});
if (!response.ok) {
throw new Error('Failed to add script');
}
return response.json();
}
// Fetch all settings
export async function fetchUserSettings(): Promise<Settings> {
const response = await fetch(`${API_URL}/settings`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch settings ' + response.statusText);
}
return response.json();
}
// Fetch a single setting by ID
export async function fetchSettingById(id: number): Promise<Settings> {
const response = await fetch(`${API_URL}/settings/${id}`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch setting');
}
return response.json();
}
// Update an existing setting
export async function updateSetting(
id: number,
updatedSetting: Partial<Settings>
): Promise<Settings> {
const response = await fetch(`${API_URL}/settings/${id}`, {
method: 'PUT',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify({ ...updatedSetting, ntfy_url: updatedSetting.ntfy_url })
});
if (!response.ok) {
throw new Error('Failed to update setting');
}
return response.json();
}
// Fetch all subscriptions
export async function fetchSubscriptions(): Promise<Subscription[]> {
const response = await fetch(`${API_URL}/subscriptions`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch subscriptions');
}
return response.json();
}
// Fetch subscriptions by topic
export async function getSubscription(topic_id: string): Promise<Subscription> {
const response = await fetch(`${API_URL}/subscriptions/${topic_id}`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch subscriptions');
}
return response.json();
}
// Add a new notification to a subscription
export async function addNotification(
subscriptionId: number,
title: string,
message: string,
priority: number
): Promise<Notification> {
const response = await fetch(`${API_URL}/notifications`, {
method: 'POST',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify({ subscription_id: subscriptionId, title, message, priority })
});
if (!response.ok) {
throw new Error('Failed to add notification');
}
return response.json();
}
// Mark a notification as viewed
export async function setViewed(notificationId: number): Promise<Notification> {
const response = await fetch(`${API_URL}/notifications/${notificationId}`, {
method: 'PUT',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify({ viewed: true })
});
if (!response.ok) {
throw new Error('Failed to set notification as viewed');
}
return response.json();
}
// Add a new subscription
export async function addSubscription(topic: string): Promise<Subscription> {
const response = await fetch(`${API_URL}/subscriptions`, {
method: 'POST',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify({ topic })
});
if (!response.ok) {
throw new Error('Failed to add subscription');
}
return response.json();
}
// Delete a subscription
export async function deleteSubscription(subscriptionId: number): Promise<void> {
const response = await fetch(`${API_URL}/subscriptions/${subscriptionId}`, {
method: 'DELETE',
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to delete subscription');
}
}
// Get subscription notifications with pagination
export async function fetchSubscriptionNotifications(
subscriptionId: string,
limit: number = 20,
offset: number = 0
): Promise<Notification[]> {
const response = await fetch(
`${API_URL}/subscriptions/${subscriptionId}/notifications?limit=${limit}&offset=${offset}`,
{
headers: authHeaders()
}
);
if (!response.ok) {
throw new Error('Failed to fetch subscription notifications');
}
return response.json();
}
// Fetch all notifications or filter by topic
export async function fetchAllNotifications(): Promise<Notification[]> {
const url = `${API_URL}/notifications`;
const response = await fetch(url, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch notifications');
}
return response.json();
}
// Delete a notification
export async function deleteNotification(notificationId: number): Promise<void> {
const response = await fetch(`${API_URL}/notifications/${notificationId}`, {
method: 'DELETE',
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to delete notification');
}
}
// Fetch a single script by ID
export async function fetchScriptById(id: number): Promise<Script> {
const response = await fetch(`${API_URL}/script/${id}`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch script');
}
return response.json();
}
// Update an existing script
export async function updateScript(id: number, updatedScript: Partial<Script>): Promise<Script> {
const response = await fetch(`${API_URL}/script/${id}`, {
method: 'PUT',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify(updatedScript)
});
if (!response.ok) {
throw new Error('Failed to update script');
}
return response.json();
}
// Fetch logs for a specific script
export async function fetchLogs(scriptId: number): Promise<Log[]> {
const response = await fetch(`${API_URL}/script/${scriptId}/log`, {
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to fetch logs');
}
return response.json();
}
// Add a new log to a specific script
export async function addLog(scriptId: number, log: Log): Promise<Log> {
const response = await fetch(`${API_URL}/script/${scriptId}/log`, {
method: 'POST',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify(log)
});
if (!response.ok) {
throw new Error('Failed to add log');
}
return response.json();
}
// Execute a script by ID
export async function executeScript(scriptId: number): Promise<{ message: string }> {
const response = await fetch(`${API_URL}/script/${scriptId}/execute`, {
method: 'POST',
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to execute script');
}
return response.json();
}
// Delete a log from a specific script
export async function deleteLog(scriptId: number, logId: number): Promise<void> {
const response = await fetch(`${API_URL}/script/${scriptId}/log/${logId}`, {
method: 'DELETE',
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to delete log');
}
return response.json();
}
// Delete a script
export async function deleteScript(id: number): Promise<void> {
const response = await fetch(`${API_URL}/script/${id}`, {
method: 'DELETE',
headers: authHeaders()
});
if (!response.ok) {
throw new Error('Failed to delete script');
}
return response.json();
}