Files
epess-web-backend/src/Message/message.schema.ts
2024-10-29 02:21:18 +07:00

151 lines
4.7 KiB
TypeScript

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;
},
}),
}));
}
}