-
Notifications
You must be signed in to change notification settings - Fork 3
/
plugin.js
104 lines (89 loc) · 2.95 KB
/
plugin.js
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
import fp from 'fastify-plugin'
import { GraphQLClient } from 'graphql-request'
import hasuraRoutes from './routes.js'
function fastifyHasura(fastify, options, done) {
// Register fastify-sensible for handling errors in routes.
fastify.register(import('fastify-sensible'))
// Check options
if (!options.endpoint) throw new Error('You must provide hasura endpoint')
if (!options.admin_secret)
throw new Error('You must provide hasura admin secret')
if (!options.routes_prefix) options.routes_prefix = ''
// Provide fake graphql Hasura endpoint for testing
// if (fastify.config.NODE_ENV === 'test' && env.HASURA_GRAPHQL_TEST_ENDPOINT)
// env.HASURA_GRAPHQL_ENDPOINT = env.HASURA_GRAPHQL_TEST_ENDPOINT
// Ugly error come from graphql-request! See here https://github.com/prisma-labs/graphql-request/blob/777cc55f3f772f5b527df4b7b4ae5f66006b30e9/src/types.ts#L29
// TODO Implement formatter ? https://github.com/mercurius-js/mercurius/blob/master/lib/errors.js
class ErrorHasura extends Error {
constructor({ message }) {
const err = message.split(': {"resp')
const { response, request } = JSON.parse(
`{"resp${err[1]}`
.replace(/\n/g, '')
.replace(/field "(.*)" not/, "field '$1' not")
)
super(err[0])
this.query = request.query
this.variables = request.variables
this.extensions = response.errors[0].extensions
this.statusCode = 200
}
}
// Create graphql client.
const graphql_client = new GraphQLClient(options.endpoint, {
headers: {
'Content-Type': 'application/json',
'x-hasura-admin-secret': options.admin_secret
}
})
fastify.decorate('hasura', {
/**
* Provide `fastify.hasura.graphql` function to make request on Hasura graphql endpoint.
* @param {String} query Graphql query in AST format. Eg: gql`query...`
* @param {Object} variables Variables passed to the query.
* @return Object Response from Hasura instance.
*/
graphql: async (query, variables) => {
try {
const hasura_data = await graphql_client.request(query, variables)
// check if we got any response back
if (hasura_data.length === 0) {
throw new Error('Invalid request')
}
return hasura_data
} catch (err) {
throw new ErrorHasura(err)
}
},
/**
* Register events
*/
events: {},
registerEvent: (event, func) => {
fastify.hasura.events[event] = func
},
/**
* Register actions
*/
actions: {},
registerAction: (action, func) => {
fastify.hasura.actions[action] = func
},
/**
* Register crons
*/
crons: {},
registerCron: (cron, func) => {
fastify.hasura.crons[cron] = func
}
})
/**
* Register routes `/events`, `/actions` and `/crons`
*/
fastify.register(hasuraRoutes, options)
done()
}
export default fp(fastifyHasura, {
fastify: '>=2.11.0',
name: 'fastify-hasura'
})