import type { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox' import { Type } from 'typebox' import { ChannelSchema, CreateChannelPayloadSchema } from '../plugins/schemas/channel.ts' import { PrismaClientKnownRequestError } from '../prisma/generated-client/internal/prismaNamespace.ts' import { TypeboxRef } from '../utils/typebox-ref.ts' const plugin: FastifyPluginAsyncTypebox = async (fastify) => { fastify.get( '/channels', { schema: { summary: 'Get channel list', tags: ['Channel'], operationId: 'channel.list', response: { 200: Type.Array(TypeboxRef(ChannelSchema)), }, }, }, async () => { return await fastify.prisma.channel.findMany() }, ) fastify.post( '/channels', { schema: { summary: 'Create channel', tags: ['Channel'], operationId: 'channel.create', body: TypeboxRef(CreateChannelPayloadSchema), response: { 200: TypeboxRef(ChannelSchema), }, }, }, async (req, reply) => { const user = req.user! const channel = await fastify.prisma.channel.create({ data: { name: req.body.name, ownerUsername: user.username, persistent: req.body.persistent, }, }) if (!channel) { return reply.unprocessableEntity() } fastify.bus.emit('channel:created', channel) return channel }, ) fastify.delete( '/channels/:id', { schema: { summary: 'Delete channel', tags: ['Channel'], operationId: 'channel.delete', params: Type.Object({ id: Type.String(), }), }, }, async (req, reply) => { const user = req.user! try { const channel = await fastify.prisma.channel.delete({ where: { id: req.params.id, ownerUsername: user.username }, }) fastify.bus.emit('channel:removed', channel) } catch (e) { if (e instanceof PrismaClientKnownRequestError && e.code === 'P2025') { return reply.notFound() } } }, ) } export default plugin