-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
134 lines (118 loc) · 5.27 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
'use strict';
const assert = require('assert');
let DEFAULT_PORT = 4321,
path = require('path'),
join = path.join,
http = require('http'),
https = require('https'),
createRoutes = require('express-json-middleware'),
BB = require('bluebird'),
fs = BB.promisifyAll(require('fs')),
_ = require('lodash'),
chalk = require('chalk'),
bodyParser = require('body-parser');
module.exports = {
start : start
};
/**
*
* @param options
*
* options.app The express app - created if not passed in
* options.engine - the express view engine used - defaults to pug
* options.express express itself - created if not passed in
* options.protocol - if this is 'https', express will handle https - suggested use for dev only
* options.https.key - used with options.protocol of https
* options.https.crt - used with options.protocol of https
* options.staticOptions - options to pass to the express.static call
* options.structure - object that describes the directory layout for the app - all paths are relative to structure.base
* options.structure.base The directory other directory options are relative to - required
* options.structure.middlewares Path to the "middlewares" directory use from routes.json
* options.structure.routes The location of the routes.json file
* options.structure.static An object of directories to be used for express.static - keys are paths
* options.structure.startup An array of modules to be rerquired in in series - optionally return promises from them - defaults to []
* options.structure.views The express "views" directory
* options.verbose If you want verbose outpout
*
*/
function start(options) {
assert(!!options.structure, 'Please pass in options.structure');
assert(!!options.structure.base, 'Please pass in options.structure.base');
const verbose = options.verbose || false;
if (verbose) {
// TODO: should have separate option for this
BB.longStackTraces();
}
// Not using object.assign, since I don't want to actually call express() if not needed, and options is nested
options.express = options.express || require('express');
options.app = options.app || express();
options.engine = options.engine || 'pug';
options.staticOptions = options.staticOptions || { maxage : '365d' };
options.structure.middlewares = options.structure.middlewares || 'middlewares';
options.structure.routes = options.structure.routes || 'routes.json';
options.structure.static = options.structure.static || [];
options.structure.startup = options.structure.startup || [];
options.structure.views = options.structure.views || 'views';
let app = options.app;
let structure = options.structure;
return BB
.try(() => {
verbose && console.log(chalk.green('> add standard bodyParse'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended : false}));
})
.then(() => {
app.set('views', join(structure.base, structure.views));
app.set('view engine', options.engine);
verbose && console.log(chalk.green(`> setup ${options.engine} template engine`));
})
.then(() => {
console.log(chalk.green('> Parsing startups'));
return BB.map(options.structure.startup, (startup) => {
console.log(chalk.green(`> starting ${startup}`));
return require(join(structure.base, startup))();
});
})
.then(() => {
console.log(chalk.green('> Adding static directories'));
Object.keys(structure.static).forEach(key => {
let staticDir = structure.static[key];
console.log(chalk.green(`> Adding ${staticDir}`));
// TODO: different static options per dir
app.use(options.express.static(join(structure.base, staticDir), options.staticOptions));
});
})
.then(() => {
let routesFilePath = join(structure.base, structure.routes);
verbose && console.log(chalk.green('> routes file:'), routesFilePath);
let routes = require(routesFilePath);
createRoutes({
app : app,
express : options.express,
routes : routes,
middlewares : join(structure.base, structure.middlewares)
});
})
.then(function () {
var port = options.port || DEFAULT_PORT,
server = null;
// Should only be used for dev
if(options.protocol === 'https') {
server = https.createServer({
key: fs.readFileSync(path.join(structure.base, options.https.key)),
cert: fs.readFileSync(path.join(structure.base, options.https.cert))
}, app);
} else {
server = http.createServer(app);
}
server.listen(port, function(){
console.log(chalk.green('> express app listening on port:'), port);
});
return server;
})
.then(function (server) {
return {
server : server
};
});
}