UNPKG

@onereach/content-builder-template-compiler

Version:

Compiles template literals with data records

131 lines (113 loc) 3.79 kB
const _ = require("lodash"); module.exports = { getTemplateCompiler(data, parent, root = data, index = '') { function getTemplateCompiler(data, parent = data, root = data, index = '') { function evalExpression(strings, ...values) { if (strings.length === 1) return strings[0]; if (strings.length === 2 && strings[0] === '' && strings[1] === '') return values[0]; return strings.reduce((acc, item, idx) => { acc += item; if (idx < values.length) acc += values[idx]; return acc; }, ''); } function compileData(exp) { if (typeof exp !== 'string') return exp; const vars = ["$data", "$parent", "$root", "$index", "_evalExpression"]; const { keys, values } = Object.entries(data).reduce( (memo, [key, value]) => { if (vars.indexOf(key) === -1) { memo.keys.push(key); memo.values.push(value); } return memo; }, { keys: [], values: [] } ); return new Function( ...vars, ...keys, `return _evalExpression\`${exp.replaceAll('`', '\\`')}\`` )(data, parent, root, index, evalExpression, ...values); } return function compile(template, key, keySuffix) { if (template == null) return template; if (!['string', 'object'].includes(typeof template)) { return template; } if (typeof template === 'string') { const s = compileData(template); if (key === 'key' && keySuffix !== undefined) { return `${s}--${keySuffix}`; } return s; } if (Array.isArray(template)) { return template.reduce( (acc, item, key) => acc.concat(compile(item, key)), [] ); } if (template && Object.prototype.hasOwnProperty.call(template, 'urn')) { if (template['$repeat'] !== undefined) { let { $repeat: items, ...tmpl } = template; if (typeof items === 'string') { items = compile(items, '$repeat'); } if (Array.isArray(items)) { const listItems = _.reduce( items, (acc, item, index) => { const compile = getTemplateCompiler(item, data, root, index); return acc.concat(compile(tmpl, index, index)); }, [] ); return listItems; } } if (template['$data'] !== undefined) { let { $data: newData, ...tmpl } = template; if (typeof newData === 'string') { newData = compile(newData, '$data'); } if (newData !== undefined) { let compile = getTemplateCompiler(newData, data, root, index); return compile(tmpl, key, keySuffix); } } if (template['$when'] !== undefined) { let { $when: condition, ...tmpl } = template; if (typeof condition === 'string') { condition = compile(condition, '$when'); } if (!condition) return []; return compile(tmpl, key, keySuffix); } } return Object.keys(template).reduce( (memo, key) => { return Object.assign(memo, { [key]: compile(template[key], key, keySuffix) }) }, {} ); } } return getTemplateCompiler(data, parent, root, index); } };