mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
feat(nestjs): migrate to NestJS
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import { PageProperties, PdfFormat } from '@/libs/Chromiumly/_types';
|
||||
import { UrlConverter } from '@/libs/Chromiumly/UrlConvert';
|
||||
import { Chromiumly } from '@/libs/Chromiumly/Chromiumly';
|
||||
import {
|
||||
PDF_FILE_EXPIRE_IN,
|
||||
getPdfFilePath,
|
||||
getPdfFilesStorageDir,
|
||||
} from './utils';
|
||||
import { Document } from './models/Document';
|
||||
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class ChromiumlyHtmlConvert {
|
||||
/**
|
||||
* @param {TenantModelProxy<typeof Document>} documentModel - Document model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(Document.name)
|
||||
private documentModel: TenantModelProxy<typeof Document>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Write HTML content to temporary file.
|
||||
* @param {string} content - HTML content.
|
||||
* @returns {Promise<[string, () => Promise<void>]>}
|
||||
*/
|
||||
async writeTempHtmlFile(
|
||||
content: string,
|
||||
): Promise<[string, () => Promise<void>]> {
|
||||
const filename = `document-print-${Date.now()}.html`;
|
||||
const filePath = getPdfFilePath(filename);
|
||||
|
||||
await fs.writeFile(filePath, content);
|
||||
await this.documentModel()
|
||||
.query()
|
||||
.insert({ key: filename, mimeType: 'text/html' });
|
||||
|
||||
const cleanup = async () => {
|
||||
await fs.unlink(filePath);
|
||||
await Document.query().where('key', filename).delete();
|
||||
};
|
||||
return [filename, cleanup];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given HTML content to PDF.
|
||||
* @param {string} html
|
||||
* @param {PageProperties} properties
|
||||
* @param {PdfFormat} pdfFormat
|
||||
* @returns {Array<Buffer>}
|
||||
*/
|
||||
async convert(
|
||||
html: string,
|
||||
properties?: PageProperties,
|
||||
pdfFormat?: PdfFormat,
|
||||
): Promise<Buffer> {
|
||||
const [filename, cleanupTempFile] = await this.writeTempHtmlFile(html);
|
||||
const fileDir = getPdfFilesStorageDir(filename);
|
||||
|
||||
const url = path.join(Chromiumly.GOTENBERG_DOCS_ENDPOINT, fileDir);
|
||||
const urlConverter = new UrlConverter();
|
||||
|
||||
const buffer = await urlConverter.convert({
|
||||
url,
|
||||
properties,
|
||||
pdfFormat,
|
||||
});
|
||||
await cleanupTempFile();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ChromiumlyHtmlConvert } from './ChromiumlyHtmlConvert.service';
|
||||
import { ChromiumlyTenancy } from './ChromiumlyTenancy.service';
|
||||
|
||||
@Module({
|
||||
providers: [ChromiumlyHtmlConvert, ChromiumlyTenancy],
|
||||
exports: [ChromiumlyHtmlConvert, ChromiumlyTenancy],
|
||||
})
|
||||
export class ChromiumlyTenancyModule {}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { PageProperties, PdfFormat } from '@/libs/Chromiumly/_types';
|
||||
import { ChromiumlyHtmlConvert } from './ChromiumlyHtmlConvert.service';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class ChromiumlyTenancy {
|
||||
constructor(private htmlConvert: ChromiumlyHtmlConvert) {}
|
||||
|
||||
/**
|
||||
* Converts the given HTML content to PDF.
|
||||
* @param {string} content
|
||||
* @param {PageProperties} properties
|
||||
* @param {PdfFormat} pdfFormat
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
public convertHtmlContent(
|
||||
content: string,
|
||||
properties?: PageProperties,
|
||||
pdfFormat?: PdfFormat
|
||||
) {
|
||||
const parsedProperties = {
|
||||
margins: { top: 0, bottom: 0, left: 0, right: 0 },
|
||||
...properties,
|
||||
}
|
||||
return this.htmlConvert.convert(content, parsedProperties, pdfFormat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { mixin } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
export class Document extends BaseModel {
|
||||
public key: string;
|
||||
public mimeType: string;
|
||||
public size?: number;
|
||||
public originName?: string;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'documents';
|
||||
}
|
||||
|
||||
/**
|
||||
* Model timestamps.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
export class DocumentLink extends BaseModel{
|
||||
public modelRef: string;
|
||||
public modelId: number;
|
||||
public documentId: number;
|
||||
public expiresAt?: Date;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'document_links';
|
||||
}
|
||||
|
||||
/**
|
||||
* Model timestamps.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const Document = require('./Document');
|
||||
|
||||
return {
|
||||
/**
|
||||
* Sale invoice associated entries.
|
||||
*/
|
||||
document: {
|
||||
relation: Model.HasOneRelation,
|
||||
modelClass: Document.default,
|
||||
join: {
|
||||
from: 'document_links.documentId',
|
||||
to: 'documents.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
14
packages/server/src/modules/ChromiumlyTenancy/utils.ts
Normal file
14
packages/server/src/modules/ChromiumlyTenancy/utils.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import path from 'path';
|
||||
|
||||
export const PDF_FILE_SUB_DIR = '/pdf';
|
||||
export const PDF_FILE_EXPIRE_IN = 40; // ms
|
||||
|
||||
export const getPdfFilesStorageDir = (filename: string) => {
|
||||
return path.join(PDF_FILE_SUB_DIR, filename);
|
||||
};
|
||||
|
||||
export const getPdfFilePath = (filename: string) => {
|
||||
const storageDir = getPdfFilesStorageDir(filename);
|
||||
|
||||
return path.join(global.__storage_dir, storageDir);
|
||||
};
|
||||
Reference in New Issue
Block a user