/* eslint-env node */ /* eslint-disable no-console */ 'use strict'; // istanbul ignore next function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } // istanbul ignore next function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _neoAsync = require('neo-async'); var _neoAsync2 = _interopRequireDefault(_neoAsync); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _handlebars = require('./handlebars'); var Handlebars = _interopRequireWildcard(_handlebars); var _handlebarsCompilerCodeGen = require('./handlebars/compiler/code-gen'); var _path = require('path'); var _sourceMap = require('source-map'); module.exports.loadTemplates = function (opts, callback) { loadStrings(opts, function (err, strings) { if (err) { callback(err); } else { loadFiles(opts, function (err, files) { if (err) { callback(err); } else { opts.templates = strings.concat(files); callback(undefined, opts); } }); } }); }; function loadStrings(opts, callback) { var strings = arrayCast(opts.string), names = arrayCast(opts.name); if (names.length !== strings.length && strings.length > 1) { return callback(new Handlebars.Exception('Number of names did not match the number of string inputs')); } _neoAsync2['default'].map(strings, function (string, callback) { if (string !== '-') { callback(undefined, string); } else { (function () { // Load from stdin var buffer = ''; process.stdin.setEncoding('utf8'); process.stdin.on('data', function (chunk) { buffer += chunk; }); process.stdin.on('end', function () { callback(undefined, buffer); }); })(); } }, function (err, strings) { strings = strings.map(function (string, index) { return { name: names[index], path: names[index], source: string }; }); callback(err, strings); }); } function loadFiles(opts, callback) { // Build file extension pattern var extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-[\]]/g, function (arg) { return '\\' + arg; }); extension = new RegExp('\\.' + extension + '$'); var ret = [], queue = (opts.files || []).map(function (template) { return { template: template, root: opts.root }; }); _neoAsync2['default'].whilst(function () { return queue.length; }, function (callback) { var _queue$shift = queue.shift(); var path = _queue$shift.template; var root = _queue$shift.root; _fs2['default'].stat(path, function (err, stat) { if (err) { return callback(new Handlebars.Exception('Unable to open template file "' + path + '"')); } if (stat.isDirectory()) { opts.hasDirectory = true; _fs2['default'].readdir(path, function (err, children) { /* istanbul ignore next : Race condition that being too lazy to test */ if (err) { return callback(err); } children.forEach(function (file) { var childPath = path + '/' + file; if (extension.test(childPath) || _fs2['default'].statSync(childPath).isDirectory()) { queue.push({ template: childPath, root: root || path }); } }); callback(); }); } else { _fs2['default'].readFile(path, 'utf8', function (err, data) { /* istanbul ignore next : Race condition that being too lazy to test */ if (err) { return callback(err); } if (opts.bom && data.indexOf('') === 0) { data = data.substring(1); } // Clean the template name var name = path; if (!root) { name = _path.basename(name); } else if (name.indexOf(root) === 0) { name = name.substring(root.length + 1); } name = name.replace(extension, ''); ret.push({ path: path, name: name, source: data }); callback(); }); } }); }, function (err) { if (err) { callback(err); } else { callback(undefined, ret); } }); } module.exports.cli = function (opts) { if (opts.version) { console.log(Handlebars.VERSION); return; } if (!opts.templates.length && !opts.hasDirectory) { throw new Handlebars.Exception('Must define at least one template or directory.'); } if (opts.simple && opts.min) { throw new Handlebars.Exception('Unable to minimize simple output'); } var multiple = opts.templates.length !== 1 || opts.hasDirectory; if (opts.simple && multiple) { throw new Handlebars.Exception('Unable to output multiple templates in simple mode'); } // Force simple mode if we have only one template and it's unnamed. if (!opts.amd && !opts.commonjs && opts.templates.length === 1 && !opts.templates[0].name) { opts.simple = true; } // Convert the known list into a hash var known = {}; if (opts.known && !Array.isArray(opts.known)) { opts.known = [opts.known]; } if (opts.known) { for (var i = 0, len = opts.known.length; i < len; i++) { known[opts.known[i]] = true; } } var objectName = opts.partial ? 'Handlebars.partials' : 'templates'; if (opts.namespace && !isValidNamespace(opts.namespace)) { throw new Handlebars.Exception('Invalid namespace format'); } var output = new _sourceMap.SourceNode(); if (!opts.simple) { if (opts.amd) { var runtimeModulePath = (opts.handlebarPath || '') + 'handlebars.runtime'; output.add('define([' + quoteForJavaScript(runtimeModulePath) + '], function(Handlebars) {\n Handlebars = Handlebars["default"];'); } else if (opts.commonjs) { output.add('var Handlebars = require(' + quoteForJavaScript(opts.commonjs) + ');'); } else { output.add('(function() {\n'); } output.add(' var template = Handlebars.template, templates = '); if (opts.namespace) { output.add(opts.namespace); output.add(' = '); output.add(opts.namespace); output.add(' || '); } output.add('{};\n'); } opts.templates.forEach(function (template) { var options = { knownHelpers: known, knownHelpersOnly: opts.o }; if (opts.map) { options.srcName = template.path; } if (opts.data) { options.data = true; } var precompiled = Handlebars.precompile(template.source, options); // If we are generating a source map, we have to reconstruct the SourceNode object if (opts.map) { var consumer = new _sourceMap.SourceMapConsumer(precompiled.map); precompiled = _sourceMap.SourceNode.fromStringWithSourceMap(precompiled.code, consumer); } if (opts.simple) { output.add([precompiled, '\n']); } else { if (!template.name) { throw new Handlebars.Exception('Name missing for template'); } if (opts.amd && !multiple) { output.add('return '); } output.add([objectName, '[', quoteForJavaScript(template.name), '] = template(', precompiled, ');\n']); } }); // Output the content if (!opts.simple) { if (opts.amd) { if (multiple) { output.add(['return ', objectName, ';\n']); } output.add('});'); } else if (!opts.commonjs) { output.add('})();'); } } if (opts.map) { output.add('\n//# sourceMappingURL=' + sanitizeSourceMapComment(opts.map) + '\n'); } output = output.toStringWithSourceMap(); output.map = output.map + ''; if (opts.min) { output = minify(output, opts.map); } if (opts.map) { _fs2['default'].writeFileSync(opts.map, output.map, 'utf8'); } output = output.code; if (opts.output) { _fs2['default'].writeFileSync(opts.output, output, 'utf8'); } else { console.log(output); } }; function arrayCast(value) { value = value != null ? value : []; if (!Array.isArray(value)) { value = [value]; } return value; } /* * Safely quotes a value for embedding in generated JavaScript strings * * Uses JSON.stringify which handles all special characters, and also escapes * line separators and the sequences that could end or change the parsing of an * enclosing