salix/print/lib/emailEngine.js

145 lines
4.3 KiB
JavaScript

const Vue = require('vue');
const VueI18n = require('vue-i18n');
const renderer = require('vue-server-renderer').createRenderer();
const fs = require('fs-extra');
const juice = require('juice');
const smtp = require('./smtp');
const i18n = new VueI18n({
locale: 'es',
});
Vue.use(VueI18n);
if (!process.env.OPENSSL_CONF)
process.env.OPENSSL_CONF = '/etc/ssl/';
module.exports = {
path: `${appPath}/reports`,
/**
* Renders a report component
*
* @param {String} name - Report name
* @param {Object} ctx - Request context
*/
async render(name, ctx) {
const component = require(`${this.path}/${name}`);
const prefetchedData = await this.preFetch(component, ctx);
const app = new Vue({
i18n,
render: h => h(component),
});
return renderer.renderToString(app).then(renderedHtml => {
return {
html: renderedHtml,
data: prefetchedData,
};
});
},
/**
* Prefetch all component data from asyncData method
*
* @param {Object} component - Component object
* @param {Object} ctx - Request context
*/
async preFetch(component, ctx) {
const preFetchData = {attachments: []};
let params = {};
let data = {};
if (Object.keys(ctx.body).length > 0)
params = ctx.body;
if (Object.keys(ctx.query).length > 0)
params = ctx.query;
await this.attachAssets(component);
if (component.hasOwnProperty('data'))
data = component.data();
if (component.hasOwnProperty('asyncData')) {
const asyncData = await component.asyncData(ctx, params);
if (asyncData.locale) {
const locale = component.i18n.messages[asyncData.locale];
preFetchData.subject = locale.subject;
}
if (asyncData.recipient)
preFetchData.recipient = asyncData.recipient;
const mergedData = {...data, ...asyncData};
component.data = function data() {
return mergedData;
};
}
if (data && data.hasOwnProperty('attachments')) {
const fileNames = data.attachments;
fileNames.forEach(attachment => {
const componentPath = `${this.path}/${component.name}`;
let fileSrc = componentPath + attachment;
if (attachment.slice(0, 4) === 'http' || attachment.slice(0, 4) === 'https')
fileSrc = attachment;
const fileName = attachment.split('/').pop();
preFetchData.attachments.push({
filename: fileName,
path: fileSrc,
cid: attachment,
});
});
}
if (component.components) {
const components = component.components;
const promises = [];
Object.keys(components).forEach(component => {
promises.push(this.preFetch(components[component], ctx));
});
return Promise.all(promises).then(results => {
results.forEach(result => {
result.attachments.forEach(atth => {
preFetchData.attachments.push(atth);
});
});
return preFetchData;
});
}
return preFetchData;
},
async attachAssets(component) {
const localePath = `${this.path}/${component.name}/locale.js`;
const templatePath = `${this.path}/${component.name}/index.html`;
const stylePath = `${this.path}/${component.name}/assets/css/style.css`;
const template = await fs.readFile(templatePath, 'utf8');
const css = await fs.readFile(stylePath, 'utf8');
component.i18n = require(localePath);
component.template = juice.inlineContent(template, css);
},
async toEmail(name, ctx) {
const rendered = await this.render(name, ctx);
const data = rendered.data;
const options = {
to: data.recipient,
subject: data.subject,
html: rendered.html,
attachments: data.attachments,
};
return smtp.send(options);
},
};