'use strict' ;
const Promise = require ( "bluebird" ) ;
const express = require ( "express" ) ;
// const expressWs = require("express-ws");
const knex = require ( "knex" ) ;
const path = require ( "path" ) ;
const bodyParser = require ( "body-parser" ) ;
const graphql = require ( "graphql" ) ;
const chalk = require ( "chalk" ) ;
const util = require ( "util" ) ;
const errorChain = require ( "error-chain" ) ;
const expressAsyncReact = require ( "./packages/express-async-react" ) ;
function projectPath ( targetPath ) {
return path . join ( _ _dirname , ".." , targetPath ) ;
}
module . exports = function ( ) {
let db = knex ( require ( "../knexfile" ) ) ;
let imageStore = require ( "./util/image-store" ) ( projectPath ( "./images" ) ) ;
let taskTracker = require ( "../lib/tasks/tracker" ) ( ) ;
let api = require ( "./api" ) ( ) ;
let state = { db , imageStore , taskTracker } ;
let app = express ( ) ;
// expressWs(app);
app . engine ( "jsx" , expressAsyncReact . createEngine ( {
prepare : ( template , locals ) => {
return Promise . try ( ( ) => {
if ( template . query != null ) {
let queryArguments = ( template . queryArguments != null )
? template . queryArguments ( locals )
: { } ;
return api . query ( template . query , queryArguments ) ;
}
} ) . then ( ( result ) => {
console . dir ( { templateInput : result } , { depth : null } ) ;
if ( result == null ) {
return { } ;
} else {
return { data : result } ;
// if (result.errors != null && result.errors.length > 0) {
// throw result.errors[0];
// } else {
// return {
// data: result.data
// };
// }
}
} ) ;
}
} ) ) ;
app . set ( "view engine" , "jsx" ) ;
app . set ( "views" , projectPath ( "src/views" ) ) ;
app . locals [ expressAsyncReact . Settings ] = {
componentPath : "template"
} ;
app . use ( ( req , res , next ) => {
res . locals . currentPath = req . originalUrl ;
next ( ) ;
} ) ;
app . use ( express . static ( projectPath ( "public" ) ) ) ;
app . use ( bodyParser . urlencoded ( {
extended : true
} ) ) ;
app . get ( "/debug-query" , ( req , res ) => {
res . render ( "debug-query" ) ;
} ) ;
app . use ( require ( "./routes/index" ) ) ;
app . use ( "/disk-images" , require ( "./routes/disk-images" ) ( state ) ) ;
app . get ( "/hardware" , ( req , res ) => {
// FIXME: default to /hardware/system-information instead, when that is implemented
res . redirect ( "/hardware/storage-devices" ) ;
} ) ;
app . use ( ( err , req , res , next ) => {
/* GraphQL will wrap any data-resolving errors in its own error type, and that'll break our `showChain` logic below. Note that some GraphQL errors may not *have* an originalError (eg. schema violations), so we account for that as well. */
// let sourceError = (err instanceof graphql.GraphQLError && err.originalError != null)
// ? err.originalError
// : err;
// console.error(errorChain.render(sourceError));
// // FIXME: Render full context instead, according to error-chain?
// for (let key of Object.keys(err)) {
// console.error(chalk.yellow.bold(`${key}: `) + util.inspect(err[key], { colors: true }));
// }
res . render ( "error" , {
error : errorChain . render ( err ) + "\n\n ✂ ----------- \n\nError context: " + util . inspect ( errorChain . getContext ( err ) , { colors : true } )
} ) ;
// debugger;
} ) ;
return app ;
} ;