Files
family_wishlist/apps/backend/src/modules/images/images.routes.ts

51 lines
1.8 KiB
TypeScript

import type { FastifyInstance } from 'fastify';
import { MAX_UPLOAD_BYTES } from '../../plugins/multipart.js';
import { WishesService } from '../wishes/wishes.service.js';
import { ValidationError } from '../../utils/errors.js';
import { deleteLocalImageIfAny, saveUploadedImage } from './storage.service.js';
import { fetchOgImageForWish } from './og.service.js';
export default async function imagesRoutes(app: FastifyInstance) {
app.addHook('preHandler', app.authenticate);
const wishes = new WishesService(app.prisma);
app.post('/:id/image', async (request) => {
const { id } = request.params as { id: string };
const current = await wishes.getOwned(request.user.id, id);
const data = await request.file();
if (!data) throw new ValidationError('No file uploaded');
const buffer = await data.toBuffer();
if (buffer.byteLength > MAX_UPLOAD_BYTES) {
throw new ValidationError('File too large');
}
const { imageUrl } = await saveUploadedImage(id, data.mimetype, buffer);
await deleteLocalImageIfAny(current.imageUrl);
return app.prisma.wish.update({
where: { id },
data: { imageUrl, imageSource: 'UPLOADED' },
});
});
app.post('/:id/image/refresh-og', async (request) => {
const { id } = request.params as { id: string };
const wish = await wishes.getOwned(request.user.id, id);
if (!wish.url) throw new ValidationError('Wish has no url');
await fetchOgImageForWish(app, id, wish.url);
return app.prisma.wish.findUniqueOrThrow({ where: { id } });
});
app.delete('/:id/image', async (request) => {
const { id } = request.params as { id: string };
const wish = await wishes.getOwned(request.user.id, id);
await deleteLocalImageIfAny(wish.imageUrl);
return app.prisma.wish.update({
where: { id },
data: { imageUrl: null, imageSource: 'DEFAULT' },
});
});
}