UNPKG

tarima

Version:
163 lines (126 loc) 4.55 kB
'use strict'; const debug = require('debug')('tarima:renderer'); const fs = require('fs'); const path = require('path'); const parse = require('./parse'); const merge = require('./merge'); const support = require('../support'); module.exports = function render(params, done) { const _cwd = params.options.cwd || process.cwd(); function push(engine, previous) { return new Promise((resolve, reject) => { const fixedMethod = previous === 'js' ? 'compile' : 'render'; function append() { if (previous === 'js' && engine.included) { params.runtimes.push(engine.included); } resolve(); } params.next = previous; try { const _ctx = {}; _ctx.parse = parse; _ctx.render = render; _ctx.support = support; (engine.requires || []) .forEach(moduleId => { const key = moduleId .replace(/\W([a-z])/g, (_, word) => word.toUpperCase()); Object.defineProperty(_ctx, key, { get() { /* eslint-disable global-require */ return require(moduleId); }, }); }); let _called; params.locals = params.locals || {}; params.locals.self = params.locals.self || {}; params.locals.self.cwd = params.locals.self.cwd || _cwd; params.locals.self.parent = params.locals.self.parent || path.relative(_cwd, params.filename); params.locals.self.filename = params.locals.self.filename || path.relative(_cwd, params.filename); const test = engine[fixedMethod].call(_ctx, params, err => { _called = true; if (err) { reject(err); } else { append(); } }); if (test && typeof test.then === 'function') { test.then(append).catch(reject); return; } if (engine[fixedMethod].length > 1) { return; } if (!_called) { append(); } } catch (e) { reject(e); } }); } params.locals = merge({}, params.options.globals, params.options.locals, params.locals, params.data); params.runtimes = []; delete params.locals.$bundle; delete params.locals.$format; delete params.locals.$external; delete params.locals.$transpiler; const pipeline = params.parts.slice().reverse(); const extensions = params.options.extensions || {}; debug('%s', path.relative(_cwd, params.filename)); return pipeline .reduce((prev, cur, i) => prev.then(() => { params.extension = cur; if (extensions[cur] !== false) { const engine = support.resolve(cur); if (engine) { params.extension = engine.ext; return push(engine, pipeline[i + 1]); } } }), Promise.resolve()) .then(() => { // FIXME: doing this `x.keep.js => x.keep.js` is fine? if (extensions[params.extension] === false) { params.extension = params.parts.join('.'); } if (params.isScript && support.isTemplateFunction(params.source)) { params.source = `${params._import ? 'export default' : 'module.exports ='} ${params.source}`; } if (!params.isScript && params.data.$render) { const _layout = path.resolve(path.dirname(params.filename), params.data.$render); const _params = parse(_layout, fs.readFileSync(_layout).toString(), params.options); _params.locals = merge({}, _params.locals || {}, params.locals); _params.locals.yield = params.source; _params.locals.self = _params.locals.self || {}; _params.locals.self.cwd = _params.locals.self.cwd || _cwd; _params.locals.self.parent = _params.locals.self.parent || path.relative(_cwd, params.filename); _params.locals.self.filename = _params.locals.self.filename || path.relative(_cwd, _params.filename); delete params.data.$render; render(_params, (err, result) => { if (!err) { params.source = result.source; params.sourceMap = result.sourceMap; result.deps.forEach(dep => { if (params.deps.indexOf(dep) === -1) { params.deps.push(dep); } }); params.deps.push(_layout); } done(err, params); }); } else { done(undefined, params); } }) .catch(error => done(error, params)); };