Files
edr-platform/apps/edr-freight-api/src/contracts/contract-renderer.service.ts
2026-06-04 15:16:27 +03:00

52 lines
1.7 KiB
TypeScript

import { Injectable, OnModuleInit } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import Handlebars from 'handlebars';
import { ContractViewModel } from './contract-view-model.builder';
@Injectable()
export class ContractRendererService implements OnModuleInit {
private readonly templatesDir = path.join(__dirname, 'templates');
private readonly compiled = new Map<string, Handlebars.TemplateDelegate>();
onModuleInit(): void {
Handlebars.registerHelper('eq', (a: unknown, b: unknown) => a === b);
const partialsDir = path.join(this.templatesDir, '_partials');
if (fs.existsSync(partialsDir)) {
for (const file of fs.readdirSync(partialsDir)) {
if (!file.endsWith('.hbs')) continue;
const name = file.replace(/\.hbs$/, '');
const content = fs.readFileSync(path.join(partialsDir, file), 'utf-8');
Handlebars.registerPartial(name, content);
}
}
}
render(view: ContractViewModel): string {
const fileName =
view.template.templateFile ?? 'generic.hbs';
const template = this.getCompiled(fileName);
return template({
...view,
paymentArticle: view.pricing.currency === 'ETB' ? 'ETB' : 'USD',
});
}
private getCompiled(fileName: string): Handlebars.TemplateDelegate {
const cached = this.compiled.get(fileName);
if (cached) return cached;
const filePath = path.join(this.templatesDir, fileName);
const fallbackPath = path.join(this.templatesDir, 'generic.hbs');
const source = fs.existsSync(filePath)
? fs.readFileSync(filePath, 'utf-8')
: fs.readFileSync(fallbackPath, 'utf-8');
const compiled = Handlebars.compile(source);
this.compiled.set(fileName, compiled);
return compiled;
}
}