import { Inject, Injectable } from '@nestjs/common'; import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken, } from '@smatch-corp/nestjs-pothos'; import { Builder } from '../Graphql/graphql.builder'; import { PrismaService } from '../Prisma/prisma.service'; @Injectable() export class MessageSchema extends PothosSchema { constructor( @Inject(SchemaBuilderToken) private readonly builder: Builder, private readonly prisma: PrismaService, ) { super(); } @PothosRef() message() { return this.builder.prismaObject('Message', { description: 'A message in the system.', fields: (t) => ({ id: t.exposeID('id', { description: 'The ID of the message.', }), senderId: t.exposeID('senderId', { description: 'The ID of the sender.', }), chatRoomId: t.exposeID('chatRoomId', { description: 'The ID of the chat room.', }), message: t.expose('message', { // eslint-disable-next-line @typescript-eslint/no-explicit-any type: 'Json' as any, description: 'The message content.', }), sentAt: t.expose('sentAt', { type: 'DateTime', description: 'The date and time the message was sent.', }), sender: t.relation('sender', { description: 'The sender of the message.', }), chatRoom: t.relation('chatRoom', { description: 'The chat room.', }), }), }); } @Pothos() init(): void { this.builder.queryFields((t) => ({ message: t.prismaField({ type: this.message(), description: 'Retrieve a single message by its unique identifier.', args: this.builder.generator.findUniqueArgs('Message'), resolve: async (query, root, args) => { return await this.prisma.message.findUnique({ ...query, where: args.where, }); }, }), messages: t.prismaField({ type: [this.message()], description: 'Retrieve a list of messages with optional filtering, ordering, and pagination.', args: this.builder.generator.findManyArgs('Message'), resolve: async (query, root, args) => { return await this.prisma.message.findMany({ ...query, skip: args.skip ?? undefined, take: args.take ?? undefined, orderBy: args.orderBy ?? undefined, where: args.filter ?? undefined, }); }, }), messagesByChatRoomId: t.prismaField({ type: [this.message()], description: 'Retrieve a list of messages by chat room ID.', args: this.builder.generator.findManyArgs('Message'), resolve: async (query, root, args) => { return await this.prisma.message.findMany({ ...query, where: args.filter ?? undefined, }); }, }), })); // mutations this.builder.mutationFields((t) => ({ sendMessage: t.prismaField({ type: this.message(), description: 'Send a message to a chat room.', args: { input: t.arg({ type: this.builder.generator.getCreateInput('Message'), description: 'The message to send.', required: true, }), }, resolve: async (query, root, args, ctx, info) => { const message = await this.prisma.message.create({ ...query, data: args.input, }); if (ctx.isSubscription) { throw new Error('Not allowed'); } ctx.http.pubSub.publish('MESSAGE_SENT', message); return message; }, }), })); // subscriptions /* The code snippet `subscriptions` is currently commented out in the provided TypeScript class. It appears to be a placeholder or a section where subscription-related logic or fields could be defined. In GraphQL, subscriptions are used to listen for real-time events or changes in data and receive updates when those events occur. */ this.builder.subscriptionFields((t) => ({ messageSent: t.field({ subscribe: (_, __, ctx) => { if (!ctx.isSubscription) { throw new Error('Not allowed'); } return { [Symbol.asyncIterator]: () => ctx.websocket.pubSub.asyncIterator('MESSAGE_SENT'), }; }, type: this.message(), // Add the type property resolve: (payload) => payload as { message: 'Json'; id: string; senderId: string; chatRoomId: string; sentAt: Date; }, }), })); } }