Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80698 views
1
"use strict";
2
3
var fs = require('fs'),
4
Handlebars = require('./index'),
5
basename = require('path').basename,
6
SourceMap = require('source-map'),
7
SourceMapConsumer = SourceMap.SourceMapConsumer,
8
SourceNode = SourceMap.SourceNode,
9
uglify = require('uglify-js');
10
11
module.exports.cli = function(opts) {
12
if (opts.version) {
13
console.log(Handlebars.VERSION);
14
return;
15
}
16
17
if (!opts.templates.length) {
18
throw new Handlebars.Exception('Must define at least one template or directory.');
19
}
20
21
opts.templates.forEach(function(template) {
22
try {
23
fs.statSync(template);
24
} catch (err) {
25
throw new Handlebars.Exception('Unable to open template file "' + template + '"');
26
}
27
});
28
29
if (opts.simple && opts.min) {
30
throw new Handlebars.Exception('Unable to minimize simple output');
31
}
32
if (opts.simple && (opts.templates.length !== 1 || fs.statSync(opts.templates[0]).isDirectory())) {
33
throw new Handlebars.Exception('Unable to output multiple templates in simple mode');
34
}
35
36
// Convert the known list into a hash
37
var known = {};
38
if (opts.known && !Array.isArray(opts.known)) {
39
opts.known = [opts.known];
40
}
41
if (opts.known) {
42
for (var i = 0, len = opts.known.length; i < len; i++) {
43
known[opts.known[i]] = true;
44
}
45
}
46
47
// Build file extension pattern
48
var extension = opts.extension.replace(/[\\^$*+?.():=!|{}\-\[\]]/g, function(arg) { return '\\' + arg; });
49
extension = new RegExp('\\.' + extension + '$');
50
51
var output = new SourceNode();
52
if (!opts.simple) {
53
if (opts.amd) {
54
output.add('define([\'' + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];');
55
} else if (opts.commonjs) {
56
output.add('var Handlebars = require("' + opts.commonjs + '");');
57
} else {
58
output.add('(function() {\n');
59
}
60
output.add(' var template = Handlebars.template, templates = ');
61
if (opts.namespace) {
62
output.add(opts.namespace);
63
output.add(' = ');
64
output.add(opts.namespace);
65
output.add(' || ');
66
}
67
output.add('{};\n');
68
}
69
function processTemplate(template, root) {
70
var path = template,
71
stat = fs.statSync(path);
72
if (stat.isDirectory()) {
73
fs.readdirSync(template).map(function(file) {
74
var path = template + '/' + file;
75
76
if (extension.test(path) || fs.statSync(path).isDirectory()) {
77
processTemplate(path, root || template);
78
}
79
});
80
} else {
81
var data = fs.readFileSync(path, 'utf8');
82
83
if (opts.bom && data.indexOf('\uFEFF') === 0) {
84
data = data.substring(1);
85
}
86
87
var options = {
88
knownHelpers: known,
89
knownHelpersOnly: opts.o
90
};
91
92
if (opts.map) {
93
options.srcName = path;
94
}
95
if (opts.data) {
96
options.data = true;
97
}
98
99
// Clean the template name
100
if (!root) {
101
template = basename(template);
102
} else if (template.indexOf(root) === 0) {
103
template = template.substring(root.length+1);
104
}
105
template = template.replace(extension, '');
106
107
var precompiled = Handlebars.precompile(data, options);
108
109
// If we are generating a source map, we have to reconstruct the SourceNode object
110
if (opts.map) {
111
var consumer = new SourceMapConsumer(precompiled.map);
112
precompiled = SourceNode.fromStringWithSourceMap(precompiled.code, consumer);
113
}
114
115
if (opts.simple) {
116
output.add([precompiled, '\n']);
117
} else if (opts.partial) {
118
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
119
output.add('return ');
120
}
121
output.add(['Handlebars.partials[\'', template, '\'] = template(', precompiled, ');\n']);
122
} else {
123
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
124
output.add('return ');
125
}
126
output.add(['templates[\'', template, '\'] = template(', precompiled, ');\n']);
127
}
128
}
129
}
130
131
opts.templates.forEach(function(template) {
132
processTemplate(template, opts.root);
133
});
134
135
// Output the content
136
if (!opts.simple) {
137
if (opts.amd) {
138
if(opts.templates.length > 1 || (opts.templates.length == 1 && fs.statSync(opts.templates[0]).isDirectory())) {
139
if(opts.partial){
140
output.add('return Handlebars.partials;\n');
141
} else {
142
output.add('return templates;\n');
143
}
144
}
145
output.add('});');
146
} else if (!opts.commonjs) {
147
output.add('})();');
148
}
149
}
150
151
152
if (opts.map) {
153
output.add('\n//# sourceMappingURL=' + opts.map + '\n');
154
}
155
156
output = output.toStringWithSourceMap();
157
output.map = output.map + '';
158
159
if (opts.min) {
160
output = uglify.minify(output.code, {
161
fromString: true,
162
163
outSourceMap: opts.map,
164
inSourceMap: JSON.parse(output.map)
165
});
166
if (opts.map) {
167
output.code += '\n//# sourceMappingURL=' + opts.map + '\n';
168
}
169
}
170
171
if (opts.map) {
172
fs.writeFileSync(opts.map, output.map, 'utf8');
173
}
174
output = output.code;
175
176
if (opts.output) {
177
fs.writeFileSync(opts.output, output, 'utf8');
178
} else {
179
console.log(output);
180
}
181
};
182