import { OnModuleInit, Inject, Injectable, HttpException, HttpStatus, InternalServerErrorException, } from '@nestjs/common'; import { firstValueFrom, lastValueFrom, ReplaySubject } from 'rxjs'; import { Link } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities'; import { DucClient } from '../duc/client.config'; import { ClientGrpc } from '@nestjs/microservices'; import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; import { CustomerUpdateRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; import { ThemeProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; import { ThemeRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; import { CustomerThemeRequest, CustomerThemeResponse } from './dtos/customers'; import DadosferaLogger from '@dadosfera/dadosfera-logs'; import { resolve } from 'path'; import { Readable } from 'stream'; type Files = { logoWhite: Express.Multer.File, logoBlack: Express.Multer.File, } // This function will accept any string, which may result in a bug. @Injectable() export class ThemeService implements OnModuleInit { private themeService: ThemeProtoService; private logger: DadosferaLogger; constructor( @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, ) { this.logger = dadosferaLogger.logger; } onModuleInit() { this.themeService = this.grpcClient.getService( ProtoServices.ThemeProtoService, ); } async createThemeByCustomer(id: string, theme: CustomerThemeRequest & Files) { if (!id) { this.logger.error('Error - saveCustomertheme - not found id:' + id); throw new HttpException(null, HttpStatus.BAD_REQUEST); } const customerThemeRequest$ = new ReplaySubject(); customerThemeRequest$.next({ customerId: id, displayName: theme.displayName, backgroundColor: theme.backgroundColor, textColor: theme.textColor, isMetadata: true, filename: '', chunk: Buffer.alloc(0) }) if(theme.logoBlack) { await this.sendFile(theme.logoBlack, customerThemeRequest$); } if(theme.logoWhite) { await this.sendFile(theme.logoWhite, customerThemeRequest$); } customerThemeRequest$.complete(); const stream = this.themeService.CustomerCreateTheme(customerThemeRequest$); return lastValueFrom(stream); } async getThemeByCustomer(id: string): Promise { if (!id) { this.logger.error('Error - getCustomerTheme - not found id:' + id); throw new HttpException(null, HttpStatus.BAD_REQUEST); } const { theme } = await firstValueFrom( this.themeService.CustomerGetTheme({ id }), ); return { theme } } private async sendFile(file: Express.Multer.File, stream$: ReplaySubject) { const bufferStream = new Readable({ highWaterMark: 1024 * 1024, // 1 MB por chunk read() {} }); bufferStream.push(file.buffer); bufferStream.push(null); return new Promise((resolve, reject) => { bufferStream.on('data', (chunk) => { console.log('enviando chunk', file.fieldname) const mimetype = file.mimetype.split('/')[1]; // example image/jpeg const filename = file.fieldname.concat(".", mimetype); stream$.next({ customerId: '', displayName: '', backgroundColor: '', textColor: '', isMetadata: false, filename: filename, chunk: chunk }); }); bufferStream.on('end', () => { console.log('terminou de enviar') resolve(file.filename) }); bufferStream.on('error', (err) => { console.error('Erro no stream:', err); reject(err); }); }); } }