Skip to content
Snippets Groups Projects
schema.js 2.37 KiB
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'
if (!isEmpty(permissions)) {
  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')
}

// #endregion GRAPHQL-MIDDLEWARE

const schemaWithMiddleWare = applyMiddleware(schema, ...middleware)

module.exports = schemaWithMiddleWare