push code chua nhi?

This commit is contained in:
2024-11-11 22:04:39 +07:00
parent 22bc231409
commit ff45e69efd
7 changed files with 115 additions and 16 deletions

55
package-lock.json generated
View File

@@ -63,6 +63,7 @@
"nodemailer": "^6.9.15", "nodemailer": "^6.9.15",
"openai": "^4.68.4", "openai": "^4.68.4",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"quill": "^2.0.2",
"reflect-metadata": "^0.2.0", "reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.1", "swagger-ui-express": "^5.0.1",
@@ -9777,7 +9778,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true,
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/fast-glob": { "node_modules/fast-glob": {
@@ -13035,6 +13035,18 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "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": { "node_modules/lodash.defaults": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
@@ -13065,6 +13077,12 @@
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT" "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": { "node_modules/lodash.isinteger": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
@@ -14712,6 +14730,12 @@
"tslib": "^2.0.3" "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": { "node_modules/parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -15497,6 +15521,35 @@
"url": "https://github.com/sponsors/sindresorhus" "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": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",

View File

@@ -85,6 +85,7 @@
"nodemailer": "^6.9.15", "nodemailer": "^6.9.15",
"openai": "^4.68.4", "openai": "^4.68.4",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"quill": "^2.0.2",
"reflect-metadata": "^0.2.0", "reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.1", "swagger-ui-express": "^5.0.1",

View File

@@ -12,7 +12,7 @@ import AuthzPlugin from '@pothos/plugin-authz'
import ErrorsPlugin from '@pothos/plugin-errors' import ErrorsPlugin from '@pothos/plugin-errors'
import type { FileUpload } from 'graphql-upload/processRequest.js' import type { FileUpload } from 'graphql-upload/processRequest.js'
import GraphQLUpload from 'graphql-upload/GraphQLUpload.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 { PrismaCrudGenerator } from './graphql.generator'
import type PrismaTypes from '../types/pothos.generated' import type PrismaTypes from '../types/pothos.generated'
import PrismaUtils from '@pothos/plugin-prisma-utils' import PrismaUtils from '@pothos/plugin-prisma-utils'
@@ -107,6 +107,7 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
// optionally customize how errors are formatted // optionally customize how errors are formatted
validationError: (zodError, _args, _context, _info) => { validationError: (zodError, _args, _context, _info) => {
// the default behavior is to just throw the zod error directly // the default behavior is to just throw the zod error directly
Logger.error(zodError.message, 'Zod Error')
return zodError return zodError
}, },
}, },

View File

@@ -56,6 +56,7 @@ export class MessageSchema extends PothosSchema {
}), }),
metadata: t.expose('metadata', { metadata: t.expose('metadata', {
type: 'Json', type: 'Json',
nullable: true,
description: 'The metadata of the message.', description: 'The metadata of the message.',
}), }),
sender: t.relation('sender', { sender: t.relation('sender', {

View File

@@ -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()
}
}

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
// @ts-ignore // import Quil, { Delta } from 'quill'
import * as Y from 'yjs'
@Injectable() @Injectable()
export class RealtimeService { export class RealtimeService {
yjs = new Y.Doc() // constructor(private readonly quil: Quil) {}
} }

View File

@@ -11,8 +11,11 @@ import { clerkClient } from '@clerk/express'
import { UnauthorizedException } from '@nestjs/common' import { UnauthorizedException } from '@nestjs/common'
import { MailService } from '../Mail/mail.service' import { MailService } from '../Mail/mail.service'
import { MessageSchema } from 'src/Message/message.schema' 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 { 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() @Injectable()
export class UserSchema extends PothosSchema { export class UserSchema extends PothosSchema {
constructor( constructor(
@@ -50,16 +53,6 @@ export class UserSchema extends PothosSchema {
}), }),
packageValue: t.exposeFloat('packageValue', { packageValue: t.exposeFloat('packageValue', {
description: 'The package value of the user.', 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, nullable: true,
}), }),
role: t.exposeString('role', { 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 // Subscription section
@@ -401,6 +433,7 @@ export class UserSchema extends PothosSchema {
const { const {
websocket: { pubSub }, websocket: { pubSub },
} = ctx } = ctx
Logger.log(ctx.websocket.me?.id, 'Me ID')
return pubSub.asyncIterator([ return pubSub.asyncIterator([
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`, `${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
]) as unknown as AsyncIterable<Message> ]) as unknown as AsyncIterable<Message>