atlasgql
Version:
A self-composing GraphQL server library using TypeScript, Express and Apollo Server
244 lines • 11 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Server = exports.EVENTS = void 0;
const chalk_1 = __importDefault(require("chalk"));
const compression_1 = __importDefault(require("compression"));
const cookie_parser_1 = __importDefault(require("cookie-parser"));
const cors_1 = __importDefault(require("cors"));
const debug_1 = __importDefault(require("debug"));
const events_1 = require("events");
const express_1 = __importDefault(require("express"));
const fs_1 = __importDefault(require("fs"));
const http_1 = __importDefault(require("http"));
const morgan_1 = __importDefault(require("morgan"));
const multer_1 = __importDefault(require("multer"));
const configurations_1 = require("./configurations");
const graphqlServer_1 = require("./graphqlServer");
const constants_1 = require("./helpers/constants");
const hooks_1 = require("./hooks");
const rest_1 = __importStar(require("./routes/rest"));
var EVENTS;
(function (EVENTS) {
EVENTS["APOLLO_READY"] = "onApolloReady";
EVENTS["WEB_INTERFACE_READY"] = "onWebInterfaceReady";
EVENTS["GRAPHQL_LISTENING"] = "onGraphQLListening";
EVENTS["EXIT"] = "onExit";
EVENTS["ERROR"] = "onError";
})(EVENTS = exports.EVENTS || (exports.EVENTS = {}));
class Server {
constructor(env, envId, confs) {
this.confs = confs;
this.events = new events_1.EventEmitter();
this.isDev = false;
this.express = (0, express_1.default)();
this.corsOptions = false;
this.debug = (0, debug_1.default)('modern-express:server');
configurations_1.Configurations.load(env, envId, confs.defaultConfs);
this.debug.log = console.log.bind(console);
this.isDev =
configurations_1.Configurations.ServerEnv === constants_1.ENV.DEV ||
configurations_1.Configurations.ServerEnv === constants_1.ENV.TEST;
}
start() {
this.configureCors();
this.initApolloServer(this.confs.serverOpts);
this.configureRestRoutes();
this.configureMiscExpressMIddlewares();
this.createWebInterface();
}
initApolloServer(options) {
const validationRules = (options === null || options === void 0 ? void 0 : options.validationRules) || [];
const formatResponse = options === null || options === void 0 ? void 0 : options.formatResponse;
const formatError = options === null || options === void 0 ? void 0 : options.formatError;
const customContext = options === null || options === void 0 ? void 0 : options.customContext;
const middlewares = options === null || options === void 0 ? void 0 : options.middlewares;
const resolvers = options === null || options === void 0 ? void 0 : options.resolvers;
graphqlServer_1.GraphQlServer.createServer(configurations_1.Configurations.GraphQlPath, this.express, this.corsOptions, this.isDev, {
validationRules,
formatResponse,
formatError,
customContext,
middlewares,
resolvers,
});
this.events.emit(EVENTS.APOLLO_READY);
}
configureCors() {
if (configurations_1.Configurations.CORSEnabled) {
this.corsOptions = {
origin: (origin, callback) => {
if (!origin ||
(origin && configurations_1.Configurations.Origin.indexOf(origin) !== -1)) {
callback(null, true);
}
else {
callback(new Error('Not allowed by CORS'));
}
},
methods: configurations_1.Configurations.AcceptedMethods,
preflightContinue: configurations_1.Configurations.PreflightContinue,
optionsSuccessStatus: configurations_1.Configurations.OptionsSuccessStatus,
credentials: true,
};
this.express.options(configurations_1.Configurations.Origin, (0, cors_1.default)(this.corsOptions));
}
}
configureRestRoutes() {
var _a;
if ((_a = this.confs.serverOpts) === null || _a === void 0 ? void 0 : _a.restRoutes) {
(0, rest_1.registerCustomRoutes)(this.confs.serverOpts.restRoutes);
}
if (typeof this.corsOptions === 'object') {
this.express.use(configurations_1.Configurations.RestPath, (0, cors_1.default)(this.corsOptions), rest_1.default);
}
else {
this.express.use(configurations_1.Configurations.RestPath, rest_1.default);
}
}
configureMiscExpressMIddlewares() {
this.express.use((0, multer_1.default)({
storage: multer_1.default.memoryStorage(),
}).any());
this.express.set('views', configurations_1.Configurations.ViewsSrcPath);
this.express.set('view engine', configurations_1.Configurations.ViewsEngine);
this.express.use((0, morgan_1.default)('dev'));
this.express.use((0, compression_1.default)());
this.express.use(express_1.default.json());
this.express.use(express_1.default.urlencoded());
this.express.use((0, cookie_parser_1.default)());
}
createWebInterface() {
var _a, _b;
if ((_b = (_a = this.confs.serverOpts) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.preInit) {
this.confs.serverOpts.hooks.preInit();
}
(0, hooks_1.PreInitHook)();
this.initHttpServer();
this.handleExit();
this.registerHttpEvents();
this.createLock();
this.sayWelcome();
this.events.emit(EVENTS.WEB_INTERFACE_READY);
}
initHttpServer() {
graphqlServer_1.GraphQlServer.httpServer = http_1.default.createServer(this.express);
graphqlServer_1.GraphQlServer.httpServer.listen(configurations_1.Configurations.ServerPort, configurations_1.Configurations.ServerAddr);
}
removeLock() {
try {
fs_1.default.unlinkSync('.pid.lock');
}
catch (err) {
}
}
onExit() {
this.events.emit(EVENTS.EXIT);
this.removeLock();
process.exit();
}
createLock() {
this.removeLock();
fs_1.default.writeFileSync('.pid.lock', `${process.pid}`, { flag: 'wx' });
}
registerHttpEvents() {
if (!graphqlServer_1.GraphQlServer.httpServer) {
throw new Error('HTTP Server not initialized.');
}
graphqlServer_1.GraphQlServer.httpServer.on('error', (error) => {
this.events.emit(EVENTS.ERROR, error);
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof configurations_1.Configurations.ServerPort === 'string'
? `Pipe ${configurations_1.Configurations.ServerPort}`
: `Port ${configurations_1.Configurations.ServerPort}`;
switch (error.code) {
default:
throw error;
case 'EACCES':
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(`${bind} is already in use`);
process.exit(1);
break;
}
});
graphqlServer_1.GraphQlServer.httpServer.on('listening', () => {
var _a, _b;
const addr = graphqlServer_1.GraphQlServer.httpServer.address();
if (addr === null) {
throw new Error('addr is null');
}
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
this.debug(`Listening on ${bind}`);
this.events.emit(EVENTS.GRAPHQL_LISTENING);
if ((_b = (_a = this.confs.serverOpts) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.postInit) {
this.confs.serverOpts.hooks.postInit();
}
(0, hooks_1.PostInitHook)();
});
}
handleExit() {
process.stdin.resume();
process.on('uncaughtException', () => this.onExit());
process.on('beforeExit', () => this.onExit());
process.on('SIGINT', () => this.onExit());
process.on('SIGTERM', () => this.onExit());
}
sayWelcome() {
const welcomeMessage = ` => Service up and running <= `;
const serverAddressMessage = ` Listening on http://${configurations_1.Configurations.ServerAddr}:${configurations_1.Configurations.ServerPort} `;
const serverKeyMessage = ` The Service ID is ${configurations_1.Configurations.ServerKey} `;
console.log('\n');
console.log(chalk_1.default.white.bgMagentaBright(' '));
console.log(chalk_1.default.white.bgMagentaBright.bold(` ${welcomeMessage} `));
console.log(chalk_1.default.white.bgMagentaBright(' '));
console.log(chalk_1.default.white.bgBlack(serverAddressMessage));
console.log(chalk_1.default.white.bgBlack(serverKeyMessage));
console.log('\n');
if (this.isDev) {
console.log(`If you want to quickly try the server, go to http://${configurations_1.Configurations.ServerAddr}:${configurations_1.Configurations.ServerPort}${configurations_1.Configurations.GraphQlPath} and try the following query:`);
console.log(`-------------------------
query demo {
info {
startedAt
name
version
uptime
}
}
-------------------------`);
console.log('\n');
}
}
}
exports.Server = Server;
//# sourceMappingURL=server.js.map