-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathhapiApollo.ts
94 lines (84 loc) · 2.64 KB
/
hapiApollo.ts
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
import Boom from 'boom';
import { Server, Request, RouteOptions } from 'hapi';
import {
GraphQLOptions,
runHttpQuery,
convertNodeHttpToRequest,
} from 'apollo-server-core';
import { ValueOrPromise } from 'apollo-server-types';
export interface IRegister {
(server: Server, options: any, next?: Function): void;
}
export interface IPlugin {
name: string;
version?: string;
register: IRegister;
}
export interface HapiOptionsFunction {
(request?: Request): ValueOrPromise<GraphQLOptions>;
}
export interface HapiPluginOptions {
path: string;
vhost?: string;
route?: RouteOptions;
graphqlOptions: GraphQLOptions | HapiOptionsFunction;
}
const graphqlHapi: IPlugin = {
name: 'graphql',
register: (server: Server, options: HapiPluginOptions, next?: Function) => {
if (!options || !options.graphqlOptions) {
throw new Error('Apollo Server requires options.');
}
server.route({
method: ['GET', 'POST'],
path: options.path || '/graphql',
vhost: options.vhost || undefined,
options: options.route || {},
handler: async (request, h) => {
try {
const { graphqlResponse, responseInit } = await runHttpQuery(
[request, h],
{
method: request.method.toUpperCase(),
options: options.graphqlOptions,
query:
request.method === 'post'
? // TODO type payload as string or Record
(request.payload as any)
: request.query,
request: convertNodeHttpToRequest(request.raw.req),
},
);
const response = h.response(graphqlResponse);
Object.keys(responseInit.headers).forEach(key =>
response.header(key, responseInit.headers[key]),
);
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;
}
},
});
if (next) {
next();
}
},
};
export { graphqlHapi };