Newer
Older
const config = require('config')
const isEmpty = require('lodash/isEmpty')
const merge = require('lodash/merge')
const { applyMiddleware } = require('graphql-middleware')
const { shield } = require('graphql-shield')
/* eslint-disable-next-line import/extensions */
const GraphQLUpload = require('graphql-upload/GraphQLUpload.js')
const { makeExecutableSchema } = require('@graphql-tools/schema')
const logger = require('../logger')
const { logTask } = require('../logger/internals')
const tryRequireRelative = require('../utils/tryRequireRelative')
const emailMiddleware = require('../middleware/email')
// #region BUILD-SCHEMA
// load base types and resolvers
const typeDefs = [`type Query, type Mutation, type Subscription, scalar Upload`]
const resolvers = merge(
{},
{
Upload: GraphQLUpload,
},
)
// recursively merge in component types and resolvers
function getSchemaRecursively(componentName) {
const component = tryRequireRelative(componentName)
if (component.extending) {
getSchemaRecursively(component.extending)
}
if (component.typeDefs) {
typeDefs.push(component.typeDefs)
}
if (component.resolvers) {
merge(resolvers, component.resolvers)
}
}
if (config.has('components')) {
config.get('components').forEach(componentName => {
getSchemaRecursively(componentName)
})
}
const schema = makeExecutableSchema({ typeDefs, resolvers })
// #endregion BUILD-SCHEMA
// #region GRAPHQL-MIDDLEWARE
const baseMessage = 'Coko server =>'
const logRegistration = name =>
logger.info(`${baseMessage} Middleware: Registered ${name} middleware`)
const middleware = []
logTask('Register graphql middleware')
/**
* Authorization middleware
*/
const permissions = config.has('permissions') && config.get('permissions')
const isProduction = process.env.NODE_ENV === 'production'
const authorizationMiddleware = shield(permissions, {
allowExternalErrors: true,
debug: !isProduction,
})
middleware.push(authorizationMiddleware)
logRegistration('authorization')
/**
* Email middleware
*/
const emailConfig =
config.has('emailMiddleware') && config.get('emailMiddleware')
if (!isEmpty(emailConfig)) {
middleware.push(emailMiddleware)
logRegistration('email')
}
const schemaWithMiddleWare = applyMiddleware(schema, ...middleware)
module.exports = schemaWithMiddleWare