1/* eslint-disable no-console */ 2 3'use strict'; 4 5function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } 6function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 7var fs = require('fs'); 8var path = require('path'); 9var Loader = require('./loader'); 10var _require = require('./precompiled-loader.js'), 11 PrecompiledLoader = _require.PrecompiledLoader; 12var chokidar; 13var FileSystemLoader = /*#__PURE__*/function (_Loader) { 14 _inheritsLoose(FileSystemLoader, _Loader); 15 function FileSystemLoader(searchPaths, opts) { 16 var _this; 17 _this = _Loader.call(this) || this; 18 if (typeof opts === 'boolean') { 19 console.log('[nunjucks] Warning: you passed a boolean as the second ' + 'argument to FileSystemLoader, but it now takes an options ' + 'object. See http://mozilla.github.io/nunjucks/api.html#filesystemloader'); 20 } 21 opts = opts || {}; 22 _this.pathsToNames = {}; 23 _this.noCache = !!opts.noCache; 24 if (searchPaths) { 25 searchPaths = Array.isArray(searchPaths) ? searchPaths : [searchPaths]; 26 // For windows, convert to forward slashes 27 _this.searchPaths = searchPaths.map(path.normalize); 28 } else { 29 _this.searchPaths = ['.']; 30 } 31 if (opts.watch) { 32 // Watch all the templates in the paths and fire an event when 33 // they change 34 try { 35 chokidar = require('chokidar'); // eslint-disable-line global-require 36 } catch (e) { 37 throw new Error('watch requires chokidar to be installed'); 38 } 39 var paths = _this.searchPaths.filter(fs.existsSync); 40 var watcher = chokidar.watch(paths); 41 watcher.on('all', function (event, fullname) { 42 fullname = path.resolve(fullname); 43 if (event === 'change' && fullname in _this.pathsToNames) { 44 _this.emit('update', _this.pathsToNames[fullname], fullname); 45 } 46 }); 47 watcher.on('error', function (error) { 48 console.log('Watcher error: ' + error); 49 }); 50 } 51 return _this; 52 } 53 var _proto = FileSystemLoader.prototype; 54 _proto.getSource = function getSource(name) { 55 var fullpath = null; 56 var paths = this.searchPaths; 57 for (var i = 0; i < paths.length; i++) { 58 var basePath = path.resolve(paths[i]); 59 var p = path.resolve(paths[i], name); 60 61 // Only allow the current directory and anything 62 // underneath it to be searched 63 if (p.indexOf(basePath) === 0 && fs.existsSync(p)) { 64 fullpath = p; 65 break; 66 } 67 } 68 if (!fullpath) { 69 return null; 70 } 71 this.pathsToNames[fullpath] = name; 72 var source = { 73 src: fs.readFileSync(fullpath, 'utf-8'), 74 path: fullpath, 75 noCache: this.noCache 76 }; 77 this.emit('load', name, source); 78 return source; 79 }; 80 return FileSystemLoader; 81}(Loader); 82var NodeResolveLoader = /*#__PURE__*/function (_Loader2) { 83 _inheritsLoose(NodeResolveLoader, _Loader2); 84 function NodeResolveLoader(opts) { 85 var _this2; 86 _this2 = _Loader2.call(this) || this; 87 opts = opts || {}; 88 _this2.pathsToNames = {}; 89 _this2.noCache = !!opts.noCache; 90 if (opts.watch) { 91 try { 92 chokidar = require('chokidar'); // eslint-disable-line global-require 93 } catch (e) { 94 throw new Error('watch requires chokidar to be installed'); 95 } 96 _this2.watcher = chokidar.watch(); 97 _this2.watcher.on('change', function (fullname) { 98 _this2.emit('update', _this2.pathsToNames[fullname], fullname); 99 }); 100 _this2.watcher.on('error', function (error) { 101 console.log('Watcher error: ' + error); 102 }); 103 _this2.on('load', function (name, source) { 104 _this2.watcher.add(source.path); 105 }); 106 } 107 return _this2; 108 } 109 var _proto2 = NodeResolveLoader.prototype; 110 _proto2.getSource = function getSource(name) { 111 // Don't allow file-system traversal 112 if (/^\.?\.?(\/|\\)/.test(name)) { 113 return null; 114 } 115 if (/^[A-Z]:/.test(name)) { 116 return null; 117 } 118 var fullpath; 119 try { 120 fullpath = require.resolve(name); 121 } catch (e) { 122 return null; 123 } 124 this.pathsToNames[fullpath] = name; 125 var source = { 126 src: fs.readFileSync(fullpath, 'utf-8'), 127 path: fullpath, 128 noCache: this.noCache 129 }; 130 this.emit('load', name, source); 131 return source; 132 }; 133 return NodeResolveLoader; 134}(Loader); 135module.exports = { 136 FileSystemLoader: FileSystemLoader, 137 PrecompiledLoader: PrecompiledLoader, 138 NodeResolveLoader: NodeResolveLoader 139};