383 lines
9.7 KiB
TypeScript
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();
|
|
}
|