Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / handlebars / lib / precompiler.js
1 /* eslint-disable no-console */
2 import Async from 'async';
3 import fs from 'fs';
4 import * as Handlebars from './handlebars';
5 import {basename} from 'path';
6 import {SourceMapConsumer, SourceNode} from 'source-map';
7 import uglify from 'uglify-js';
8
9 module.exports.loadTemplates = function(opts, callback) {
10   loadStrings(opts, function(err, strings) {
11     if (err) {
12       callback(err);
13     } else {
14       loadFiles(opts, function(err, files) {
15         if (err) {
16           callback(err);
17         } else {
18           opts.templates = strings.concat(files);
19           callback(undefined, opts);
20         }
21       });
22     }
23   });
24 };
25
26 function loadStrings(opts, callback) {
27   let strings = arrayCast(opts.string),
28       names = arrayCast(opts.name);
29
30   if (names.length !== strings.length
31       && strings.length > 1) {
32     return callback(new Handlebars.Exception('Number of names did not match the number of string inputs'));
33   }
34
35   Async.map(strings, function(string, callback) {
36       if (string !== '-') {
37         callback(undefined, string);
38       } else {
39         // Load from stdin
40         let buffer = '';
41         process.stdin.setEncoding('utf8');
42
43         process.stdin.on('data', function(chunk) {
44           buffer += chunk;
45         });
46         process.stdin.on('end', function() {
47           callback(undefined, buffer);
48         });
49       }
50     },
51     function(err, strings) {
52       strings = strings.map((string, index) => ({
53         name: names[index],
54         path: names[index],
55         source: string
56       }));
57       callback(err, strings);
58     });
59 }
60
61 function loadFiles(opts, callback) {
62   // Build file extension pattern
63   let extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-\[\]]/g, function(arg) { return '\\' + arg; });
64   extension = new RegExp('\\.' + extension + '$');
65
66   let ret = [],
67       queue = (opts.files || []).map((template) => ({template, root: opts.root}));
68   Async.whilst(() => queue.length, function(callback) {
69     let {template: path, root} = queue.shift();
70
71     fs.stat(path, function(err, stat) {
72       if (err) {
73         return callback(new Handlebars.Exception(`Unable to open template file "${path}"`));
74       }
75
76       if (stat.isDirectory()) {
77         opts.hasDirectory = true;
78
79         fs.readdir(path, function(err, children) {
80           /* istanbul ignore next : Race condition that being too lazy to test */
81           if (err) {
82             return callback(err);
83           }
84           children.forEach(function(file) {
85             let childPath = path + '/' + file;
86
87             if (extension.test(childPath) || fs.statSync(childPath).isDirectory()) {
88               queue.push({template: childPath, root: root || path});
89             }
90           });
91
92           callback();
93         });
94       } else {
95         fs.readFile(path, 'utf8', function(err, data) {
96           /* istanbul ignore next : Race condition that being too lazy to test */
97           if (err) {
98             return callback(err);
99           }
100
101           if (opts.bom && data.indexOf('\uFEFF') === 0) {
102             data = data.substring(1);
103           }
104
105           // Clean the template name
106           let name = path;
107           if (!root) {
108             name = basename(name);
109           } else if (name.indexOf(root) === 0) {
110             name = name.substring(root.length + 1);
111           }
112           name = name.replace(extension, '');
113
114           ret.push({
115             path: path,
116             name: name,
117             source: data
118           });
119
120           callback();
121         });
122       }
123     });
124   },
125   function(err) {
126     if (err) {
127       callback(err);
128     } else {
129       callback(undefined, ret);
130     }
131   });
132 }
133
134 module.exports.cli = function(opts) {
135   if (opts.version) {
136     console.log(Handlebars.VERSION);
137     return;
138   }
139
140   if (!opts.templates.length && !opts.hasDirectory) {
141     throw new Handlebars.Exception('Must define at least one template or directory.');
142   }
143
144   if (opts.simple && opts.min) {
145     throw new Handlebars.Exception('Unable to minimize simple output');
146   }
147
148   const multiple = opts.templates.length !== 1 || opts.hasDirectory;
149   if (opts.simple && multiple) {
150     throw new Handlebars.Exception('Unable to output multiple templates in simple mode');
151   }
152
153   // Force simple mode if we have only one template and it's unnamed.
154   if (!opts.amd && !opts.commonjs && opts.templates.length === 1
155       && !opts.templates[0].name) {
156     opts.simple = true;
157   }
158
159   // Convert the known list into a hash
160   let known = {};
161   if (opts.known && !Array.isArray(opts.known)) {
162     opts.known = [opts.known];
163   }
164   if (opts.known) {
165     for (let i = 0, len = opts.known.length; i < len; i++) {
166       known[opts.known[i]] = true;
167     }
168   }
169
170   const objectName = opts.partial ? 'Handlebars.partials' : 'templates';
171
172   let output = new SourceNode();
173   if (!opts.simple) {
174     if (opts.amd) {
175       output.add('define([\'' + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n  Handlebars = Handlebars["default"];');
176     } else if (opts.commonjs) {
177       output.add('var Handlebars = require("' + opts.commonjs + '");');
178     } else {
179       output.add('(function() {\n');
180     }
181     output.add('  var template = Handlebars.template, templates = ');
182     if (opts.namespace) {
183       output.add(opts.namespace);
184       output.add(' = ');
185       output.add(opts.namespace);
186       output.add(' || ');
187     }
188     output.add('{};\n');
189   }
190
191   opts.templates.forEach(function(template) {
192     let options = {
193       knownHelpers: known,
194       knownHelpersOnly: opts.o
195     };
196
197     if (opts.map) {
198       options.srcName = template.path;
199     }
200     if (opts.data) {
201       options.data = true;
202     }
203
204     let precompiled = Handlebars.precompile(template.source, options);
205
206     // If we are generating a source map, we have to reconstruct the SourceNode object
207     if (opts.map) {
208       let consumer = new SourceMapConsumer(precompiled.map);
209       precompiled = SourceNode.fromStringWithSourceMap(precompiled.code, consumer);
210     }
211
212     if (opts.simple) {
213       output.add([precompiled, '\n']);
214     } else {
215       if (!template.name) {
216         throw new Handlebars.Exception('Name missing for template');
217       }
218
219       if (opts.amd && !multiple) {
220         output.add('return ');
221       }
222       output.add([objectName, '[\'', template.name, '\'] = template(', precompiled, ');\n']);
223     }
224   });
225
226   // Output the content
227   if (!opts.simple) {
228     if (opts.amd) {
229       if (multiple) {
230         output.add(['return ', objectName, ';\n']);
231       }
232       output.add('});');
233     } else if (!opts.commonjs) {
234       output.add('})();');
235     }
236   }
237
238
239   if (opts.map) {
240     output.add('\n//# sourceMappingURL=' + opts.map + '\n');
241   }
242
243   output = output.toStringWithSourceMap();
244   output.map = output.map + '';
245
246   if (opts.min) {
247     output = uglify.minify(output.code, {
248       fromString: true,
249
250       outSourceMap: opts.map,
251       inSourceMap: JSON.parse(output.map)
252     });
253     if (opts.map) {
254       output.code += '\n//# sourceMappingURL=' + opts.map + '\n';
255     }
256   }
257
258   if (opts.map) {
259     fs.writeFileSync(opts.map, output.map, 'utf8');
260   }
261   output = output.code;
262
263   if (opts.output) {
264     fs.writeFileSync(opts.output, output, 'utf8');
265   } else {
266     console.log(output);
267   }
268 };
269
270 function arrayCast(value) {
271   value = value != null ? value : [];
272   if (!Array.isArray(value)) {
273     value = [value];
274   }
275   return value;
276 }