@@ -24,8 +24,15 @@ import url from 'url';
24
24
import { parseBody } from './parseBody' ;
25
25
import { renderGraphiQL } from './renderGraphiQL' ;
26
26
27
- import type { Request , Response } from 'express' ;
28
-
27
+ import type { Response } from 'express' ;
28
+
29
+ export type Request = {
30
+ method : string ;
31
+ url: string ;
32
+ body: mixed ;
33
+ headers: { [ header : string ] : mixed } ;
34
+ pipe < T > ( stream : T ) : T ;
35
+ } ;
29
36
30
37
/**
31
38
* Used to configure the graphqlHTTP middleware by providing a schema
@@ -147,17 +154,14 @@ export default function graphqlHTTP(options: Options): Middleware {
147
154
throw httpError ( 405 , 'GraphQL only supports GET and POST requests.' ) ;
148
155
}
149
156
150
- // Parse the Request body.
151
- return parseBody ( request ) ;
152
- } ) . then ( bodyData => {
153
- const urlData = request . url && url . parse ( request . url , true ) . query || { } ;
154
- showGraphiQL = graphiql && canDisplayGraphiQL ( request , urlData , bodyData ) ;
155
-
157
+ // Parse the Request to get GraphQL request parameters.
158
+ return getGraphQLParams ( request ) ;
159
+ } ) . then ( params => {
156
160
// Get GraphQL params from the request and POST body data.
157
- const params = getGraphQLParams ( urlData , bodyData ) ;
158
161
query = params . query ;
159
162
variables = params . variables ;
160
163
operationName = params . operationName ;
164
+ showGraphiQL = graphiql && canDisplayGraphiQL ( request , params ) ;
161
165
162
166
// If there is no query, but GraphiQL will be displayed, do not produce
163
167
// a result, otherwise return a 400: Bad Request.
@@ -252,16 +256,28 @@ export default function graphqlHTTP(options: Options): Middleware {
252
256
} ;
253
257
}
254
258
255
- type GraphQLParams = {
259
+ export type GraphQLParams = {
256
260
query : ?string ;
257
261
variables: ?{ [ name : string ] : mixed } ;
258
262
operationName: ?string ;
263
+ raw: ?boolean ;
259
264
} ;
260
265
266
+ /**
267
+ * Provided a "Request" provided by express or connect (typically a node style
268
+ * HTTPClientRequest), Promise the GraphQL request parameters.
269
+ */
270
+ export function getGraphQLParams ( request : Request ) : Promise < GraphQLParams > {
271
+ return parseBody ( request ) . then ( bodyData => {
272
+ const urlData = request . url && url . parse ( request . url , true ) . query || { } ;
273
+ return parseGraphQLParams ( urlData , bodyData ) ;
274
+ } ) ;
275
+ }
276
+
261
277
/**
262
278
* Helper function to get the GraphQL params from the request.
263
279
*/
264
- function getGraphQLParams (
280
+ function parseGraphQLParams (
265
281
urlData : { [ param : string ] : mixed } ,
266
282
bodyData : { [ param : string ] : mixed }
267
283
) : GraphQLParams {
@@ -289,22 +305,22 @@ function getGraphQLParams(
289
305
operationName = null ;
290
306
}
291
307
292
- return { query, variables, operationName } ;
308
+ const raw = urlData . raw !== undefined || bodyData . raw !== undefined ;
309
+
310
+ return { query, variables, operationName, raw } ;
293
311
}
294
312
295
313
/**
296
314
* Helper function to determine if GraphiQL can be displayed.
297
315
*/
298
316
function canDisplayGraphiQL (
299
317
request : Request ,
300
- urlData : { [ param : string ] : mixed } ,
301
- bodyData : { [ param : string ] : mixed }
318
+ params : GraphQLParams
302
319
) : boolean {
303
320
// If `raw` exists, GraphiQL mode is not enabled.
304
- const raw = urlData . raw !== undefined || bodyData . raw !== undefined ;
305
321
// Allowed to show GraphiQL if not requested as raw and this request
306
322
// prefers HTML over JSON.
307
- return ! raw && accepts ( request ) . types ( [ 'json' , 'html' ] ) === 'html' ;
323
+ return ! params . raw && accepts ( request ) . types ( [ 'json' , 'html' ] ) === 'html' ;
308
324
}
309
325
310
326
/**
0 commit comments