diff --git a/src/api/extensions/prismaExtensionPgpathToMysql.js b/src/api/extensions/prismaExtensionPgpathToMysql.js new file mode 100644 index 000000000..1cc3e2b0f --- /dev/null +++ b/src/api/extensions/prismaExtensionPgpathToMysql.js @@ -0,0 +1,63 @@ +import { Prisma } from '@prisma/client' +import { Logger } from '@config/logger.config'; + +const logger = new Logger('PGPATH2MYSQL'); + +function convertPgPathToMysql (path) { + if (!Array.isArray(path)) { + return path + } + let result = '$' + for (const item of path) { + if (/^\d+$/.test(item)) { + result += `[${item}]` + } else { + result += `.${item}` + } + } + return result +} + +function processWhere (obj) { + if (obj && typeof obj === 'object') { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (key === 'path') { + obj[key] = convertPgPathToMysql(obj[key]); + } else { + processWhere(obj[key]); + } + } + } + } +} + +// https://www.prisma.io/docs/orm/prisma-client/client-extensions/query#modify-all-operations-in-all-models-of-your-schema +// https://www.prisma.io/docs/orm/prisma-client/client-extensions/query#modify-a-specific-operation-in-a-specific-model + +const overriddenOperation = async ({ model, operation, args, query }) => { + if (args?.where) { + processWhere(args.where) + } + const result = await query(args) + logger.debug({ model, operation, args: JSON.stringify(args), result }) + return result +} + +export default Prisma.defineExtension({ + name: 'prisma-extension-pgpath-to-mysql', + query: { + $allModels: { + findFirst: overriddenOperation, + findMany: overriddenOperation, + updateMany: overriddenOperation, + count: overriddenOperation, + deleteMany: overriddenOperation, + + delete: overriddenOperation, + findUnique: overriddenOperation, + update: overriddenOperation, + upsert: overriddenOperation, + } + } +}) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 10feb7ce1..2e29b7cdc 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -1509,7 +1509,7 @@ export class BaileysStartupService extends ChannelStartupService { remoteJid: key.remoteJid, fromMe: key.fromMe, participant: key?.remoteJid, - status: status[update.status], + status: status[update.status] ?? findMessage.status, pollUpdates, instanceId: this.instanceId, }; diff --git a/src/api/server.module.ts b/src/api/server.module.ts index 49fc56952..c72a0a0cb 100644 --- a/src/api/server.module.ts +++ b/src/api/server.module.ts @@ -1,7 +1,8 @@ import { CacheEngine } from '@cache/cacheengine'; -import { Chatwoot, configService, ProviderSession } from '@config/env.config'; +import { Chatwoot, configService, Database, ProviderSession } from '@config/env.config'; import { eventEmitter } from '@config/event.config'; import { Logger } from '@config/logger.config'; +import { extendsWithProxy } from '@utils/extendsWithProxy'; import { CallController } from './controllers/call.controller'; import { ChatController } from './controllers/chat.controller'; @@ -12,6 +13,7 @@ import { ProxyController } from './controllers/proxy.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; import { SettingsController } from './controllers/settings.controller'; import { TemplateController } from './controllers/template.controller'; +import pgPathToMysql from './extensions/prismaExtensionPgpathToMysql'; import { ChannelController } from './integrations/channel/channel.controller'; import { EvolutionController } from './integrations/channel/evolution/evolution.controller'; import { MetaController } from './integrations/channel/meta/meta.controller'; @@ -55,7 +57,12 @@ if (configService.get('PROVIDER').ENABLED) { providerFiles = new ProviderFiles(configService); } -export const prismaRepository = new PrismaRepository(configService); +const provider = configService.get('DATABASE').PROVIDER; +let extendablePrismaRepository: PrismaRepository = new PrismaRepository(configService); +if (typeof provider === 'string' && provider?.toLowerCase() === 'mysql') { + extendablePrismaRepository = extendsWithProxy(extendablePrismaRepository, pgPathToMysql); +} +export const prismaRepository = extendablePrismaRepository; export const waMonitor = new WAMonitoringService( eventEmitter, diff --git a/src/utils/extendsWithProxy.ts b/src/utils/extendsWithProxy.ts new file mode 100644 index 000000000..90c92238f --- /dev/null +++ b/src/utils/extendsWithProxy.ts @@ -0,0 +1,26 @@ +import { PrismaClient } from '@prisma/client'; + +type ExtensionArgs = Parameters[0]; + +export function extendsWithProxy(instanciaBase: T, extensao: ExtensionArgs): T { + const instanciaEstendida = instanciaBase.$extends(extensao); + + const proxy = new Proxy(instanciaBase as unknown as object, { + get(target, prop, receiver) { + if (prop === 'toString') { + return () => '[Proxy toString]'; + } + if (prop === Symbol.toStringTag) { + return undefined; + } + return prop in instanciaEstendida + ? Reflect.get(instanciaEstendida as any, prop, receiver) + : Reflect.get(target, prop, receiver); + }, + has(target, prop) { + return prop in target || prop in (instanciaEstendida as any); + }, + }); + + return proxy as unknown as T; +} diff --git a/tsconfig.json b/tsconfig.json index af814134a..28a3630a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,7 @@ "strictNullChecks": false, "incremental": true, "noImplicitAny": false, + "allowJs": true, "baseUrl": ".", "paths": { "@api/*": ["./src/api/*"],