website/frontend/src/api/RESTful.ts
2026-04-26 21:10:04 +03:00

73 lines
2.3 KiB
TypeScript

import { NewsData, NewsFeed } from "../pages/feed/news";
import { NewsItem } from "../pages/feed/news-item";
type EndpointURL = "" | `http${'s' | ''}://${string}`;
interface ErrorDetails {
code: string,
message: string,
}
interface APIResponse<T> {
response ?: T;
error ?: ErrorDetails;
}
let newsFeed : NewsFeed | null = null;
class ErrorAPI extends Error {}
export class ControllerAPI {
protected endpoint: EndpointURL;
constructor(endpoint: EndpointURL = "") {
this.endpoint = endpoint;
}
protected async request<T>(path: string, options: RequestInit = {}): Promise<T> {
const url = new URL(path, this.endpoint || window.location.origin).href;
const response = await fetch(url, options);
const result: APIResponse<T> = await response.json();
if (result.error) throw new ErrorAPI(result.error.message);
if (result.response === undefined) throw new ErrorAPI("Missing response from API");
return result.response;
}
protected checkFirstAuth(): boolean {
// Implement your authentication logic here, e.g., check for a valid token in localStorage
//const token = localStorage.getItem('authToken');
//return !!token; // Returns true if token exists and is not empty
return true;
}
protected throwIfUnauthed(): void {
// Let's redirect to /auth if not authed
if (!this.checkFirstAuth()) {
window.location.href = '/auth';
}
}
async isAuthenticated(): Promise<boolean> {
if (!this.checkFirstAuth()) return false;
const result = await this.request<boolean>('/api/isAuthenticated', {
method: 'GET',
credentials: 'include' // Include cookies for authentication
});
return result;
}
async getNews(returnElement: boolean = false) : Promise<NewsFeed | NewsData[]> {
this.throwIfUnauthed();
const result = await this.request<NewsData[]>('/api/news', {
method: 'GET',
credentials: 'include' // Include cookies for authentication
});
if (!returnElement)
return result;
if (!newsFeed)
newsFeed = new NewsFeed(result.map(x => new NewsItem(x.title, new Date(x.publishedAt), x.content)));
return newsFeed;
}
}