-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.js
127 lines (111 loc) · 3.4 KB
/
index.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const { mergeResolvers, mergeTypes } = require('merge-graphql-schemas');
const ApolloServerExpress = require('apollo-server-express');
const express = require('express');
const http = require('http');
const { ApolloServer, gql } = ApolloServerExpress;
class Router {
constructor() {
this.RESOLVER_TYPES = {
Query: 'Query',
Mutation: 'Mutation',
Subscription: 'Subscription',
};
this.delete = this.patch = this.post = this.put = this.mutation;
this.get = this.query;
this.middlewares = [];
this.resolvers = {};
this.schemas = [];
}
use(func) {
if (func instanceof Router) {
this.middlewares = this.middlewares.concat(func.middlewares);
this.resolvers = mergeResolvers([this.resolvers, func.resolvers]);
this.schemas = [...this.schemas, ...func.schemas];
} else if (func instanceof Function) {
this.middlewares.push(func);
} else {
throw Error('use() expects an instance of Function or Router');
}
return this;
}
query(route, resolver) {
const { Query } = this.RESOLVER_TYPES;
if (!this.resolvers[Query]) {
this.resolvers[Query] = {};
}
return this.useResolver(route, resolver, Query);
}
mutation(route, resolver) {
const { Mutation } = this.RESOLVER_TYPES;
if (!this.resolvers[Mutation]) {
this.resolvers[Mutation] = {};
}
return this.useResolver(route, resolver, Mutation);
}
subscription(route, resolver) {
const { Subscription } = this.RESOLVER_TYPES;
if (!this.resolvers[Subscription]) {
this.resolvers[Subscription] = {};
}
return this.useResolver(route, resolver, Subscription);
}
useResolver(route, resolver, type) {
const name = route.replace('/', '');
if (this.resolvers[type][name]) {
throw Error(`Cannot declare duplicate resolver name: ${name}`);
}
const { Subscription } = this.RESOLVER_TYPES;
this.resolvers[type][name] =
type === Subscription
? resolver
: (parent, args, context, info) =>
new Promise(resolve =>
resolver({ body: args, context }, { send: resolve })
);
return this;
}
useSchema(schema) {
this.schemas.push(schema);
return this;
}
}
class GraphQLess extends Router {
constructor(config = { options: {} }) {
super();
this.express = express();
const { options, ...rest } = config;
this.configApolloServer = rest;
this.options = {
endpoint: '/graphql',
playground: true,
mergeTypes: { all: true },
...options,
};
}
listen(...argsListen) {
const server = new ApolloServer({
typeDefs: gql(mergeTypes(this.schemas, this.options.mergeTypes)),
resolvers: this.resolvers,
playground: this.options.playground,
...this.configApolloServer,
});
this.middlewares.forEach(middleware => {
this.express.use(this.options.endpoint, middleware);
});
server.applyMiddleware({ app: this.express, path: this.options.endpoint });
const { Subscription } = this.RESOLVER_TYPES;
const hasSubscriptions = this.resolvers[Subscription];
if (hasSubscriptions) {
const httpServer = http.createServer(this.express);
server.installSubscriptionHandlers(httpServer);
return httpServer.listen(...argsListen);
}
return this.express.listen(...argsListen);
}
}
module.exports = {
GraphQLess,
Router,
ApolloServerExpress,
express,
};