UNPKG

4.63 kBPlain TextView Raw
1#!/usr/bin/env node
2
3var fs = require('fs')
4 ,path = require('path')
5 ,uglify = require('uglify-js')
6 ,cli = require('commander')
7 ,vash = require('../index')
8
9function prefix(tplStr, options){
10
11 if( options.targetNamespace ){
12
13 tplStr = options.targetNamespace
14 + '["'
15 + ( options.propertyName || options.file.replace(/\/|\\/g, options.separator) )
16 + '"]=' + tplStr;
17
18 // ensure the simple namespace exists
19 var accum = '';
20 options.targetNamespace.split('.').reduce(function(all, prop, i){
21
22 accum += all + prop + ' = ' + all + prop + ' || {};\n';
23 all += prop;
24 return all + '.';
25
26 }, '')
27
28 tplStr = accum + tplStr;
29 }
30
31 return tplStr;
32}
33
34function ugly(tplStr, options){
35
36 var ast
37 ,jsp = uglify.parser
38 ,pro = uglify.uglify;
39
40 if( options.uglify ){
41 ast = jsp.parse(tplStr);
42 ast = pro.ast_mangle(ast);
43 ast = pro.ast_squeeze(ast);
44 tplStr = pro.gen_code(ast);
45 }
46
47 return tplStr;
48}
49
50function render(tpl, options){
51 var model = {};
52
53 if( options.render ){
54
55 try {
56 model = JSON.parse( options.render );
57 } catch(e) {
58 try {
59 model = JSON.parse(fs.readFileSync(options.render));
60 } catch(e) {
61
62 }
63 }
64
65 return tpl(model);
66 }
67
68 return tpl;
69}
70
71function stdin(options){
72 var buffer = ''
73 process.stdin.resume();
74 process.stdin.setEncoding('utf8');
75
76 process.stdin.on('data', function(chunk){
77 buffer += chunk;
78 })
79
80 process.stdin.on('end', function(){
81 var tpl = vash[options.helper ? 'compileHelper' : 'compile'](buffer, options.vopts);
82
83 if( options.render ){
84 tpl = render(tpl, options);
85 } else {
86 tpl = prefix( options.autolink
87 ? tpl.toClientString()
88 : tpl.toString(), options);
89 tpl = ugly(tpl, options);
90 }
91
92 process.stdout.write(tpl);
93 })
94}
95
96function file(filepath, options){
97 var contents = fs.readFileSync( filepath, 'utf8' )
98 ,tpl = vash[options.helper ? 'compileHelper' : 'compile'](contents, options.vopts)
99 ,outpath = path.join(
100 options.out
101 ,path.join(
102 path.dirname(filepath)
103 ,path.basename(filepath) + '.js'
104 ).replace(/\/|\\/g, options.separator)
105 )
106
107 if( options.render ){
108 tpl = render(tpl, options);
109 } else {
110 tpl = prefix( options.autolink
111 ? tpl.toClientString()
112 : tpl.toString(), options);
113 tpl = ugly(tpl, options);
114 }
115
116 if( options.out ) {
117 fs.writeFile( outpath, tpl.toString(), 'utf8', function(err){
118 if(err){ process.stderr.write( err ) }
119 } )
120 } else {
121 process.stdout.write(tpl.toString());
122 }
123}
124
125// TODO: if passed a directory, recursively traverse
126
127cli.on('--help', function(){
128 console.log(' Examples:');
129 console.log('');
130 console.log(' $ echo \'<p>Hello!</p>\' | vash --json \'{ "debug": false }\' -t myapp.tplcache -p hello');
131 console.log('');
132 console.log(' > myapp = myapp || {};');
133 console.log(' > myapp.tplcache = myapp.tplcache || {};');
134 console.log(' > myapp.tplcache["hello"]=vash.link( function anonymous(model,html) {');
135 console.log(' > html.buffer.push(\'<p></p>\\n\'); ');
136 console.log(' > return html.buffer.flush(); ');
137 console.log(' > } )');
138 console.log('');
139 console.log(' Remember to include vash-runtime.js if precompiling for client-side usage.')
140 console.log('');
141});
142
143cli
144 .option('-t, --target-namespace <namespace>', 'Assign template to a <namespace>. Recommended is `vash.helpers.tplcache` for view engine compatibility')
145 .option('-p, --property-name [name]', 'Assign template to property named <name>. Defaults to filename, and requires --target-namespace.')
146 .option('-f, --file <file>', 'Compile the template in <file>')
147 .option('-j, --json <json>', 'Pass options to the Vash compiler. See docs for valid options.')
148 .option('-o, --out <path>', 'Write template into <path> directory')
149 .option('-u, --uglify', 'Uglify the template, safely')
150 .option('-a, --no-autolink', 'Do not wrap each template in `vash.link`.')
151 //.option('-d, --prepend-runtime', 'Include the required Vash runtime')
152 .option('-r, --render [json]', 'Render the template using <json> as the model. If <json> is not valid json, assume a filename and load those contents as json.')
153 .option('-s, --separator [separator]', 'Templates are auto-named by concatenating the file path with [separator]', '/')
154 .option('--helper', 'Assume the input is a to-be-compiled helper')
155 .option('--helpers <file>', 'Execute these compiled helpers')
156 .parse(process.argv)
157
158if( cli.json ){
159 cli.vopts = JSON.parse(cli.json);
160}
161
162// helpers via .toClientString, therefore vash.link
163if( cli.helpers ){
164 eval(fs.readFileSync(cli.helpers, 'utf8'));
165}
166
167if(cli.file){
168 cli.file = path.normalize( cli.file )
169 // assume file input
170 file( cli.file, cli )
171} else {
172 // assume stdin
173 stdin( cli );
174}
175