laconic-console/packages/console-server/src/server/main.js

156 lines
3.4 KiB
JavaScript

//
// Copyright 2020 DxOS.org
//
import compression from 'compression';
import bodyParser from 'body-parser';
import cors from 'cors';
import debug from 'debug';
import express from 'express';
import mustache from 'mustache-express';
import fs from 'fs';
import yaml from 'js-yaml';
import { ApolloServer, gql } from 'apollo-server-express';
import { print } from 'graphql/language';
import yargs from 'yargs';
// TODO(burdon): Use once published by @ashwinp.
// import { extensions as WNS_EXTENSIONS, schema as WNS_SCHEMA } from '@wirelineio/wns-schema';
import SYSTEM_STATUS from '@dxos/console-app/src/gql/system_status.graphql';
import { resolvers } from '../resolvers';
import API_SCHEMA from '../gql/api.graphql';
const argv = yargs
.option('config', {
alias: 'c',
description: 'Config file',
type: 'string'
})
.option('verbose', {
alias: 'v',
description: 'Verbse info',
type: 'boolean'
})
.help()
.alias('help', 'h')
.argv;
const configFile = argv.config || process.env.CONFIG_FILE;
if (!configFile) {
yargs.showHelp();
process.exit(1);
}
const config = yaml.safeLoad(fs.readFileSync(configFile));
const log = debug('dxos:console:server');
debug.enable(config.system.debug);
if (argv.verbose) {
log(JSON.stringify(config, undefined, 2));
}
//
// Express server.
//
const { app: { publicUrl } } = config;
const app = express();
app.set('views', `${__dirname}/views`);
app.set('view engine', 'mustache');
app.engine('mustache', mustache());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(compression());
app.get('/', (req, res) => {
res.redirect(publicUrl);
});
//
// CORS
//
// import cors from 'cors'
// https://expressjs.com/en/resources/middleware/cors.html
// https://www.prisma.io/blog/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
app.use(cors({
origin: true,
credentials: true
}));
//
// React app
// TODO(burdon): Can we load this via WNS?
//
const bundles = [
'runtime', 'vendor', 'material-ui', 'dxos', 'main'
];
app.use(`${publicUrl}/lib`, express.static('./dist/client'));
app.get(publicUrl, (req, res) => {
res.render('console', {
title: 'Console',
container: 'root',
config: JSON.stringify(config),
scripts: bundles.map(bundle => ({ src: `${publicUrl}/lib/${bundle}.bundle.js` }))
});
});
//
// Apollo Server and middleware
// https://www.apollographql.com/docs/apollo-server/api/apollo-server
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
//
const server = new ApolloServer({
typeDefs: [
API_SCHEMA
],
// https://www.apollographql.com/docs/graphql-tools/resolvers
resolvers,
// https://www.apollographql.com/docs/apollo-server/data/resolvers/#the-context-argument
context: ({ req }) => ({
config,
// TODO(burdon): Auth.
authToken: req.headers.authorization
}),
// https://www.apollographql.com/docs/apollo-server/testing/graphql-playground
// https://github.com/prisma-labs/graphql-playground#usage
// introspection: true,
playground: {
settings: {
'editor.theme': config.app.theme
},
tabs: [
{
name: 'Status',
endpoint: config.api.path,
query: print(gql(SYSTEM_STATUS))
}
]
}
});
server.applyMiddleware({ app, path: config.api.path });
//
// Start server
//
const { api: { port } } = config;
app.listen({ port }, () => {
log(`Running: http://localhost:${port}`);
});