From ff45e69efd74432a0874bb2ea0e4ed24f675a477 Mon Sep 17 00:00:00 2001 From: Ly Tuan Kiet Date: Mon, 11 Nov 2024 22:04:39 +0700 Subject: [PATCH] push code chua nhi? --- package-lock.json | 55 +++++++++++++++++++++++++++++++- package.json | 1 + src/Graphql/graphql.builder.ts | 3 +- src/Message/message.schema.ts | 1 + src/Realtime/realtime.schema.ts | 10 ++++++ src/Realtime/realtime.service.ts | 6 ++-- src/User/user.schema.ts | 55 +++++++++++++++++++++++++------- 7 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 src/Realtime/realtime.schema.ts diff --git a/package-lock.json b/package-lock.json index b3ad35c..ed4360d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,6 +63,7 @@ "nodemailer": "^6.9.15", "openai": "^4.68.4", "passport-jwt": "^4.0.1", + "quill": "^2.0.2", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.1", @@ -9777,7 +9778,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/fast-glob": { @@ -13035,6 +13035,18 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -13065,6 +13077,12 @@ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "license": "MIT" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "license": "MIT" + }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -14712,6 +14730,12 @@ "tslib": "^2.0.3" } }, + "node_modules/parchment": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz", + "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==", + "license": "BSD-3-Clause" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -15497,6 +15521,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/quill": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.2.tgz", + "integrity": "sha512-QfazNrhMakEdRG57IoYFwffUIr04LWJxbS/ZkidRFXYCQt63c1gK6Z7IHUXMx/Vh25WgPBU42oBaNzQ0K1R/xw==", + "license": "BSD-3-Clause", + "dependencies": { + "eventemitter3": "^5.0.1", + "lodash-es": "^4.17.21", + "parchment": "^3.0.0", + "quill-delta": "^5.1.0" + }, + "engines": { + "npm": ">=8.2.3" + } + }, + "node_modules/quill-delta": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", + "license": "MIT", + "dependencies": { + "fast-diff": "^1.3.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", diff --git a/package.json b/package.json index 0af01c7..e8ca8b6 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "nodemailer": "^6.9.15", "openai": "^4.68.4", "passport-jwt": "^4.0.1", + "quill": "^2.0.2", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "swagger-ui-express": "^5.0.1", diff --git a/src/Graphql/graphql.builder.ts b/src/Graphql/graphql.builder.ts index 0197b13..1aac399 100644 --- a/src/Graphql/graphql.builder.ts +++ b/src/Graphql/graphql.builder.ts @@ -12,7 +12,7 @@ import AuthzPlugin from '@pothos/plugin-authz' import ErrorsPlugin from '@pothos/plugin-errors' import type { FileUpload } from 'graphql-upload/processRequest.js' import GraphQLUpload from 'graphql-upload/GraphQLUpload.js' -import { Injectable } from '@nestjs/common' +import { Injectable, Logger } from '@nestjs/common' import { PrismaCrudGenerator } from './graphql.generator' import type PrismaTypes from '../types/pothos.generated' import PrismaUtils from '@pothos/plugin-prisma-utils' @@ -107,6 +107,7 @@ export class Builder extends SchemaBuilder { // optionally customize how errors are formatted validationError: (zodError, _args, _context, _info) => { // the default behavior is to just throw the zod error directly + Logger.error(zodError.message, 'Zod Error') return zodError }, }, diff --git a/src/Message/message.schema.ts b/src/Message/message.schema.ts index 7630714..1e39551 100644 --- a/src/Message/message.schema.ts +++ b/src/Message/message.schema.ts @@ -56,6 +56,7 @@ export class MessageSchema extends PothosSchema { }), metadata: t.expose('metadata', { type: 'Json', + nullable: true, description: 'The metadata of the message.', }), sender: t.relation('sender', { diff --git a/src/Realtime/realtime.schema.ts b/src/Realtime/realtime.schema.ts new file mode 100644 index 0000000..2bd45b0 --- /dev/null +++ b/src/Realtime/realtime.schema.ts @@ -0,0 +1,10 @@ +import { Inject, Injectable } from '@nestjs/common' +import { PothosSchema } from '@smatch-corp/nestjs-pothos' +import { PrismaService } from 'src/Prisma/prisma.service' + +@Injectable() +export class RealtimeSchema extends PothosSchema { + constructor(private readonly prisma: PrismaService) { + super() + } +} diff --git a/src/Realtime/realtime.service.ts b/src/Realtime/realtime.service.ts index ceb988a..dab069d 100644 --- a/src/Realtime/realtime.service.ts +++ b/src/Realtime/realtime.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common' -// @ts-ignore -import * as Y from 'yjs' +// import Quil, { Delta } from 'quill' + @Injectable() export class RealtimeService { - yjs = new Y.Doc() + // constructor(private readonly quil: Quil) {} } diff --git a/src/User/user.schema.ts b/src/User/user.schema.ts index e4bd20b..db5ce8d 100644 --- a/src/User/user.schema.ts +++ b/src/User/user.schema.ts @@ -11,8 +11,11 @@ import { clerkClient } from '@clerk/express' import { UnauthorizedException } from '@nestjs/common' import { MailService } from '../Mail/mail.service' import { MessageSchema } from 'src/Message/message.schema' -import { Message } from '@prisma/client' +import { Message, MessageContextType, MessageType } from '@prisma/client' import { PubSubEvent } from 'src/common/pubsub/pubsub-event' +import { DateTimeUtils } from 'src/common/utils/datetime.utils' +import { JsonValue } from '@prisma/client/runtime/library' +import { z } from 'zod' @Injectable() export class UserSchema extends PothosSchema { constructor( @@ -50,16 +53,6 @@ export class UserSchema extends PothosSchema { }), packageValue: t.exposeFloat('packageValue', { description: 'The package value of the user.', - validate: (value) => { - if (typeof value !== 'number') { - return false - } - // value can be only 0 to 1 - if (value < 0 || value > 1) { - return false - } - return true - }, nullable: true, }), role: t.exposeString('role', { @@ -390,6 +383,45 @@ export class UserSchema extends PothosSchema { }) }, }), + // send test notification + + sendTestNotification: t.field({ + type: this.messageSchema.message(), + args: { + input: t.arg({ + type: this.builder.generator.getCreateInput('Message'), + required: true, + }), + }, + resolve: async (_, args, ctx) => { + if (ctx.isSubscription) { + throw new Error('Not allowed') + } + const me = ctx.http.me + if (!me) { + throw new Error('User not found') + } + // create message + const message = await this.prisma.message.create({ + data: { + type: args.input.type, + content: args.input.content, + senderId: me.id, + recipientId: args.input.recipient?.connect?.id ?? null, + chatRoomId: args.input.chatRoom?.connect?.id ?? null, + sentAt: DateTimeUtils.nowAsJSDate(), + context: args.input.context ?? undefined, + metadata: args.input.metadata ?? undefined, + }, + }) + // publish message + await ctx.http.pubSub.publish( + `${PubSubEvent.NEW_MESSAGE}.${message.recipientId}`, + message, + ) + return message + }, + }), })) // Subscription section @@ -401,6 +433,7 @@ export class UserSchema extends PothosSchema { const { websocket: { pubSub }, } = ctx + Logger.log(ctx.websocket.me?.id, 'Me ID') return pubSub.asyncIterator([ `${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`, ]) as unknown as AsyncIterable