UNPKG

23.6 kBJavaScriptView Raw
1/*------------------------------------*\
2 WEB SERVER
3\*------------------------------------*/
4/* jslint node: true */
5
6/**
7 * Inform CLI when the server is up.
8 * @private
9 * @function cliServerUp
10 * @memberOf NA~
11 * @param {NA} NA NodeAtlas instance.
12 * @param {string} urlOutput URL default access for website.
13 * @param {string} message Details provide with URL.
14 */
15function cliServerUp(NA, urlOutput, message) {
16 var limit = Math.max(message.length + 2, urlOutput.length + 7),
17 separator = "",
18 i;
19
20 for (i = 0; i < limit; i++) {
21 separator += "=";
22 }
23
24 NA.log("");
25 NA.log("\u001B[32m", separator);
26 NA.log(" " + message);
27 NA.log("\u001B[32m", " URL: \u001B[31m" + urlOutput);
28 NA.log("\u001B[32m", separator);
29 NA.log("");
30}
31
32/**
33 * Calculate the url output for simple web server.
34 * @private
35 * @function simpleServerUrlOutput
36 * @memberOf NA~
37 * @param {NA} NA NodeAtlas instance.
38 * @param {number} httpPort Port used by application.
39 * @returns The url Output.
40 */
41function simpleServerUrlOutput(NA, httpPort) {
42 var url = NA.modules.url,
43 hostname = NA.configuration.httpHostname || process.env.IP_ADDRESS || "localhost",
44 http = (httpPort === 80 && !NA.configuration.httpSecure),
45 https = (httpPort === 443 && NA.configuration.httpSecure),
46 port = http || https ? "" : ":" + httpPort,
47 s = (NA.configuration.httpSecure ? "s" : ""),
48 path = (typeof NA.configuration.browse === "string") ? NA.configuration.browse : "";
49
50 return url.resolve("http" + s + '://' + hostname + port + "/", path);
51}
52
53/**
54 * Listen the port.
55 * @private
56 * @function serverListener
57 * @memberOf NA~
58 * @param {NA} NA NodeAtlas instance.
59 * @param {number} httpPort Port used by application.
60 * @param {number} urlOutput The url Output.
61 * @param {number} messageCode For find the correct JSON message.
62 * @param {NA~callback} next After server listenning.
63 */
64function serverListener(NA, httpPort, urlOutput, messageCode, next) {
65 var path = NA.modules.path;
66
67 /* Listen HTTP(s) request. */
68 NA.server.listen(httpPort, function () {
69 var data = {
70 httpPort: httpPort,
71 path: path.join(NA.serverPath, NA.webconfigName)
72 },
73 message = NA.cliLabels.running[messageCode].replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return data[matches]; });
74
75 /* Inform CLI the server is running. */
76 cliServerUp(NA, urlOutput, message);
77
78 /* Some action after server listening */
79 if (next) {
80 next();
81 }
82
83 /* After website was started. */
84 if (NA.afterRunning) {
85 NA.afterRunning.call(NA);
86 }
87 });
88}
89
90/**
91 * Catch error from server.
92 * @private
93 * @function errorServer
94 * @memberOf NA~
95 * @param {NA} NA NodeAtlas instance.
96 */
97function serverError(NA) {
98
99 /* Catch error. */
100 NA.server.on("error", function (error) {
101 if (error.syscall !== 'listen') {
102 throw error;
103 }
104
105 /* In case of error. */
106 switch (error.code) {
107 case 'EACCES':
108 NA.log(NA.cliLabels.running.portRequiresPrivileges.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return error[matches]; }));
109 /* Kill current process. */
110 process.exit(1);
111 break;
112 case 'EADDRINUSE':
113 NA.log(NA.cliLabels.running.portAlreadyListened.replace(/%([\-a-zA-Z0-9_]+)%/g, function (regex, matches) { return error[matches]; }));
114 /* Kill current process. */
115 process.exit(1);
116 break;
117 default:
118 throw error;
119 }
120 });
121}
122
123/**
124 * Set information to avoid cache.
125 * @private
126 * @function noCache
127 * @memberOf NA~
128 * @param {NA} NA NodeAtlas instance.
129 * @param {boolean} nocache No cache if set to true.
130 * @param {Object} staticOptions All options for publics file cache.
131 */
132function noCache(NA, nocache, staticOptions) {
133 /* No Cache */
134 if (nocache) {
135 NA.express.set("etag", false);
136 NA.express.get("/*", function(request, response, next) {
137 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
138 response.setHeader("Pragma", "no-cache");
139 response.setHeader("Expires", 0);
140 next();
141 });
142 if (staticOptions) {
143 staticOptions.maxAge = 0;
144 staticOptions.etag = false;
145 staticOptions.lastModified = false;
146 }
147 }
148 if (staticOptions) {
149 return staticOptions;
150 }
151}
152
153/**
154 * Run project folder with targeted directory (without webconfig) as a « public » directory.
155 * @private
156 * @function simpleWebServer
157 * @memberOf NA#
158 * @this NA
159 */
160exports.simpleWebServer = function () {
161 var NA = this,
162 fs = NA.modules.fs,
163 path = NA.modules.path,
164 http = NA.modules.http,
165 https = NA.modules.https,
166 express = NA.modules.express,
167 compress = NA.modules.compress,
168 staticOptions = { maxAge: 86400000 * 30 },
169 opn = NA.modules.opn,
170 httpPort = NA.configuration.httpPort || process.env.PORT || (NA.configuration.httpSecure ? 443 : 80),
171 urlOutput = simpleServerUrlOutput(NA, httpPort);
172
173 /* Configure the server. */
174 NA.express = express();
175
176 NA.express.set("strict routing", true);
177 NA.express.set("x-powered-by", false);
178 NA.express.set("port", httpPort);
179
180 staticOptions = noCache(NA, !NA.configuration.cache, staticOptions);
181
182 /* Use gzip and others client-server data compression. */
183 NA.express.use(compress());
184
185 /* Provide all files behind possible HTTP Response in the current directory. */
186 NA.express.use(express.static(NA.serverPath, staticOptions));
187
188 /* Create HTTPs server. */
189 if (NA.configuration.httpSecure && typeof NA.configuration.httpSecure === "string") {
190 NA.httpsServer = https.createServer({
191 key: fs.readFileSync(path.join(NA.serverPath, NA.configuration.httpSecure + ".key"), "utf-8"),
192 cert: fs.readFileSync(path.join(NA.serverPath, NA.configuration.httpSecure + ".crt"), "utf-8")
193 }, NA.express);
194 }
195
196 NA.httpServer = http.createServer(NA.express);
197 NA.server = NA.httpsServer || NA.httpServer;
198
199 /* Listenning HTTP request. */
200 serverListener(NA, httpPort, urlOutput, "publicMode", function () {
201
202 /* Open url provided at the default page in a tab of default system browser. */
203 if (NA.configuration.browse) {
204 opn(urlOutput);
205 }
206 });
207
208 /* Catche error from Server. */
209 serverError(NA);
210
211};
212
213/**
214 * Start a real NodeAtlas Server.
215 * @public
216 * @function nodeAtlasWebServer
217 * @memberOf NA#
218 * @this NA
219 * @param {NA~callback} next Passed to the next function.
220 * @param {NA~fallback} fallback Called if you want generate mode.
221 */
222exports.nodeAtlasWebServer = function (next, fallback) {
223 var NA = this,
224 express = NA.modules.express,
225 fs = NA.modules.fs,
226 path = NA.modules.path,
227 http = NA.modules.http,
228 https = NA.modules.https;
229
230 /**
231 * Instance of Express.js module.
232 * @public
233 * @function express
234 * @memberOf NA#
235 */
236 NA.express = express();
237
238 /* Configure the server. */
239 NA.express.set("strict routing", true);
240 NA.express.set("x-powered-by", false);
241
242 /* Change Engine */
243 if (NA.webconfig.engine) {
244 NA.express.set("view engine", NA.webconfig.engine);
245 NA.express.set("views", path.join(NA.serverPath, NA.webconfig.viewsRelativePath));
246 }
247
248 noCache(NA, !NA.webconfig.cache);
249
250 if (typeof NA.webconfig.httpSecure !== "boolean" && NA.webconfig.httpSecureKeyRelativePath && NA.webconfig.httpSecureCertificateRelativePath) {
251
252 /**
253 * The HTTPs server if exist.
254 * @public
255 * @function httpsServer
256 * @memberOf NA#
257 * @default undefined
258 */
259 NA.httpsServer = https.createServer({
260 key: fs.readFileSync(path.join(NA.serverPath, NA.webconfig.httpSecureKeyRelativePath), 'utf-8'),
261 cert: fs.readFileSync(path.join(NA.serverPath, NA.webconfig.httpSecureCertificateRelativePath), 'utf-8')
262 }, NA.express);
263 }
264
265 /**
266 * The HTTP server.
267 * @public
268 * @function httpServer
269 * @memberOf NA#
270 */
271 NA.httpServer = http.createServer(NA.express);
272
273 /**
274 * The Server used to listen.
275 * @public
276 * @function server
277 * @memberOf NA#
278 */
279 NA.server = NA.httpsServer || NA.httpServer;
280
281 /* Allow you to parse request and response. */
282 NA.initMiddlewares();
283
284 /* Allow you to parse the Less files. */
285 NA.initLessProcess();
286
287 /* Allow you to parse the Styl files. */
288 NA.initStylusProcess();
289
290 /* Allow you to use Session variables. */
291 NA.initSessions(next, fallback);
292};
293
294/**
295 * Add middleware for parse request and response.
296 * @private
297 * @function initMiddlewares
298 * @memberOf NA#
299 * @this NA
300 */
301exports.initMiddlewares = function () {
302 var NA = this,
303 path = NA.modules.path,
304 compress = NA.modules.compress,
305 bodyParser = NA.modules.bodyParser,
306 cookieParser = NA.modules.cookieParser,
307 middlewares,
308 i,
309 l;
310
311 /* Use gzip and others client-server data compression. */
312 NA.express.use(compress());
313
314 /* Allow you to parse the x-www-form-urlencoded format. */
315 NA.express.use(bodyParser.urlencoded({ extended: true }));
316
317 /* Allow you to parse the JSON format. */
318 NA.express.use(bodyParser.json());
319
320 /* Allow you to parse the Cookie data format. */
321 NA.express.use(cookieParser());
322
323 function hasMiddlewaresFile(callback) {
324 if (
325
326 /**
327 * Allow you to set Express middleware for all routes.
328 * @public
329 * @alias middlewares
330 * @type {string}
331 * @memberOf NA#webconfig
332 */
333 NA.webconfig.middlewares) {
334 middlewares = [];
335 if (NA.webconfig.middlewares instanceof Array) {
336 NA.webconfig.middlewares.forEach(function (middleware) {
337 callback(require(path.join(NA.serverPath, NA.webconfig.middlewaresRelativePath, middleware)).bind(NA));
338 });
339 } else {
340 callback(require(path.join(NA.serverPath, NA.webconfig.middlewaresRelativePath, NA.webconfig.middlewares)).bind(NA));
341 }
342 }
343 }
344
345 hasMiddlewaresFile(function (file) {
346 var content;
347 try {
348 content = file();
349 } catch (e) {
350 content = "";
351 }
352
353 if (content instanceof Array) {
354 middlewares = middlewares.concat(content);
355 } else {
356 middlewares.push(file);
357 }
358 });
359
360 if (middlewares) {
361 for (i = 0, l = middlewares.length; i < l; i++) {
362 NA.express.use(middlewares[i]);
363 }
364 }
365};
366
367/**
368 * Source Map for Less files.
369 * @private
370 * @function lessStoreSourcemap
371 * @memberOf NA~
372 * @param {NA} NA NodeAtlas instance.
373 * @param {RegExp} regex Used for change pathname.
374 */
375function lessStoreSourcemap(NA, regex) {
376 var fs = NA.modules.fs,
377 path = NA.modules.path,
378 mkpath = NA.modules.mkpath,
379 lessMiddlewareUtilities = NA.modules.lessMiddlewareUtilities;
380
381 return function (pathname, sourcemap) {
382 if (NA.webconfig.urlRelativeSubPath) {
383 pathname = pathname.replace(regex, path.join(NA.serverPath, NA.webconfig.assetsRelativePath) + path.sep);
384 }
385 fs.exists(path.join(pathname.replace(/\.css\.map/g,".less")), function (exists) {
386 if (exists) {
387 mkpath(path.dirname(pathname), function (error) {
388 if (error) {
389 lessMiddlewareUtilities.lessError(error);
390 return;
391 }
392 fs.writeFile(pathname, sourcemap, 'utf8', function () {});
393 });
394 }
395 });
396 };
397}
398
399/**
400 * CSS generate from Less files.
401 * @private
402 * @function lessStoreCss
403 * @memberOf NA~
404 * @param {NA} NA NodeAtlas instance.
405 * @param {RegExp} regex Used for change pathname.
406 */
407function lessStoreCss(NA, regex) {
408 var fs = NA.modules.fs,
409 path = NA.modules.path,
410 mkpath = NA.modules.mkpath;
411
412 return function (pathname, css, req, next) {
413 if (NA.webconfig.urlRelativeSubPath) {
414 pathname = pathname.replace(regex, path.join(NA.serverPath, NA.webconfig.assetsRelativePath) + path.sep);
415 }
416
417 mkpath(path.dirname(pathname), function (error) {
418 if (error) {
419 return next(error);
420 }
421
422 fs.writeFile(pathname, css, 'utf8', next);
423 });
424 };
425}
426
427/**
428 * Active Mechanism for generate Less files.
429 * @private
430 * @function initLessProcess
431 * @memberOf NA#
432 * @this NA
433 */
434exports.initLessProcess = function () {
435 var NA = this,
436 lessMiddleware = NA.modules.lessMiddleware,
437 path = NA.modules.path,
438 prefixLess = new NA.modules.prefixLess(),
439 compressValue = false,
440 sourceMapValue = true,
441 regex = new RegExp(path.join(NA.serverPath, NA.webconfig.assetsRelativePath, NA.webconfig.urlRelativeSubPath).replace(/(\\|\/)/g, '\\' + path.sep), 'g'),
442 renderOptions = {
443 compress: (NA.webconfig.less && NA.webconfig.less.compress) || compressValue,
444 sourceMap: (NA.webconfig.less && NA.webconfig.less.sourceMap) || sourceMapValue
445 };
446
447 if (NA.webconfig.less && NA.webconfig.less.autoprefix) {
448 renderOptions.plugins = [prefixLess];
449 }
450
451 if (NA.webconfig.less && !NA.webconfig.cssBundlingBeforeResponse) {
452
453 /* Generate Less on the fly during the development phase. */
454 NA.express.use(lessMiddleware(path.join(NA.webconfig.assetsRelativePath), {
455 dest: path.join(NA.webconfig.assetsRelativePath),
456 pathRoot: path.join(NA.serverPath),
457 preprocess: {
458 path: function (pathname) {
459 if (NA.webconfig.urlRelativeSubPath) {
460 pathname = pathname.replace(regex, path.join(NA.serverPath, NA.webconfig.assetsRelativePath) + path.sep);
461 }
462 return pathname;
463 }
464 },
465 postprocess: {
466 css: function (css, req) {
467 return css + "/*# sourceMappingURL=" + req.url.replace(/\.css$/i, '.css.map') + " */";
468 }
469 },
470 storeSourcemap: lessStoreSourcemap(NA, regex),
471 storeCss: lessStoreCss(NA, regex),
472 render: renderOptions
473 }));
474 }
475};
476
477/**
478 * Active Mechanism for generate Stylus files.
479 * @private
480 * @function initStylusProcess
481 * @memberOf NA#
482 * @this NA
483 */
484exports.initStylusProcess = function () {
485 var NA = this,
486 path = NA.modules.path,
487 stylusMiddleware,
488 compressValue = false,
489 sourceMapValue = {
490 "inline": true
491 },
492 forceValue = false,
493 firebugValue = false,
494 linenosValue = false;
495
496 if (NA.webconfig.stylus && !NA.webconfig.cssBundlingBeforeResponse) {
497 stylusMiddleware = NA.modules.stylus.middleware({
498 src: path.join(NA.serverPath, NA.webconfig.assetsRelativePath),
499 compile: function (str, src) {
500 var stylusFn = NA.modules.stylus(str);
501
502 if (NA.webconfig.stylus.autoprefix) {
503 stylusFn = stylusFn.use(NA.modules.prefixStylus());
504 }
505
506 stylusFn = stylusFn
507 .set('filename', src)
508 .set('src', path.join(NA.serverPath, NA.webconfig.assetsRelativePath))
509 .set('dest', path.join(NA.serverPath, NA.webconfig.assetsRelativePath))
510 .set('firebug', NA.webconfig.stylus.firebug || firebugValue)
511 .set('force', NA.webconfig.stylus.force || forceValue)
512 .set('linenos', NA.webconfig.stylus.linenos || linenosValue)
513 .set('sourcemap', NA.webconfig.stylus.sourceMap || sourceMapValue)
514 .set('compress', NA.webconfig.stylus.compress || compressValue);
515
516 return stylusFn;
517 }
518 });
519
520 /* Generate Stylus on the fly during the development phase. */
521 NA.express.use(function (req, res, next) {
522 var regex = new RegExp("^" + NA.webconfig.urlRelativeSubPath, 'g'),
523 request = {
524 url: req.url.replace(regex, ""),
525 method: req.method
526 };
527
528 stylusMiddleware(request, res, next);
529 });
530 }
531};
532
533/**
534 * Set the Sessions variables possibility.
535 * @private
536 * @function initSessions
537 * @memberOf NA#
538 * @this NA
539 * @param {NA~callback} next Passed to the next function.
540 * @param {NA~fallback} fallback Called if you want generate mode.
541 */
542exports.initSessions = function (next, fallback) {
543 var NA = this,
544 optionSession = {},
545 session = NA.modules.session;
546
547 /**
548 * Name for Session cookie of connected user.
549 * @public
550 * @alias sessionKey
551 * @type {string}
552 * @memberOf NA#webconfig
553 * @default "nodeatlas.sid"
554 */
555 optionSession.key = NA.webconfig.sessionKey || "nodeatlas.sid";
556
557 /**
558 * Secret for Session cookie of connected user.
559 * @public
560 * @alias sessionSecret
561 * @type {string}
562 * @memberOf NA#webconfig
563 * @default '1234567890bépo'.
564 */
565 optionSession.secret = NA.webconfig.sessionSecret || "1234567890bépo";
566 optionSession.saveUninitialized = true;
567 optionSession.resave = true;
568
569 if (NA.webconfig.session) {
570
571 /**
572 * Use a more complexe session cookie options.
573 * Replace `NA#webconfig.sessionKey` and `NA#webconfig.sessionSecret` if set.
574 * @public
575 * @alias session
576 * @type {Object}
577 * @memberOf NA#webconfig
578 * @see {@link https://github.com/expressjs/session Session Middleware}
579 */
580 optionSession = NA.webconfig.session;
581 }
582
583 /**
584 * A default session loaded with `NA#webconfig.sessionKey` and `NA#webconfig.sessionSecret` or `NA.webconfig#sessionKey` and `NA#webconfig.session`.
585 * @public
586 * @alias sessionStore
587 * @type {Object}
588 * @memberOf NA#
589 * @see {@link https://github.com/expressjs/session Session Middleware}
590 */
591 NA.sessionStore = new session.MemoryStore();
592
593 /* Use the `NA.controllers[<controller>].setSessions(...)` function if set... */
594 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
595 typeof NA.controllers[NA.webconfig.controller].setSessions !== 'undefined') {
596
597 /**
598 * Define this function for configure sessions of application. Only for `common` controller file.
599 * @function setSessions
600 * @memberOf NA#controllers[]
601 * @param {NA~callback} next Next steps after session is setted.
602 */
603 NA.controllers[NA.webconfig.controller].setSessions.call(NA, function () {
604 NA.initSockets(session, optionSession, next, fallback);
605 });
606 /* ...else, just continue. */
607 } else {
608 NA.initSockets(session, optionSession, next, fallback);
609 }
610};
611
612/**
613 * Deliver NA.io to the client-side.
614 * @private
615 * @function addFrontSockets
616 * @memberOf NA~
617 * @param {NA} NA NodeAtlas instance.
618 */
619function addFrontSockets(NA) {
620 var fs = NA.modules.fs,
621 url = NA.modules.url,
622 path = NA.modules.path;
623
624 // Deliver the `NA.io` object to client-side.
625 if (NA.webconfig.socketClientFile) {
626 NA.express.get(url.format(path.join("/", NA.webconfig.urlRelativeSubPath, NA.webconfig.socketClientFile)), function (request, response) {
627 response.setHeader("Content-type", "text/javascript; charset=utf-8");
628 fs.readFile(path.join(NA.nodeatlasPath, "src", "socket.io.js"), "utf-8", function (err, content) {
629 if (err) {
630 throw err;
631 }
632
633 response.write(content
634 .replace(/%urlRelativeSubPath%/g, NA.webconfig.urlRelativeSubPath.slice(1))
635 .replace(/%urlRoot%/g, NA.webconfig.urlRoot));
636 response.end();
637 });
638 });
639 }
640}
641
642/**
643 * Set the Hooks for Controllors.
644 * @private
645 * @function addBackSockets
646 * @memberOf NA~
647 * @param {NA} NA NodeAtlas instance.
648 */
649function addBackSockets(NA) {
650 var path = NA.modules.path,
651 controllers = {},
652 controller;
653
654 /* Use the `NA.controllers[<controller>].setSockets(...)` function if set... */
655 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
656 typeof NA.controllers[NA.webconfig.controller].setSockets !== 'undefined') {
657
658 /**
659 * Define this function for set WebSockets from both `common` and `specific` controller.
660 * @function setSockets
661 * @memberOf NA#controllers[]
662 */
663 NA.controllers[NA.webconfig.controller].setSockets.call(NA);
664 }
665
666 // Global sockets
667 NA.forEach(NA.webconfig.routes, function (route) {
668 if (typeof route === "string") {
669 route = NA.webconfig.routes[route];
670 }
671 if (route.controller) {
672 controllers[route.controller] = true;
673 }
674 });
675
676 // Controler setSockets runned just one time.
677 for (var item in controllers) {
678 if (controllers.hasOwnProperty(item)) {
679 /* Use the `NA.controllers[<controller>].setSockets(...)` function if set... */
680 controller = require(path.join(NA.serverPath, NA.webconfig.controllersRelativePath, item));
681 if (controller.setSockets) {
682 controller.setSockets.call(NA);
683 }
684 }
685 }
686}
687
688/**
689 * Allow you to set your websocket back-end behavior.
690 * @private
691 * @function initSockets
692 * @memberOf NA#
693 * @this NA
694 * @param {Object} session Session Object.
695 * @param {Object} optionSession Property for Object Session.
696 * @param {NA~callback} next Passed to the next function.
697 * @param {NA~fallback} fallback Called if you want generate mode.
698 */
699exports.initSockets = function (session, optionSession, next, fallback) {
700 var NA = this,
701 server = NA.httpsServer || NA.httpServer,
702 socketio = NA.modules.socketio,
703 secure = NA.webconfig.httpSecure ? true : false,
704 optionIo = (NA.webconfig.urlRelativeSubPath) ? {
705 path: NA.webconfig.urlRelativeSubPath + "/socket.io",
706 secure: secure
707 } : {
708 secure: secure
709 },
710 fullOptionIo = {};
711
712 Object.assign(fullOptionIo, optionIo,
713
714 /**
715 * Allow you to extend Socket.IO options object.
716 * @public
717 * @alias socketServerOptions
718 * @type {Object}
719 * @memberOf NA#webconfig
720 */
721 NA.webconfig.socketServerOptions);
722
723 /**
724 * Instance of Socket.io module.
725 * @public
726 * @function express
727 * @memberOf NA#
728 */
729 NA.io = socketio(server, fullOptionIo);
730
731 optionSession.store = NA.sessionStore;
732 NA.webconfig.session = optionSession;
733
734 /* Create a cookie Session. */
735 NA.express.use(session(optionSession));
736
737 /* Sync cookie Session with socket.io. */
738 NA.io.use(function (socket, next) {
739 session(optionSession)(socket.request, socket.request.res, next);
740 });
741
742 /* Deliver io to the client-side. */
743 addFrontSockets(NA);
744
745 /* Set Hooks for controllers. */
746 addBackSockets(NA);
747
748 /* Allow you to set configurations. */
749 NA.initConfigurations(next, fallback);
750};
751
752/**
753 * Allow you to configure your own modules configuration.
754 * @private
755 * @function initConfigurations
756 * @memberOf NA#
757 * @this NA
758 * @param {NA~callback} next Passed to the next function.
759 * @param {NA~fallback} fallback Called if you want generate mode.
760 */
761exports.initConfigurations = function (next, fallback) {
762 var NA = this;
763
764 /* Use the `NA.controllers[<controller>].setConfigurations(...)` function if set... */
765 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
766 typeof NA.controllers[NA.webconfig.controller].setConfigurations !== 'undefined') {
767
768 /**
769 * Define this function for configure all modules of your application. Only for `common` controller file.
770 * @function setConfigurations
771 * @memberOf NA#controllers[]
772 * @param {NA~callback} next Next steps after configuration is done.
773 */
774 NA.controllers[NA.webconfig.controller].setConfigurations.call(NA, function () {
775 NA.initServer(next, fallback);
776 });
777 /* ...else, just continue. */
778 } else {
779 NA.initServer(next, fallback);
780 }
781};
782
783/**
784 * Run the Server of NodeAtlas.
785 * @private
786 * @function initServer
787 * @memberOf NA#
788 * @this NA
789 * @param {NA~callback} next Called after running of server.
790 * @param {NA~fallback} fallback Called if you want generate mode.
791 */
792exports.initServer = function (next, fallback) {
793 var NA = this,
794 opn = NA.modules.opn,
795 path = NA.modules.path,
796 url = NA.modules.url,
797 urlOutput = url.resolve(NA.webconfig.urlRoot, path.join(NA.webconfig.urlRelativeSubPath, ((typeof NA.configuration.browse === 'string') ? NA.configuration.browse : "")));
798
799 NA.express.set("port", NA.webconfig.httpPort);
800
801 if (!NA.configuration.generate) {
802 serverListener(NA, NA.webconfig.httpPort, urlOutput, "isRunning", function () {
803
804 /* If index index exist, we go to url later. */
805 if (NA.configuration.browse && !NA.webconfig.index) {
806 opn(urlOutput);
807 }
808
809 next();
810 });
811 } else {
812 fallback();
813 }
814
815 /* Catche error from Server. */
816 serverError(NA);
817};
\No newline at end of file