-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathprocessGraphqlRequest.ts
90 lines (87 loc) · 2.79 KB
/
processGraphqlRequest.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
// eslint-disable-next-line import/extensions
import { IncomingMessage } from 'http'
import { GraphqlContextError, GraphqlValidationError } from './errors'
import { badRequest, badRequestJson, json, methodNotAllowed } from './responses'
import GraphqlQueryStore from './GraphqlQueryStore'
type GraphqlResponse = {
status: number
text?: string
body?: any
}
type ProcessGraphqlRequestOptions = {
store: GraphqlQueryStore
context: any
processFileUploads?: (req: IncomingMessage) => Promise<any>
readRequestBody: (req: IncomingMessage) => Promise<any>
}
export default async function processGraphqlRequest(
req: IncomingMessage,
{
store,
context = {},
processFileUploads,
readRequestBody,
}: ProcessGraphqlRequestOptions
): Promise<GraphqlResponse> {
if (!store) {
throw Error('No query store provided.')
}
if (!readRequestBody) {
throw Error('No method provided to read the incoming request data.')
}
if (req.method !== 'POST') {
return methodNotAllowed()
}
let jsonBody = null
const contentType = req.headers['content-type']
if (contentType && contentType.startsWith('multipart/form-data')) {
if (!processFileUploads) {
return badRequest('File upload is not supported.')
}
try {
jsonBody = await processFileUploads(req)
} catch (e: any) {
return badRequest(`Failed to upload file. ${e.message}`)
}
} else {
try {
jsonBody = await readRequestBody(req)
} catch (e) {
return badRequest('Unable to parse the request body.')
}
}
const { query, variables } = jsonBody
if (!query) {
return badRequest('The query body param is required.')
}
const queryId = store.createId(query)
let compiledQuery = null
if (store.has(queryId)) {
compiledQuery = store.get(queryId)
} else {
try {
compiledQuery = store.create(query, variables)
} catch (e: any) {
if (e instanceof GraphqlValidationError) {
const { extensions, message } = e
return badRequestJson({ message, extensions })
}
return badRequest(e.message)
}
}
let queryContext = context
if (typeof context === 'function') {
try {
queryContext = await context(req, compiledQuery.query.name)
} catch (e: any) {
if (e instanceof GraphqlContextError) {
const { extensions, message } = e
return badRequestJson({ message, extensions })
}
return badRequest(e.message)
}
}
const root = {}
const result = await compiledQuery.query(root, queryContext, variables)
return json(result)
}