chore: update various components and services for improved functionality and consistency, including formatting adjustments and minor refactors

This commit is contained in:
Julien Froidefond
2025-12-07 09:54:05 +01:00
parent 4f5724c0ff
commit 39e3328123
141 changed files with 5292 additions and 3243 deletions

View File

@@ -13,9 +13,13 @@ export async function GET() {
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_FORBIDDEN" ? 403 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
{
status:
error.code === "AUTH_FORBIDDEN"
? 403
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: 500,
}
);
}
@@ -26,4 +30,3 @@ export async function GET() {
);
}
}

View File

@@ -14,17 +14,14 @@ export async function PUT(
const { newPassword } = body;
if (!newPassword) {
return NextResponse.json(
{ error: "Nouveau mot de passe manquant" },
{ status: 400 }
);
return NextResponse.json({ error: "Nouveau mot de passe manquant" }, { status: 400 });
}
// Vérifier que le mot de passe est fort
if (!AuthServerService.isPasswordStrong(newPassword)) {
return NextResponse.json(
{
error: "Le mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre"
{
error: "Le mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre",
},
{ status: 400 }
);
@@ -39,11 +36,17 @@ export async function PUT(
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_FORBIDDEN" ? 403 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
error.code === "AUTH_USER_NOT_FOUND" ? 404 :
error.code === "ADMIN_CANNOT_RESET_OWN_PASSWORD" ? 400 : 500
{
status:
error.code === "AUTH_FORBIDDEN"
? 403
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: error.code === "AUTH_USER_NOT_FOUND"
? 404
: error.code === "ADMIN_CANNOT_RESET_OWN_PASSWORD"
? 400
: 500,
}
);
}
@@ -54,4 +57,3 @@ export async function PUT(
);
}
}

View File

@@ -13,10 +13,7 @@ export async function PATCH(
const { roles } = body;
if (!roles || !Array.isArray(roles)) {
return NextResponse.json(
{ error: "Rôles invalides" },
{ status: 400 }
);
return NextResponse.json({ error: "Rôles invalides" }, { status: 400 });
}
await AdminService.updateUserRoles(userId, roles);
@@ -28,10 +25,15 @@ export async function PATCH(
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_FORBIDDEN" ? 403 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
error.code === "AUTH_USER_NOT_FOUND" ? 404 : 500
{
status:
error.code === "AUTH_FORBIDDEN"
? 403
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: error.code === "AUTH_USER_NOT_FOUND"
? 404
: 500,
}
);
}
@@ -58,11 +60,17 @@ export async function DELETE(
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_FORBIDDEN" ? 403 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 :
error.code === "AUTH_USER_NOT_FOUND" ? 404 :
error.code === "ADMIN_CANNOT_DELETE_SELF" ? 400 : 500
{
status:
error.code === "AUTH_FORBIDDEN"
? 403
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: error.code === "AUTH_USER_NOT_FOUND"
? 404
: error.code === "ADMIN_CANNOT_DELETE_SELF"
? 400
: 500,
}
);
}
@@ -73,4 +81,3 @@ export async function DELETE(
);
}
}

View File

@@ -13,9 +13,13 @@ export async function GET() {
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_FORBIDDEN" ? 403 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
{
status:
error.code === "AUTH_FORBIDDEN"
? 403
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: 500,
}
);
}

View File

@@ -1,3 +1,3 @@
import { handlers } from "@/lib/auth";
export const { GET, POST } = handlers;
export const { GET, POST } = handlers;

View File

@@ -44,10 +44,10 @@ export async function GET(
return { buffer, contentType };
}
);
// Cloner le buffer pour cette requête pour éviter tout partage de référence
const clonedBuffer = buffer.slice(0);
const headers = new Headers();
headers.set("Content-Type", contentType);
headers.set("Cache-Control", "public, max-age=31536000"); // Cache for 1 year

View File

@@ -16,7 +16,7 @@ export async function GET(
const data: KomgaBookWithPages = await BookService.getBook(bookId);
const nextBook = await BookService.getNextBook(bookId, data.book.seriesId);
return NextResponse.json({ ...data, nextBook });
} catch (error) {
logger.error({ err: error }, "API Books - Erreur:");

View File

@@ -10,13 +10,13 @@ export async function POST() {
try {
const cacheService: ServerCacheService = await getServerCacheService();
await cacheService.clear();
// Revalider toutes les pages importantes après le vidage du cache
revalidatePath("/");
revalidatePath("/libraries");
revalidatePath("/series");
revalidatePath("/books");
return NextResponse.json({ message: "🧹 Cache vidé avec succès" });
} catch (error) {
logger.error({ err: error }, "Erreur lors de la suppression du cache:");

View File

@@ -9,7 +9,7 @@ export async function GET() {
try {
const cacheService: ServerCacheService = await getServerCacheService();
const entries = await cacheService.getCacheEntries();
return NextResponse.json({ entries });
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération des entrées du cache");
@@ -25,4 +25,3 @@ export async function GET() {
);
}
}

View File

@@ -9,11 +9,11 @@ export async function GET() {
try {
const cacheService: ServerCacheService = await getServerCacheService();
const { sizeInBytes, itemCount } = await cacheService.getCacheSize();
return NextResponse.json({
sizeInBytes,
return NextResponse.json({
sizeInBytes,
itemCount,
mode: cacheService.getCacheMode()
mode: cacheService.getCacheMode(),
});
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la taille du cache:");
@@ -29,4 +29,3 @@ export async function GET() {
);
}
}

View File

@@ -10,10 +10,10 @@ import logger from "@/lib/logger";
export async function GET() {
try {
const favoriteIds: string[] = await FavoriteService.getAllFavoriteIds();
// Valider que chaque série existe encore dans Komga
const validFavoriteIds: string[] = [];
for (const seriesId of favoriteIds) {
try {
await SeriesService.getSeries(seriesId);
@@ -27,7 +27,7 @@ export async function GET() {
}
}
}
return NextResponse.json(validFavoriteIds);
} catch (error) {
if (error instanceof AppError) {

View File

@@ -67,4 +67,3 @@ export async function DELETE() {
);
}
}

View File

@@ -20,10 +20,10 @@ export async function GET(
return response;
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la page du livre:");
// Chercher un status HTTP 404 dans la chaîne d'erreurs
const httpStatus = findHttpStatus(error);
if (httpStatus === 404) {
const { bookId, pageNumber } = await params;
// eslint-disable-next-line no-console
@@ -39,7 +39,7 @@ export async function GET(
{ status: 404 }
);
}
if (error instanceof AppError) {
return NextResponse.json(
{

View File

@@ -34,10 +34,10 @@ export async function GET(
return response;
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la miniature de la page:");
// Chercher un status HTTP 404 dans la chaîne d'erreurs
const httpStatus = findHttpStatus(error);
if (httpStatus === 404) {
const { bookId, pageNumber: pageNumberParam } = await params;
const pageNumber: number = parseInt(pageNumberParam);
@@ -54,7 +54,7 @@ export async function GET(
{ status: 404 }
);
}
if (error instanceof AppError) {
return NextResponse.json(
{

View File

@@ -18,10 +18,10 @@ export async function GET(
return response;
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la miniature du livre:");
// Chercher un status HTTP 404 dans la chaîne d'erreurs
const httpStatus = findHttpStatus(error);
if (httpStatus === 404) {
const bookId: string = (await params).bookId;
// eslint-disable-next-line no-console
@@ -37,7 +37,7 @@ export async function GET(
{ status: 404 }
);
}
if (error instanceof AppError) {
return NextResponse.json(
{

View File

@@ -20,10 +20,10 @@ export async function GET(
return response;
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la couverture de la série:");
// Chercher un status HTTP 404 dans la chaîne d'erreurs
const httpStatus = findHttpStatus(error);
if (httpStatus === 404) {
const seriesId: string = (await params).seriesId;
// eslint-disable-next-line no-console
@@ -39,7 +39,7 @@ export async function GET(
{ status: 404 }
);
}
if (error instanceof AppError) {
return NextResponse.json(
{

View File

@@ -17,10 +17,10 @@ export async function GET(
return response;
} catch (error) {
logger.error({ err: error }, "Erreur lors de la récupération de la miniature de la série");
// Chercher un status HTTP 404 dans la chaîne d'erreurs
const httpStatus = findHttpStatus(error);
if (httpStatus === 404) {
const seriesId: string = (await params).seriesId;
logger.info(`📷 Image not found for series: ${seriesId}`);
@@ -35,7 +35,7 @@ export async function GET(
{ status: 404 }
);
}
if (error instanceof AppError) {
return NextResponse.json(
{

View File

@@ -12,7 +12,7 @@ export async function POST(
) {
try {
const libraryId: string = (await params).libraryId;
// Scan library with deep=false
await LibraryService.scanLibrary(libraryId, false);
@@ -43,4 +43,3 @@ export async function POST(
);
}
}

View File

@@ -16,7 +16,7 @@ export async function GET(
try {
const libraryId: string = (await params).libraryId;
const searchParams = request.nextUrl.searchParams;
const page = parseInt(searchParams.get("page") || "0");
const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE));
const unreadOnly = searchParams.get("unread") === "true";
@@ -24,15 +24,15 @@ export async function GET(
const [series, library] = await Promise.all([
LibraryService.getLibrarySeries(libraryId, page, size, unreadOnly, search),
LibraryService.getLibrary(libraryId)
LibraryService.getLibrary(libraryId),
]);
return NextResponse.json(
{ series, library },
{
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
}
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
},
}
);
} catch (error) {
@@ -68,7 +68,7 @@ export async function DELETE(
) {
try {
const libraryId: string = (await params).libraryId;
await LibraryService.invalidateLibrarySeriesCache(libraryId);
return NextResponse.json({ success: true });
@@ -98,4 +98,3 @@ export async function DELETE(
);
}
}

View File

@@ -51,4 +51,3 @@ export async function GET(request: NextRequest) {
);
}
}

View File

@@ -16,22 +16,22 @@ export async function GET(
try {
const seriesId: string = (await params).seriesId;
const searchParams = request.nextUrl.searchParams;
const page = parseInt(searchParams.get("page") || "0");
const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE));
const unreadOnly = searchParams.get("unread") === "true";
const [books, series] = await Promise.all([
SeriesService.getSeriesBooks(seriesId, page, size, unreadOnly),
SeriesService.getSeries(seriesId)
SeriesService.getSeries(seriesId),
]);
return NextResponse.json(
{ books, series },
{
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
}
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
},
}
);
} catch (error) {
@@ -67,10 +67,10 @@ export async function DELETE(
) {
try {
const seriesId: string = (await params).seriesId;
await Promise.all([
SeriesService.invalidateSeriesBooksCache(seriesId),
SeriesService.invalidateSeriesCache(seriesId)
SeriesService.invalidateSeriesCache(seriesId),
]);
return NextResponse.json({ success: true });
@@ -100,4 +100,3 @@ export async function DELETE(
);
}
}

View File

@@ -18,8 +18,8 @@ export async function GET(
const series: KomgaSeries = await SeriesService.getSeries(seriesId);
return NextResponse.json(series, {
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=120'
}
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=120",
},
});
} catch (error) {
logger.error({ err: error }, "API Series - Erreur:");

View File

@@ -1,4 +1,4 @@
import type { NextRequest} from "next/server";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
import { PreferencesService } from "@/lib/services/preferences.service";
import { ERROR_CODES } from "@/constants/errorCodes";
@@ -41,9 +41,8 @@ export async function GET() {
export async function PUT(request: NextRequest) {
try {
const preferences: UserPreferences = await request.json();
const updatedPreferences: UserPreferences = await PreferencesService.updatePreferences(
preferences
);
const updatedPreferences: UserPreferences =
await PreferencesService.updatePreferences(preferences);
return NextResponse.json(updatedPreferences);
} catch (error) {
logger.error({ err: error }, "Erreur lors de la mise à jour des préférences:");

View File

@@ -10,17 +10,15 @@ export async function PUT(request: NextRequest) {
const { currentPassword, newPassword } = body;
if (!currentPassword || !newPassword) {
return NextResponse.json(
{ error: "Mots de passe manquants" },
{ status: 400 }
);
return NextResponse.json({ error: "Mots de passe manquants" }, { status: 400 });
}
// Vérifier que le nouveau mot de passe est fort
if (!AuthServerService.isPasswordStrong(newPassword)) {
return NextResponse.json(
{
error: "Le nouveau mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre"
{
error:
"Le nouveau mot de passe doit contenir au moins 8 caractères, une majuscule et un chiffre",
},
{ status: 400 }
);
@@ -35,9 +33,13 @@ export async function PUT(request: NextRequest) {
if (error instanceof AppError) {
return NextResponse.json(
{ error: error.message, code: error.code },
{
status: error.code === "AUTH_INVALID_PASSWORD" ? 400 :
error.code === "AUTH_UNAUTHENTICATED" ? 401 : 500
{
status:
error.code === "AUTH_INVALID_PASSWORD"
? 400
: error.code === "AUTH_UNAUTHENTICATED"
? 401
: 500,
}
);
}