Skip to content
Snippets Groups Projects
graphqlServer.js 2.23 KiB
Newer Older
const {
  ApolloServer,
  ForbiddenError,
  UserInputError,
  AuthenticationError,
  ApolloError,
} = require('apollo-server-express')

const isEmpty = require('lodash/isEmpty')
const config = require('config')

const errors = require('./errors')
const logger = require('./logger')
const loaders = require('./graphql/loaders')
const schema = require('./graphqlSchema')

const isDevelopment = process.env.NODE_ENV === 'development'

const createGraphQLServer = testUserContext => {
  if (process.env.NODE_ENV !== 'test' && testUserContext) {
    throw new Error(
      'Do not pass a test user context unless you are running a test suite',
    )
  }

  const createdLoaders = loaders()

  const serverConfig = {
    schema,
    context: ({ req, res }) => ({
      user: testUserContext || req.user,
    }),
    formatError: err => {
      const error = isEmpty(err.originalError) ? err : err.originalError

      logger.error(error.message, { error })

      const isPubsweetDefinedError = Object.values(errors).some(
        pubsweetError => error instanceof pubsweetError,
      )

      const isGraphqlDefinedError = [
        ForbiddenError,
        UserInputError,
        AuthenticationError,
        ApolloError,
      ].some(graphqlError => error instanceof graphqlError)

      // err is always a GraphQLError which should be passed to the client
      if (
        !isEmpty(err.originalError) &&
        !isPubsweetDefinedError &&
        !isGraphqlDefinedError
      )
        return {
          name: 'Server Error',
          message: 'Something went wrong! Please contact your administrator',
        }

      if (isGraphqlDefinedError) return error

      return {
        name: error.name || 'GraphQLError',
        message: error.message,
        extensions: {
          code: err.extensions.code,
        },
      }
    },
    introspection: process.env.NODE_ENV === 'development',
    const host = `${config.get('host')}${
      config.get('port') ? `:${config.get('port')}` : ''
    }`

    serverConfig.playground = {
      subscriptionEndpoint: `ws://${host}/subscriptions`,
    }
  }

  return new ApolloServer(serverConfig)
}

module.exports = createGraphQLServer