Files
website/src/routes/trackers/books/covers/[id=integer]/+server.ts

30 lines
1.1 KiB
TypeScript

// Public cover images for the catalogue (covers only, never book files).
import { error } from '@sveltejs/kit';
import { and, eq, isNull } from 'drizzle-orm';
import { isOwner } from '#lib/server/owner.js';
import { db } from '#lib/server/db/index.js';
import { bookWorks } from '#lib/server/db/schema/index.js';
import { safeResolve, streamFile } from '#lib/server/books/files.js';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async (event) => {
const [work] = await db
.select({ coverPath: bookWorks.coverPath })
.from(bookWorks)
.where(
and(
eq(bookWorks.id, Number(event.params.id)),
isOwner(event) ? undefined : isNull(bookWorks.archivedAt)
)
)
.limit(1);
const resolved = work?.coverPath ? await safeResolve('covers', work.coverPath) : null;
if (!resolved) error(404, 'Not Found');
const response = await streamFile(resolved, event.request, {
'cache-control': 'public, max-age=86400, stale-while-revalidate=604800',
'x-content-type-options': 'nosniff'
});
if (!response.headers.get('content-type')?.startsWith('image/')) error(404, 'Not Found');
return response;
};