refacto(services): fetchFromApi simpler + bug libraries fetch
This commit is contained in:
@@ -9,6 +9,11 @@ interface KomgaRequestInit extends RequestInit {
|
|||||||
isImage?: boolean;
|
isImage?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface KomgaUrlBuilder {
|
||||||
|
path: string;
|
||||||
|
params?: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
export abstract class BaseApiService {
|
export abstract class BaseApiService {
|
||||||
protected static async getKomgaConfig(): Promise<AuthConfig> {
|
protected static async getKomgaConfig(): Promise<AuthConfig> {
|
||||||
try {
|
try {
|
||||||
@@ -78,10 +83,24 @@ export abstract class BaseApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static async fetchFromApi<T>(
|
protected static async fetchFromApi<T>(
|
||||||
url: string,
|
urlBuilder: KomgaUrlBuilder,
|
||||||
headers: Headers,
|
headersOptions = {},
|
||||||
options: KomgaRequestInit = {}
|
options: KomgaRequestInit = {}
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
|
const config = await this.getKomgaConfig();
|
||||||
|
const { path, params } = urlBuilder;
|
||||||
|
const url = this.buildUrl(config, path, params);
|
||||||
|
|
||||||
|
const headers = this.getAuthHeaders(config);
|
||||||
|
if (headersOptions) {
|
||||||
|
for (const [key, value] of Object.entries(headersOptions)) {
|
||||||
|
headers.set(key as string, value as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log("Fetching from", url);
|
||||||
|
// console.log("Headers", headers);
|
||||||
|
// console.log("headersOptions", headersOptions);
|
||||||
|
// console.log("options", options);
|
||||||
const response = await fetch(url, { headers, ...options });
|
const response = await fetch(url, { headers, ...options });
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|||||||
@@ -6,23 +6,16 @@ import { PreferencesService } from "./preferences.service";
|
|||||||
export class BookService extends BaseApiService {
|
export class BookService extends BaseApiService {
|
||||||
static async getBook(bookId: string): Promise<{ book: KomgaBook; pages: number[] }> {
|
static async getBook(bookId: string): Promise<{ book: KomgaBook; pages: number[] }> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
|
|
||||||
return this.fetchWithCache<{ book: KomgaBook; pages: number[] }>(
|
return this.fetchWithCache<{ book: KomgaBook; pages: number[] }>(
|
||||||
`book-${bookId}`,
|
`book-${bookId}`,
|
||||||
async () => {
|
async () => {
|
||||||
// Récupération des détails du tome
|
// Récupération des détails du tome
|
||||||
const book = await this.fetchFromApi<KomgaBook>(
|
const book = await this.fetchFromApi<KomgaBook>({ path: `books/${bookId}` });
|
||||||
this.buildUrl(config, `books/${bookId}`),
|
|
||||||
headers
|
|
||||||
);
|
|
||||||
|
|
||||||
// Récupération des pages du tome
|
// Récupération des pages du tome
|
||||||
const pages = await this.fetchFromApi<{ number: number }[]>(
|
const pages = await this.fetchFromApi<{ number: number }[]>({
|
||||||
this.buildUrl(config, `books/${bookId}/pages`),
|
path: `books/${bookId}/pages`,
|
||||||
headers
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
book,
|
book,
|
||||||
|
|||||||
@@ -12,45 +12,47 @@ interface HomeData {
|
|||||||
export class HomeService extends BaseApiService {
|
export class HomeService extends BaseApiService {
|
||||||
static async getHomeData(): Promise<HomeData> {
|
static async getHomeData(): Promise<HomeData> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
|
|
||||||
// Construction des URLs avec des paramètres optimisés
|
|
||||||
const ongoingUrl = this.buildUrl(config, "series", {
|
|
||||||
read_status: "IN_PROGRESS",
|
|
||||||
sort: "readDate,desc",
|
|
||||||
page: "0",
|
|
||||||
size: "10",
|
|
||||||
media_status: "READY",
|
|
||||||
});
|
|
||||||
|
|
||||||
const recentlyReadUrl = this.buildUrl(config, "books/latest", {
|
|
||||||
page: "0",
|
|
||||||
size: "10",
|
|
||||||
media_status: "READY",
|
|
||||||
});
|
|
||||||
|
|
||||||
const onDeckUrl = this.buildUrl(config, "books/ondeck", {
|
|
||||||
page: "0",
|
|
||||||
size: "10",
|
|
||||||
media_status: "READY",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Appels API parallèles avec cache individuel
|
// Appels API parallèles avec cache individuel
|
||||||
const [ongoing, recentlyRead, onDeck] = await Promise.all([
|
const [ongoing, recentlyRead, onDeck] = await Promise.all([
|
||||||
this.fetchWithCache<LibraryResponse<KomgaSeries>>(
|
this.fetchWithCache<LibraryResponse<KomgaSeries>>(
|
||||||
"home-ongoing",
|
"home-ongoing",
|
||||||
async () => this.fetchFromApi<LibraryResponse<KomgaSeries>>(ongoingUrl, headers),
|
async () =>
|
||||||
|
this.fetchFromApi<LibraryResponse<KomgaSeries>>({
|
||||||
|
path: "series",
|
||||||
|
params: {
|
||||||
|
read_status: "IN_PROGRESS",
|
||||||
|
sort: "readDate,desc",
|
||||||
|
page: "0",
|
||||||
|
size: "10",
|
||||||
|
media_status: "READY",
|
||||||
|
},
|
||||||
|
}),
|
||||||
"HOME"
|
"HOME"
|
||||||
),
|
),
|
||||||
this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
||||||
"home-recently-read",
|
"home-recently-read",
|
||||||
async () => this.fetchFromApi<LibraryResponse<KomgaBook>>(recentlyReadUrl, headers),
|
async () =>
|
||||||
|
this.fetchFromApi<LibraryResponse<KomgaBook>>({
|
||||||
|
path: "books/latest",
|
||||||
|
params: {
|
||||||
|
page: "0",
|
||||||
|
size: "10",
|
||||||
|
media_status: "READY",
|
||||||
|
},
|
||||||
|
}),
|
||||||
"HOME"
|
"HOME"
|
||||||
),
|
),
|
||||||
this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
||||||
"home-on-deck",
|
"home-on-deck",
|
||||||
async () => this.fetchFromApi<LibraryResponse<KomgaBook>>(onDeckUrl, headers),
|
async () =>
|
||||||
|
this.fetchFromApi<LibraryResponse<KomgaBook>>({
|
||||||
|
path: "books/ondeck",
|
||||||
|
params: {
|
||||||
|
page: "0",
|
||||||
|
size: "10",
|
||||||
|
media_status: "READY",
|
||||||
|
},
|
||||||
|
}),
|
||||||
"HOME"
|
"HOME"
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ interface ImageResponse {
|
|||||||
export class ImageService extends BaseApiService {
|
export class ImageService extends BaseApiService {
|
||||||
static async getImage(path: string): Promise<ImageResponse> {
|
static async getImage(path: string): Promise<ImageResponse> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
const headers = { Accept: "image/jpeg, image/png, image/gif, image/webp, */*" };
|
||||||
const url = this.buildUrl(config, path);
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
headers.set("Accept", "image/jpeg, image/png, image/gif, image/webp, */*");
|
|
||||||
|
|
||||||
return this.fetchWithCache<ImageResponse>(
|
return this.fetchWithCache<ImageResponse>(
|
||||||
`image-${path}`,
|
`image-${path}`,
|
||||||
async () => {
|
async () => {
|
||||||
const response = await this.fetchFromApi<Response>(url, headers, { isImage: true });
|
const response = await this.fetchFromApi<Response>({ path }, headers, { isImage: true });
|
||||||
const contentType = response.headers.get("content-type");
|
const contentType = response.headers.get("content-type");
|
||||||
const arrayBuffer = await response.arrayBuffer();
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
const buffer = Buffer.from(arrayBuffer);
|
const buffer = Buffer.from(arrayBuffer);
|
||||||
|
|||||||
@@ -6,13 +6,9 @@ import { serverCacheService } from "./server-cache.service";
|
|||||||
export class LibraryService extends BaseApiService {
|
export class LibraryService extends BaseApiService {
|
||||||
static async getLibraries(): Promise<Library[]> {
|
static async getLibraries(): Promise<Library[]> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
|
||||||
const url = this.buildUrl(config, "libraries");
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
|
|
||||||
return this.fetchWithCache<Library[]>(
|
return this.fetchWithCache<Library[]>(
|
||||||
"libraries",
|
"libraries",
|
||||||
async () => this.fetchFromApi<Library[]>(url, headers),
|
async () => this.fetchFromApi<Library[]>({ path: "libraries" }),
|
||||||
"LIBRARIES"
|
"LIBRARIES"
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -31,12 +27,7 @@ export class LibraryService extends BaseApiService {
|
|||||||
|
|
||||||
static async getAllLibrarySeries(libraryId: string): Promise<Series[]> {
|
static async getAllLibrarySeries(libraryId: string): Promise<Series[]> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
const headers = { "Content-Type": "application/json" };
|
||||||
const url = this.buildUrl(config, "series/list", {
|
|
||||||
size: "1000", // On récupère un maximum de séries
|
|
||||||
});
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
headers.set("Content-Type", "application/json");
|
|
||||||
|
|
||||||
const searchBody = {
|
const searchBody = {
|
||||||
condition: {
|
condition: {
|
||||||
@@ -51,10 +42,19 @@ export class LibraryService extends BaseApiService {
|
|||||||
const response = await this.fetchWithCache<LibraryResponse<Series>>(
|
const response = await this.fetchWithCache<LibraryResponse<Series>>(
|
||||||
cacheKey,
|
cacheKey,
|
||||||
async () =>
|
async () =>
|
||||||
this.fetchFromApi<LibraryResponse<Series>>(url, headers, {
|
this.fetchFromApi<LibraryResponse<Series>>(
|
||||||
method: "POST",
|
{
|
||||||
body: JSON.stringify(searchBody),
|
path: "series/list",
|
||||||
}),
|
params: {
|
||||||
|
size: "1000", // On récupère un maximum de livres
|
||||||
|
},
|
||||||
|
},
|
||||||
|
headers,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(searchBody),
|
||||||
|
}
|
||||||
|
),
|
||||||
"SERIES"
|
"SERIES"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -74,7 +74,6 @@ export class LibraryService extends BaseApiService {
|
|||||||
try {
|
try {
|
||||||
// Récupérer toutes les séries depuis le cache
|
// Récupérer toutes les séries depuis le cache
|
||||||
const allSeries = await this.getAllLibrarySeries(libraryId);
|
const allSeries = await this.getAllLibrarySeries(libraryId);
|
||||||
|
|
||||||
// Filtrer les séries
|
// Filtrer les séries
|
||||||
let filteredSeries = allSeries;
|
let filteredSeries = allSeries;
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,9 @@ import { serverCacheService } from "./server-cache.service";
|
|||||||
export class SeriesService extends BaseApiService {
|
export class SeriesService extends BaseApiService {
|
||||||
static async getSeries(seriesId: string): Promise<KomgaSeries> {
|
static async getSeries(seriesId: string): Promise<KomgaSeries> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
|
||||||
const url = this.buildUrl(config, `series/${seriesId}`);
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
|
|
||||||
return this.fetchWithCache<KomgaSeries>(
|
return this.fetchWithCache<KomgaSeries>(
|
||||||
`series-${seriesId}`,
|
`series-${seriesId}`,
|
||||||
async () => this.fetchFromApi<KomgaSeries>(url, headers),
|
async () => this.fetchFromApi<KomgaSeries>({ path: `series/${seriesId}` }),
|
||||||
"SERIES"
|
"SERIES"
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -29,12 +25,7 @@ export class SeriesService extends BaseApiService {
|
|||||||
|
|
||||||
static async getAllSeriesBooks(seriesId: string): Promise<KomgaBook[]> {
|
static async getAllSeriesBooks(seriesId: string): Promise<KomgaBook[]> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
const headers = { "Content-Type": "application/json" };
|
||||||
const url = this.buildUrl(config, "books/list", {
|
|
||||||
size: "1000", // On récupère un maximum de livres
|
|
||||||
});
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
headers.set("Content-Type", "application/json");
|
|
||||||
|
|
||||||
const searchBody = {
|
const searchBody = {
|
||||||
condition: {
|
condition: {
|
||||||
@@ -49,10 +40,19 @@ export class SeriesService extends BaseApiService {
|
|||||||
const response = await this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
const response = await this.fetchWithCache<LibraryResponse<KomgaBook>>(
|
||||||
cacheKey,
|
cacheKey,
|
||||||
async () =>
|
async () =>
|
||||||
this.fetchFromApi<LibraryResponse<KomgaBook>>(url, headers, {
|
this.fetchFromApi<LibraryResponse<KomgaBook>>(
|
||||||
method: "POST",
|
{
|
||||||
body: JSON.stringify(searchBody),
|
path: "books/list",
|
||||||
}),
|
params: {
|
||||||
|
size: "1000", // On récupère un maximum de livres
|
||||||
|
},
|
||||||
|
},
|
||||||
|
headers,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(searchBody),
|
||||||
|
}
|
||||||
|
),
|
||||||
"BOOKS"
|
"BOOKS"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -131,17 +131,13 @@ export class SeriesService extends BaseApiService {
|
|||||||
|
|
||||||
static async getFirstBook(seriesId: string): Promise<string> {
|
static async getFirstBook(seriesId: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const config = await this.getKomgaConfig();
|
|
||||||
const url = this.buildUrl(config, `series/${seriesId}/books`);
|
|
||||||
const headers = this.getAuthHeaders(config);
|
|
||||||
|
|
||||||
return this.fetchWithCache<string>(
|
return this.fetchWithCache<string>(
|
||||||
`series-first-book-${seriesId}`,
|
`series-first-book-${seriesId}`,
|
||||||
async () => {
|
async () => {
|
||||||
const data = await this.fetchFromApi<LibraryResponse<KomgaBook>>(
|
const data = await this.fetchFromApi<LibraryResponse<KomgaBook>>({
|
||||||
`series/${seriesId}/books?page=0&size=1`,
|
path: `series/${seriesId}/books`,
|
||||||
headers
|
params: { page: "0", size: "1" },
|
||||||
);
|
});
|
||||||
if (!data.content || data.content.length === 0) {
|
if (!data.content || data.content.length === 0) {
|
||||||
throw new Error("Aucun livre trouvé dans la série");
|
throw new Error("Aucun livre trouvé dans la série");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user