ng-server
Version:
A NodeJs server for Angular 2 applications
199 lines (140 loc) • 5.86 kB
JavaScript
/*eslint-env node */
var Cache = require('./cache');
var Helper = require('./helper');
var MimeType = require('./mime-types');
module.exports = function (context) {
// ========================= MIDDLEWARES =========================
this.cacheResponse = function (req, res, next) {
var cached = context.$cache.get(req.url);
if (!cached) {
next();
return;
}
context.$logger.success('File (cached): ' + req.url + ' sent.');
for (var reader in cached.headers)
res.setHeader(reader, cached.headers[reader]);
res.status(200);
res.send(cached.data);
};
// add the path config to request object
this.putPathData = function (req, res, next) {
context.$logger.info ('Request: ' + req.url);
// looking for the path context
for (var path in context) {
if (req.url.startsWith(path)) {
req.$path = path;
req.$pathContext = context[path];
break;
}
}
// If path not exists
if (!req.$pathContext) {
Helper.sendErr404(res);
return;
}
next();
};
// verify the cors
this.corsFilter = function (req, res, next) {
var cors = context[req.$path].cors;
if (cors.indexOf('*') > -1) {
next();
return;
}
if (cors.indexOf(req.host) === -1) Helper.sendErr403(res);
next();
};
// serve static files
this.serveStatics = function (req, res, next) {
var resources = req.$pathContext.resources;
var goNext = true;
var srcUrl = '';
for (var src in resources) {
src = resources[src];
srcUrl = req.$path === '/'? src.url: req.$path + src.url;
if (req.url.startsWith(srcUrl)) {
srcUrl = src.path + req.url.substring(srcUrl.length);
Helper.readFile(res, srcUrl, function (data) {
context.$logger.success('File: ' + srcUrl + ' sent.');
var readers = {
'Content-Type': MimeType.get(srcUrl),
'Access-Control-Allow-Origin': context[req.$path].cors,
};
var item =context.$cache.add (req.url, srcUrl, readers, data);
for (var reader in item.headers)
res.setHeader(reader, item.headers[reader]);
res.status(200);
res.send(item.data);
});
goNext = false;
}
}
if (goNext) next();
};
// SEND NOT STATIC FILES
this.sendFiles = function (req, res, next) {
var srcUrl = context[req.$path].path + (req.url === '/'? '/' + context[req.$path].entry_point: req.url);
Helper.readFileOrMoveNext(res, next, srcUrl, function (data) {
Helper.compressFile(data, function (err, ziped) {
if (err) {
Helper.sendErr500(res, "Can't gzip response data");
return;
}
context.$logger.success('File (gziped): ' + srcUrl + ' sent.');
var readers = {
'Content-Type': MimeType.get(srcUrl),
'Access-Control-Allow-Origin': context[req.$path].cors,
'Content-Encoding': 'gzip'
};
var item =context.$cache.add (req.url, srcUrl, readers, ziped);
for (var reader in item.headers)
res.setHeader(reader, item.headers[reader]);
res.status(200);
res.send(item.data);
});
});
};
// USE ENTRY POINT AS RESPONSE
this.angularRouteResponse = function (req, res, next) {
var srcUrl = context[req.$path].path + '/' + context[req.$path].entry_point;
Helper.readFile(res, srcUrl, function (data) {
Helper.compressFile(data, function (err, ziped) {
if (err) {
Helper.sendErr500(res, "Can't gzip response data");
return;
}
context.$logger.success('File (gziped): ' + srcUrl + ' sent.');
var readers = {
'Content-Type': MimeType.get(srcUrl),
'Access-Control-Allow-Origin': context[req.$path].cors,
'Content-Encoding': 'gzip'
};
var item = context.$cache.add (req.url, srcUrl, readers, ziped);
for (var reader in item.headers)
res.setHeader(reader, item.headers[reader]);
res.status(200);
res.send(item.data);
});
});
};
this.send = function(res, item) {
for (var reader in item.headers)
res.setHeader(reader[0], reader[1]);
res.status(200);
res.send(item.data);
};
this.cacheAndSend = function (res, url, dir, headers, data) {
var item =context.$cache.add (url, dir, headers, data);
this.send(res, item);
};
// setting
this.init = function () {
context.$cache = new Cache();
context.$server.use(this.cacheResponse);
context.$server.use(this.putPathData);
context.$server.use(this.corsFilter);
context.$server.use(this.serveStatics);
context.$server.use(this.sendFiles);
context.$server.use(this.angularRouteResponse);
};
};