All files / libs/vendors/carbone/src/lib carbone.service.ts

100% Statements 87/87
100% Branches 9/9
100% Functions 3/3
100% Lines 87/87

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 881x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 2x 2x 1x 2x 2x 1x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 1x 1x 4x 4x 1x  
import { BadGatewayException, Injectable, Logger } from '@nestjs/common';
 
import { toError } from '@amalia/ext/typescript';
 
import { createCarboneClient, type CarboneClient } from './carbone-sdk';
import { InjectCarboneConfig, type CarboneConfig } from './carbone.config';
 
const CARBONE_API_VERSION = 5;
 
export type RenderCarboneTemplateToPdfArgs = {
  readonly data: Record<string, unknown> | unknown[];
  readonly lang?: string;
  readonly reportName?: string;
  readonly template: Buffer;
  readonly templateExtension: 'docx' | 'odt';
  readonly timezone?: string;
};
 
@Injectable()
export class CarboneService {
  private readonly client: CarboneClient;
 
  private readonly logger = new Logger(CarboneService.name);
 
  public constructor(@InjectCarboneConfig() private readonly config: CarboneConfig) {
    this.client = createCarboneClient();
    this.client.setApiVersion(CARBONE_API_VERSION);
    this.client.setOptions({ carboneUrl: this.ensureTrailingSlash(config.baseUrl) });
  }
 
  public async renderTemplateToPdf({
    data,
    lang,
    reportName,
    template,
    templateExtension,
    timezone,
  }: RenderCarboneTemplateToPdfArgs) {
    const renderStartedAt = Date.now();
 
    try {
      this.logger.debug({
        message: 'Starting Carbone document render',
        reportName,
        templateExtension,
        templateSizeBytes: template.byteLength,
      });
 
      const response = await this.client.renderPromise(template, {
        data,
        convertTo: 'pdf',
        ...(lang && {
          lang,
        }),
        ...(reportName && {
          reportName,
        }),
        ...(timezone && {
          timezone,
        }),
      });
 
      this.logger.debug({
        message: 'Completed Carbone document render',
        reportName,
        templateExtension,
        elapsedMs: Date.now() - renderStartedAt,
      });
 
      return Buffer.from(response.content);
    } catch (error) {
      this.logger.error({
        message: 'Failed Carbone document render',
        error: toError(error),
        reportName,
        templateExtension,
        elapsedMs: Date.now() - renderStartedAt,
      });
 
      throw new BadGatewayException('Error while rendering the document to PDF.');
    }
  }
 
  private ensureTrailingSlash(url: string): string {
    return url.endsWith('/') ? url : `${url}/`;
  }
}