const Vue = require('vue'); const VueI18n = require('vue-i18n'); const renderer = require('vue-server-renderer').createRenderer(); Vue.use(VueI18n); const fs = require('fs'); const yaml = require('js-yaml'); const juice = require('juice'); const path = require('path'); const config = require('./config'); class Component { constructor(name, template) { console.log('cosntructor Component'); console.log('template: ', template); console.log('name: ', name); this.name = name; this._template = template; } get path() { return `./components/${this.name}`; } get template() { console.log('this._template: ', this._template); if (this._template) return this._template; const templatePath = `${this.path}/${this.name}.html`; const fullPath = path.resolve(__dirname, templatePath); console.log('fullPath: ', fullPath); if (!fs.existsSync(fullPath)) { const path = require('path'); const vnPrintPath = path.resolve('print'); return fs.readFileSync(`${vnPrintPath}/core/components/blank-template/blank-template.html`, 'utf8'); } return fs.readFileSync(fullPath, 'utf8'); } get locale() { if (!this._locale) this._locale = this.getLocales(); return this._locale; } getLocales() { const mergedLocales = {messages: {}}; const localePath = path.resolve(__dirname, `${this.path}/locale`); if (!fs.existsSync(localePath)) return mergedLocales; const localeDir = fs.readdirSync(localePath); for (const locale of localeDir) { const fullPath = path.join(localePath, '/', locale); const yamlLocale = fs.readFileSync(fullPath, 'utf8'); const jsonLocale = yaml.safeLoad(yamlLocale); const localeName = locale.replace('.yml', ''); mergedLocales.messages[localeName] = jsonLocale; } return mergedLocales; } async getUserLocale() { let lang = this.args.lang; // Fetches user locale from mixing method getLocale() if (this.args.recipientId) { const component = await this.component(); lang = await component.getLocale(this.args.recipientId); } const messages = this.locale.messages; const userTranslations = messages[lang]; if (!userTranslations) { const fallbackLang = config.i18n.fallbackLocale; return messages[fallbackLang]; } return userTranslations; } get stylesheet() { let css = []; const path = require('path'); const vnPrintPath = path.resolve('print'); const styles = require(`${vnPrintPath}/common/css/index.js`); for (const style of styles) css.push(fs.readFileSync(style)); const style = `${path.resolve(__dirname, this.path)}/assets/css/style.css`; // regex to match css files if (fs.existsSync(style)) css.push(fs.readFileSync(style)); return css.join('\n'); } get attachments() { const attachmentsPath = `${this.path}/attachments.json`; const fullPath = path.resolve(__dirname, attachmentsPath); if (!fs.existsSync(fullPath)) return []; return require(fullPath); } build() { console.log('this.name ', this.name); console.log('this._template: ', this._template); const fullPath = path.resolve(__dirname, this.path); if (!fs.existsSync(fullPath)) throw new Error(`Template "${this.name}" not found`); let component = {}; if (this.template !== undefined) { component = require(`${this.path}/${this.name}`); component.template = juice.inlineContent(this.template, this.stylesheet, { inlinePseudoElements: true }); } component.i18n = this.locale; component.attachments = this.attachments; const tplPath = this.path; if (!component.computed) component.computed = {}; component.computed.path = function() { return tplPath; }; return component; } component() { if (this._component) return this._component; const component = this.build(); const i18n = new VueI18n(config.i18n); const props = {...this.args}; this._component = new Vue({ i18n: i18n, render: h => h(component, { props: props }) }); return this._component; } /** * @return {Promise} Rendered component */ async render() { const render = await renderer.renderToString( this.component() ); return render; } } module.exports = Component;