1 | 'use strict';
|
2 |
|
3 | const Assert = require('assert');
|
4 | const Fs = require('fs');
|
5 | const Url = require('url');
|
6 | const Path = require('path');
|
7 | const Graphi = require('graphi');
|
8 | const Package = require('../package.json');
|
9 | const CloudApi = require('webconsole-cloudapi-client');
|
10 | const Formatters = require('./formatters');
|
11 | const Routes = require('./routes');
|
12 |
|
13 | const Schema = Fs.readFileSync(Path.join(__dirname, '/schema.graphql'));
|
14 |
|
15 | const setupCloudApi = ({ keyId, key, apiBaseUrl }) => {
|
16 | return ({ auth, log }) => {
|
17 | return new CloudApi({
|
18 | token: auth.credentials && auth.credentials.token,
|
19 | url: apiBaseUrl,
|
20 | keyId,
|
21 | key,
|
22 | log
|
23 | });
|
24 | };
|
25 | };
|
26 |
|
27 | const preResolve = (cloudapi) => {
|
28 | return (root, args, request) => {
|
29 | if (request.route.settings.auth === false) {
|
30 | return;
|
31 | }
|
32 |
|
33 | return cloudapi({ auth: request.auth, log: request.log.bind(request) });
|
34 | };
|
35 | };
|
36 |
|
37 | const postAuth = (cloudapi) => {
|
38 | return (request, h) => {
|
39 | if (request.route.settings.auth === false) {
|
40 | return h.continue;
|
41 | }
|
42 |
|
43 | request.plugins.cloudapi = cloudapi({ auth: request.auth, log: request.log.bind(request) });
|
44 |
|
45 | return h.continue;
|
46 | };
|
47 | };
|
48 |
|
49 | const graphqlHandler = function (route, options) {
|
50 | Assert(typeof options.method === 'function', 'method must be a function');
|
51 |
|
52 | return function (request, h) {
|
53 | const fetch = request.plugins.cloudapi.fetch.bind(request.plugins.cloudapi);
|
54 | return options.method(fetch, request.payload, request);
|
55 | };
|
56 | };
|
57 |
|
58 | const register = async (server, options = {}) => {
|
59 | Assert(options.apiBaseUrl, 'options.apiBaseUrl is required');
|
60 | Assert(options.keyId, 'options.keyId is required');
|
61 | Assert(options.keyPath, 'options.keyPath is required');
|
62 |
|
63 | const key = Fs.readFileSync(options.keyPath);
|
64 | options.dcName = options.dcName || Url.parse(options.apiBaseUrl).host.split('.')[0];
|
65 |
|
66 | const cloudapi = setupCloudApi({ key, ...options });
|
67 |
|
68 | const schema = Graphi.makeExecutableSchema({
|
69 | schema: Schema.toString(),
|
70 | resolvers: Formatters,
|
71 | preResolve: preResolve(cloudapi)
|
72 | });
|
73 |
|
74 | server.decorate('handler', 'graphql', graphqlHandler);
|
75 | server.expose('options', options);
|
76 | server.route(Routes);
|
77 |
|
78 | const graphiOptions = {
|
79 | graphiqlPath: process.env.NODE_ENV === 'development' ? '/graphiql' : options.graphiqlPath,
|
80 | schema: schema,
|
81 | authStrategy: options.authStrategy
|
82 | };
|
83 |
|
84 | await server.register({ plugin: Graphi, options: graphiOptions });
|
85 |
|
86 | server.ext({ type: 'onPostAuth', method: postAuth(cloudapi), options: { sandbox: 'plugin' } });
|
87 | };
|
88 |
|
89 | module.exports = {
|
90 | pkg: Package,
|
91 | register
|
92 | };
|