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};