All files / utils/services/apollo apollo.service.ts

20% Statements 9/45
0% Branches 0/30
0% Functions 0/7
18.18% Lines 8/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1298x   8x 8x         8x 8x                                             8x                                                                                                                                           8x                                                   8x
import * as Boom from 'boom';
import { Server, Request } from 'hapi';
import * as GraphiQL from 'apollo-server-module-graphiql';
import {
  GraphQLOptions,
  runHttpQuery,
  HttpQueryError,
} from 'apollo-server-core';
import { AuthService } from '../auth/auth.service';
import { Container } from '../../container';
 
export interface IRegister {
  (server: Server, options: any): void;
}
 
export interface IPlugin {
  name: string;
  version?: string;
  register: IRegister;
}
 
export interface HapiOptionsFunction {
  (req?: Request): GraphQLOptions | Promise<GraphQLOptions>;
}
 
export interface HapiPluginOptions {
  path: string;
  vhost?: string;
  route?: any;
  graphqlOptions: GraphQLOptions | HapiOptionsFunction;
}
 
const graphqlHapi: IPlugin = {
  name: 'graphql',
  register: (server: Server, options) => {
    if (!options || !options.graphqlOptions) {
      throw new Error('Apollo Server requires options.');
    }
 
    server.route(<any>{
      method: ['GET', 'POST'],
      path: options.path || '/graphql',
      vhost: options.vhost || undefined,
      config: options.route || {},
      handler: async (request, h) => {
        try {
          if (request.headers.authorization && request.headers.authorization !== 'undefined') {
            try {
              const serviceUtilsService: AuthService = Container.get(AuthService);
              options.graphqlOptions.context = await serviceUtilsService.modifyFunctions.validateToken(request.headers.authorization);
            } catch (e) {
              return Boom.unauthorized();
            }
          } else {
            options.graphqlOptions.context = null;
          }
          const gqlResponse = await runHttpQuery([request], {
            method: request.method.toUpperCase(),
            options: options.graphqlOptions,
            query: request.method === 'post' ? request.payload : request.query,
          });
 
          const response = h.response(gqlResponse);
          response.type('application/json');
          return response;
        } catch (error) {
          if ('HttpQueryError' !== error.name) {
            throw Boom.boomify(error);
          }
 
          if (true === error.isGraphQLError) {
            const response = h.response(error.message);
            response.code(error.statusCode);
            response.type('application/json');
            return response;
          }
 
          const err = new Boom(error.message, { statusCode: error.statusCode });
          if (error.headers) {
            Object.keys(error.headers).forEach(header => {
              err.output.headers[header] = error.headers[header];
            });
          }
          // Boom hides the error when status code is 500
          err.output.payload.message = error.message;
          throw err;
        }
      },
    });
  },
};
 
export interface HapiGraphiQLOptionsFunction {
  (req?: Request): GraphiQL.GraphiQLData | Promise<GraphiQL.GraphiQLData>;
}
 
export interface HapiGraphiQLPluginOptions {
  path: string;
  route?: any;
  graphiqlOptions: GraphiQL.GraphiQLData | HapiGraphiQLOptionsFunction;
}
 
const graphiqlHapi: IPlugin = {
  name: 'graphiql',
  register: (server: Server, options: HapiGraphiQLPluginOptions) => {
    if (!options || !options.graphiqlOptions) {
      throw new Error('Apollo Server GraphiQL requires options.');
    }
 
    server.route(<any>{
      method: 'GET',
      path: options.path || '/graphiql',
      config: options.route || {},
      handler: async (request, h) => {
        const graphiqlString = await GraphiQL.resolveGraphiQLString(
          request.query,
          options.graphiqlOptions,
          request,
        );
 
        const response = h.response(graphiqlString);
        response.type('text/html');
        return response;
      },
    });
  },
};
 
export { graphqlHapi, graphiqlHapi };