UNPKG

10.1 kBJavaScriptView Raw
1/*------------------------------------*\
2 ASSETS GENERATION
3\*------------------------------------*/
4/* jslint node: true */
5
6/**
7 * Copy content of a project from NodeAtlas `templates/` folder into current directory.
8 * @private
9 * @function createTemplateProject
10 * @memberOf NA#
11 * @this NA
12 * @param {NA~fallback} next Fallback function.
13 */
14exports.createTemplateProject = function (next) {
15 var NA = this,
16 fs = NA.modules.fs,
17 path = NA.modules.path,
18 copyDir = NA.modules.copyDir,
19 source = (typeof NA.configuration.create === "string") ? NA.configuration.create : "hello-world",
20 sourcePath = path.join(NA.nodeatlasPath, "templates", source),
21 destinationPath = path.join(NA.serverPath),
22 data = {};
23
24 if (NA.configuration.create) {
25
26 /* Copy starting project from `templates/` directory. By default it is "hello-world". */
27 if (sourcePath !== destinationPath && fs.existsSync(sourcePath)) {
28
29 copyDir(sourcePath, destinationPath, function () {
30 data.pathName = sourcePath;
31 NA.log(NA.cliLabels.initCopy.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return data[matches]; }));
32 if (NA.afterNewProject) {
33 NA.afterNewProject.call(NA);
34 } else {
35 process.exit(0);
36 }
37 });
38 } else {
39 data.initPath = source;
40 NA.log(NA.cliLabels.initNotFound.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return data[matches]; }));
41 process.exit(0);
42 }
43 } else {
44
45 /**
46 * Continue with this alternative way if main operation not possible.
47 * @callback NA~fallback
48 */
49 next();
50 }
51};
52
53/**
54 * Open all pages for generate HTML render into `serverlessRelativePath`.
55 * @private
56 * @function generateHTML
57 * @memberOf NA~
58 * @param {NA} NA NodeAtlas instance.
59 */
60function generateHTML(NA) {
61 var output = false;
62
63 /* Avoid copy of `assetsRelativePath` into `serverlessRelativePath` even if serverlessRelativePath directory exist. */
64 if (typeof NA.webconfig.output === "boolean") {
65
66 /**
67 * Disable HTML generation mechanism.
68 * @public
69 * @alias output
70 * @type {boolean}
71 * @memberOf NA#webconfig
72 * @default true
73 */
74 output = NA.webconfig.output;
75 }
76
77 /* Generation only if is configured to « true » in `generate` or set co command line. */
78 if (NA.configuration.generate) {
79
80 /* Generate all HTML files. */
81 if (output) {
82 NA.forEach(NA.webconfig.routes, function (currentUrl) {
83 NA.prepareResponse(currentUrl, NA.webconfig.routes, undefined, undefined, function (locals, request, response) {
84 NA.changeVariationsCommon(locals, request, response);
85 });
86 });
87 }
88
89 NA.generateAssets();
90 }
91}
92
93/**
94 * Crawl all routes and generate them after passed into `NA#controllers[].setRoutes` hook.
95 * @private
96 * @function initOutputs
97 * @memberOf NA#
98 * @this NA
99 */
100exports.initOutputs = function () {
101 var NA = this;
102
103 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
104 typeof NA.controllers[NA.webconfig.controller].setRoutes !== 'undefined') {
105 NA.controllers[NA.webconfig.controller].setRoutes.call(NA, function () {
106 generateHTML(NA);
107 });
108 } else {
109 generateHTML(NA);
110 }
111};
112
113/**
114 * Compress all assets for generate `assetsRelativePath` content into `serverlessRelativePath` and copy all `NA#statics` directories..
115 * @private
116 * @function generateAssets
117 * @memberOf NA#
118 * @this NA
119 */
120exports.generateAssets = function () {
121 var NA = this,
122 async = NA.modules.async;
123
124 /* Generate all minified CSS, JS and Images files. */
125 async.parallel([
126 NA.cssCompilation.bind(NA),
127 NA.jsObfuscation.bind(NA)
128 ], function () {
129
130 /* Copy all content of `assetsRelativePath` and `statics` into `serverlessRelativePath` */
131 async.parallel([
132 NA.publicsGeneration.bind(NA),
133 NA.staticsGeneration.bind(NA),
134 ], function () {
135
136 if (NA.afterGeneration) {
137 NA.afterGeneration.call(NA);
138 } else {
139 process.exit(0);
140 }
141 });
142 });
143};
144
145/**
146 * Copy all `public` file from `assetsRelativePath` to `serverlessRelativePath`.
147 * @private
148 * @function publicsGeneration
149 * @memberOf NA#
150 * @this NA
151 * @param {NA~callback} next Next step after copy of all `assetsRelativePath` content.
152 */
153exports.publicsGeneration = function (next) {
154 var NA = this,
155 path = NA.modules.path,
156 fs = NA.modules.fs,
157 copyDir = NA.modules.copyDir,
158 sourcePath = path.join(NA.serverPath, NA.webconfig.assetsRelativePath),
159 destinationPath = path.join(NA.serverPath, NA.webconfig.serverlessRelativePath),
160 assetsCopy = false;
161
162 /* Avoid copy of `assetsRelativePath` into `serverlessRelativePath` even if serverlessRelativePath directory exist. */
163 if (typeof NA.webconfig.assetsCopy === "boolean") {
164
165 /**
166 * Disable Assets generation mechanism.
167 * @public
168 * @alias assetsCopy
169 * @type {boolean}
170 * @memberOf NA#webconfig
171 * @default true
172 */
173 assetsCopy = NA.webconfig.assetsCopy;
174 }
175
176 if (assetsCopy && sourcePath !== destinationPath && fs.existsSync(sourcePath)) {
177 copyDir(sourcePath, destinationPath, function () {
178 NA.log(NA.cliLabels.assetsCopy);
179 next();
180 });
181 } else {
182 next();
183 }
184};
185
186/**
187 * Copy mechanism for statics.
188 * @private
189 * @function traverse
190 * @memberOf NA~
191 * @this NA
192 * @param {Object} paths Contain a `statics` content.
193 * @param {string} paths.real The path of source directory.
194 * @param {string} paths.virtual The path of virtual url.
195 * @param {boolean} paths.output Inform if copy is required
196 * @param {NA~callback} next Go to next steps.
197 */
198function traverse(paths, next) {
199 var NA = this,
200 copyDir = NA.modules.copyDir,
201 path = NA.modules.path,
202 sourcePath = path.join(NA.serverPath, paths.real),
203 destinationPath = path.join(NA.serverPath, NA.webconfig.serverlessRelativePath, paths.virtual),
204 data = {
205 source: sourcePath,
206 dest: destinationPath
207 };
208
209 if (paths.output) {
210 copyDir(sourcePath, destinationPath, function () {
211 NA.log(NA.cliLabels.staticsCopy.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return data[matches]; }));
212 next();
213 });
214 } else {
215 next();
216 }
217}
218
219/**
220 * Copy all `statics` form real directory to `serverlessRelativePath`.
221 * @private
222 * @function staticsGeneration
223 * @memberOf NA#
224 * @this NA
225 * @param {NA~callback} next Next step after copy of all `assetsRelativePath` content.
226 */
227exports.staticsGeneration = function (next) {
228 var NA = this,
229 async = NA.modules.async,
230 statics = [];
231
232 if (NA.webconfig.statics) {
233
234 NA.forEach(NA.webconfig.statics, function (directory, directories) {
235 var virtual = directory,
236 real = directories[directory],
237 output = false;
238
239 if (NA.webconfig.statics instanceof Array) {
240 virtual = directory.virtual;
241 output = directory.output;
242 real = directory;
243 }
244
245 if (typeof real === "object") {
246 output = (typeof real.output === "boolean" && !real.output) ? false : true;
247 real = real.path;
248 }
249
250 statics.push({
251 real: real,
252 virtual: virtual,
253 output: output
254 });
255 });
256
257 async.map(statics, traverse.bind(NA), function() {
258 next();
259 });
260 } else {
261 next();
262 }
263};
264
265/**
266 * Save the render.
267 * @private
268 * @function save
269 * @memberOf NA~
270 * @param {NA} NA NodeAtlas instance.
271 * @param {string} html HTML result to save.
272 * @param {string} data Result if html is not a HTML content.
273 * @param {string} templateName Name for register file.
274 */
275function save(NA, html, data, templateName) {
276 var mkpath = NA.modules.mkpath,
277 path = NA.modules.path,
278 pathToSaveFileComplete = path.join(NA.serverPath, NA.webconfig.serverlessRelativePath, templateName),
279 pathToSaveFile = path.dirname(pathToSaveFileComplete),
280 fs = NA.modules.fs;
281
282 if (templateName) {
283
284 /* Create file render. */
285 mkpath(pathToSaveFile, function () {
286 var dataError = {};
287
288 /* If source is not a HTML format, keep initial data format. */
289 if (data.trim().match(/<\/html>$/g) === null) {
290 html = data;
291 }
292
293 dataError.pathName = path.join(NA.serverPath, NA.webconfig.serverlessRelativePath, templateName);
294
295 /* Write file */
296 fs.writeFile(pathToSaveFileComplete, html, function (error) {
297 if (error) {
298 if (error.code === 'EISDIR' || error.code === 'ENOENT') {
299 NA.log(NA.cliLabels.templateNotGenerate.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return dataError[matches]; }));
300 } else {
301 throw error;
302 }
303 } else {
304 NA.log(NA.cliLabels.templateGenerate.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return dataError[matches]; }));
305 }
306 });
307
308 });
309 }
310}
311
312/**
313 * Generate a template into an HTML file in folder `serverlessRelativePath`.
314 * @private
315 * @function saveRender
316 * @memberOf NA#
317 * @this NA
318 * @param {string} data Content of file generated.
319 * @param {string} templateName The filename of file generated.
320 */
321exports.saveRender = function (data, templateName) {
322 var NA = this,
323 jsdom = NA.modules.jsdom,
324 dom = new jsdom.JSDOM(data),
325 deeper,
326 newBase = "";
327
328 /*
329 * If false, no generate for this line.
330 */
331 if (templateName !== false) {
332
333 /*
334 * If templateName ending with "/", remove it.
335 */
336 templateName = templateName.replace(/\/$/g, "");
337
338 /*
339 * If a <base> markup exist, calculation of
340 * relative placement of page under root folder...
341 */
342 deeper = templateName.split("/").length - 1;
343 if (templateName[0] === "/") {
344 deeper = templateName.split("/").length - 2;
345 }
346
347 /* ...and creation of path for all resources */
348 for (var i = 0; i < deeper; i++) {
349 newBase += "../";
350 }
351
352 /* ...and set new base */
353 Array.prototype.forEach.call(dom.window.document.getElementsByTagName("base"), function (base) {
354 base.setAttribute("href", newBase.replace(/\/$/, ""));
355 });
356
357 /* Save the render. */
358 save(NA, dom.serialize(), data, (templateName) ? templateName : "");
359 }
360};
\No newline at end of file