1'use strict'; 2 3var fs = require('fs'); 4var path = require('path'); 5var _require = require('./lib'), 6 _prettifyError = _require._prettifyError; 7var compiler = require('./compiler'); 8var _require2 = require('./environment'), 9 Environment = _require2.Environment; 10var precompileGlobal = require('./precompile-global'); 11function match(filename, patterns) { 12 if (!Array.isArray(patterns)) { 13 return false; 14 } 15 return patterns.some(function (pattern) { 16 return filename.match(pattern); 17 }); 18} 19function precompileString(str, opts) { 20 opts = opts || {}; 21 opts.isString = true; 22 var env = opts.env || new Environment([]); 23 var wrapper = opts.wrapper || precompileGlobal; 24 if (!opts.name) { 25 throw new Error('the "name" option is required when compiling a string'); 26 } 27 return wrapper([_precompile(str, opts.name, env)], opts); 28} 29function precompile(input, opts) { 30 // The following options are available: 31 // 32 // * name: name of the template (auto-generated when compiling a directory) 33 // * isString: input is a string, not a file path 34 // * asFunction: generate a callable function 35 // * force: keep compiling on error 36 // * env: the Environment to use (gets extensions and async filters from it) 37 // * include: which file/folders to include (folders are auto-included, files are auto-excluded) 38 // * exclude: which file/folders to exclude (folders are auto-included, files are auto-excluded) 39 // * wrapper: function(templates, opts) {...} 40 // Customize the output format to store the compiled template. 41 // By default, templates are stored in a global variable used by the runtime. 42 // A custom loader will be necessary to load your custom wrapper. 43 44 opts = opts || {}; 45 var env = opts.env || new Environment([]); 46 var wrapper = opts.wrapper || precompileGlobal; 47 if (opts.isString) { 48 return precompileString(input, opts); 49 } 50 var pathStats = fs.existsSync(input) && fs.statSync(input); 51 var precompiled = []; 52 var templates = []; 53 function addTemplates(dir) { 54 fs.readdirSync(dir).forEach(function (file) { 55 var filepath = path.join(dir, file); 56 var subpath = filepath.substr(path.join(input, '/').length); 57 var stat = fs.statSync(filepath); 58 if (stat && stat.isDirectory()) { 59 subpath += '/'; 60 if (!match(subpath, opts.exclude)) { 61 addTemplates(filepath); 62 } 63 } else if (match(subpath, opts.include)) { 64 templates.push(filepath); 65 } 66 }); 67 } 68 if (pathStats.isFile()) { 69 precompiled.push(_precompile(fs.readFileSync(input, 'utf-8'), opts.name || input, env)); 70 } else if (pathStats.isDirectory()) { 71 addTemplates(input); 72 for (var i = 0; i < templates.length; i++) { 73 var name = templates[i].replace(path.join(input, '/'), ''); 74 try { 75 precompiled.push(_precompile(fs.readFileSync(templates[i], 'utf-8'), name, env)); 76 } catch (e) { 77 if (opts.force) { 78 // Don't stop generating the output if we're 79 // forcing compilation. 80 console.error(e); // eslint-disable-line no-console 81 } else { 82 throw e; 83 } 84 } 85 } 86 } 87 return wrapper(precompiled, opts); 88} 89function _precompile(str, name, env) { 90 env = env || new Environment([]); 91 var asyncFilters = env.asyncFilters; 92 var extensions = env.extensionsList; 93 var template; 94 name = name.replace(/\\/g, '/'); 95 try { 96 template = compiler.compile(str, asyncFilters, extensions, name, env.opts); 97 } catch (err) { 98 throw _prettifyError(name, false, err); 99 } 100 return { 101 name: name, 102 template: template 103 }; 104} 105module.exports = { 106 precompile: precompile, 107 precompileString: precompileString 108};