reiso
Version:
286 lines • 27.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express = require("express");
const bodyParser = require("body-parser");
const http = require("http");
const cookieParser = require("cookie-parser");
const helmet = require("helmet");
const graphqlHTTP = require("apollo-server-express");
const graphql = require("graphql");
const subscriptionServer = require("subscriptions-transport-ws");
const multer = require("multer");
const fs = require("fs");
const path = require("path");
const compression = require("compression");
const seaport = require("seaport");
const ddos = require('ddos');
const Config_1 = require("../Modules/Config");
const Translation = require("../Modules/Translation");
const Query = require("../Modules/Query");
const Log = require("../Modules/Log");
const WebHook = require("../Modules/WebHook");
const Hooks = require("../Modules/ServerHook");
const Render_1 = require("../Server/Render");
const Error_1 = require("./Lib/Error");
const Url_1 = require("./Lib/Url");
const Translation_1 = require("./Lib/Translation");
class Server {
async start() {
await this.init();
await this.setBasic();
await this.setHelmet();
await this.setStatic();
await this.setLogger();
await this.setFileUpload();
await this.setGraphQL();
await this.setWebHook();
await this.setRender();
await this.setSubscription();
await this.setLogError();
await this.run();
}
async stop() {
await Promise.all([
new Promise(r => this.websocketServer.close(r)),
new Promise(r => this.server.close(r))
]);
}
init() {
this.app = express();
}
setBasic() {
Config_1.getConfig().port && this.app.set('port', Config_1.getConfig().port);
this.app.use(cookieParser());
this.app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
this.app.use(bodyParser.urlencoded({ extended: true }));
this.app.use(bodyParser.json());
this.app.use(compression());
}
setHelmet() {
if (Config_1.getConfig().proxyProtection)
this.app.set('trust proxy', 1);
this.app.use(helmet());
this.app.disable('x-powered-by');
if (Config_1.getConfig().ddos) {
this.app.use((new ddos(Config_1.getConfig().ddos)).express);
}
}
setStatic() {
this.app.get('*.js', (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('GET ' + Url_1.processUrl(req.url), 'static');
if (fs.existsSync(path.resolve(Config_1.getConfig().publicDir, Url_1.processUrl(req.url)) + '.gz')) {
req.url = req.url + '.gz';
res.set('Content-Type', 'text/javascript');
res.set('Content-Encoding', 'gzip');
}
next();
});
this.app.get('*.css', (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('GET ' + Url_1.processUrl(req.url), 'static');
if (fs.existsSync(path.resolve(Config_1.getConfig().publicDir, Url_1.processUrl(req.url)) + '.gz')) {
req.url = req.url + '.gz';
res.set('Content-Type', 'text/css');
res.set('Content-Encoding', 'gzip');
}
next();
});
this.app.use(express.static(Config_1.getConfig().publicDir));
this.app.use('/uploads', express.static(Config_1.getConfig().uploadDir));
}
setLogger() {
this.app.all('/*', (req, res, next) => {
Log.logInfo({
message: 'request',
method: req.method,
path: req.path,
url: req.url,
hostname: req.hostname,
headers: req.headers,
ip: req.ip,
body: req.body
});
next();
});
}
setSubscription() {
this.subscriptionManager = new Query.SubscriptionManager();
this.subscriptionManager.init();
}
setLogError() {
this.app.use((error, req, res, next) => {
if (error.status)
res.status(error.status);
else
res.status(501);
res.json(Error_1.parseAndLogError(error, 'server', req, res));
});
}
setRender() {
Translation.getLanguages().forEach(language => {
this.app.get('/' + language + '/*', (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('GET ' + Url_1.processUrl(req.baseUrl), 'render');
return Render_1.Render(req, res, next, language);
});
});
this.app.get('/*', (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('GET ' + Url_1.processUrl(req.baseUrl), 'render');
return Render_1.Render(req, res, next);
});
}
setFileUpload() {
let storage;
if (Config_1.getConfig().tempUploadDir) {
storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, path.resolve(Config_1.getConfig().tempUploadDir));
},
filename: (req, file, callback) => {
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
}
else {
storage = multer.memoryStorage();
}
let upload = multer({
storage,
limits: {
fileSize: Config_1.getConfig().maxFileSize * 1000000
}
}).any();
this.app.post('/*', (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('POST ' + Url_1.processUrl(req.baseUrl), 'upload');
upload(req, res, err => {
var a = req;
if (err) {
res.error = err.message;
}
next();
});
});
}
setWebHook() {
Hooks.getWebHooks().forEach(webHook => {
this.app.post('/wh/' + webHook.path, (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName('POST ' + Url_1.processUrl(req.baseUrl), 'webhook');
WebHook.hook(webHook, req, res, next);
});
});
}
initGraphQL() {
Query.getSchema();
Query.getSubscriptionSchema();
}
async setGraphQL() {
this.initGraphQL();
this.app.use('/graphql', bodyParser.json(), async (req, res, next) => {
Config_1.getConfig().apm && Log.getApm().setTransactionName(req.method + ' ' + Url_1.processUrl(req.baseUrl), 'graphql');
let context = {
files: req.files,
language: Translation.getLanguage(),
quotaLimit: Config_1.getConfig().quotaLimit || 0,
quota: 0
};
if (req.body.operations) {
req.body = JSON.parse(req.body.operations);
}
for (let hook of Hooks.getHooksGraphQL()) {
await hook(req, context);
}
Translation_1.setLanguageContext(context);
if (req.headers.language) {
context.language = req.headers.language;
context.trans = (query, ...args) => Translation.trans(context.language, query, ...args);
}
graphqlHTTP.graphqlExpress({
schema: Query.getSchema(),
context,
formatError: error => Error_1.parseAndLogError(error, 'graphql', req, res),
debug: false,
})(req, res, next);
});
Config_1.getConfig().graphiql && this.app.get('/graphiql', graphqlHTTP.graphiqlExpress({ endpointURL: '/graphql' }));
this.websocketServer = http.createServer(this.app);
await new Promise(r => {
if (Config_1.getConfig().seaportHost && Config_1.getConfig().seaportPort) {
var ports = seaport.connect(Config_1.getConfig().seaportHost, Config_1.getConfig().seaportPort);
this.websocketServer.listen(ports.register(Config_1.getConfig().seaportWSName || "ServerWS"), () => {
Log.logInfo(`Websocket Server is connected to seaport as "${Config_1.getConfig().seaportWSName || "ServerWS"}" on ${Config_1.getConfig().seaportHost}:${Config_1.getConfig().seaportPort}`);
this.subscriptionsServer = this.makeSubscriptionServer(this.websocketServer);
r();
});
}
else {
this.websocketServer.listen(Config_1.getConfig().portWS, () => {
Log.logInfo(`Websocket Server is listening on port ${Config_1.getConfig().portWS}`);
this.subscriptionsServer = this.makeSubscriptionServer(this.websocketServer);
r();
});
}
});
}
makeSubscriptionServer(websocketServer) {
return new subscriptionServer.SubscriptionServer({
schema: Query.getSubscriptionSchema(),
execute: graphql.execute,
subscribe: graphql.subscribe,
onConnect: async (connectionParams, webSocket, connectionContext) => {
for (let hook of Hooks.getHooksWSonConnect()) {
await hook(connectionParams, webSocket, connectionContext);
}
if (connectionParams.language)
connectionContext.socket.upgradeReq.headers.language = connectionParams.language;
},
onOperation: async (message, params, webSocket) => {
if (!params.context)
params.context = {};
params.context.language = Translation.getLanguage();
for (let hook of Hooks.getHooksWSonMessage()) {
await hook(message, params, webSocket);
}
if (webSocket.upgradeReq.headers.language)
params.context.language = webSocket.upgradeReq.headers.language;
Translation_1.setLanguageContext(params.context);
return params;
},
onDisconnect: async (webSocket) => {
for (let hook of Hooks.getHooksWSonDisconnect()) {
await hook(webSocket);
}
}
}, {
server: websocketServer
});
}
async run() {
this.server = http.createServer(this.app);
await new Promise(r => {
if (Config_1.getConfig().seaportHost && Config_1.getConfig().seaportPort) {
Log.logInfo(`Server is connected to seaport as "${Config_1.getConfig().seaportName || "Server"}" on ${Config_1.getConfig().seaportHost}:${Config_1.getConfig().seaportPort}`);
var ports = seaport.connect(Config_1.getConfig().seaportHost, Config_1.getConfig().seaportPort);
this.server.listen(ports.register(Config_1.getConfig().seaportName || "Server"));
for (let hook of Hooks.getHooksAfterServerStart()) {
hook();
}
r();
}
else {
this.server.listen(this.app.get('port'), () => {
Log.logInfo('Server is listening on port ' + this.app.get('port'));
for (let hook of Hooks.getHooksAfterServerStart()) {
hook();
}
r();
// TODO: Make an example in hooks
// if (process.env.NODE_ENV == 'development') fetch('http://localhost:3001/__browser_sync__?method=reload&args=index.js');
});
}
});
}
}
exports.Server = Server;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL1NlcnZlci9TZXJ2ZXIudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQW1DO0FBQ25DLDBDQUEwQztBQUMxQyw2QkFBNkI7QUFDN0IsOENBQThDO0FBQzlDLGlDQUFpQztBQUNqQyxxREFBcUQ7QUFDckQsbUNBQW1DO0FBQ25DLGlFQUFpRTtBQUNqRSxpQ0FBaUM7QUFDakMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwyQ0FBMkM7QUFDM0MsbUNBQW1DO0FBQ25DLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUU3Qiw4Q0FBOEM7QUFDOUMsc0RBQXNEO0FBQ3RELDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFDdEMsOENBQThDO0FBQzlDLCtDQUErQztBQUMvQyw2Q0FBMEM7QUFDMUMsdUNBQStDO0FBQy9DLG1DQUF1QztBQUN2QyxtREFBdUQ7QUFFdkQ7SUFPUyxLQUFLLENBQUMsS0FBSztRQUNoQixNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixNQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4QixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4QixNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM3QixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUksQ0FB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