-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathgraphql-loader.js
116 lines (110 loc) · 3.18 KB
/
graphql-loader.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
'use strict';
const { join, dirname } = require('path');
const { merge, isFunction } = require('lodash');
const is = require('is-type-of');
const {
makeExecutableSchema,
SchemaDirectiveVisitor,
} = require('graphql-tools');
const SYMBOL_SCHEMA = Symbol('Application#schema');
const SYMBOL_CONNECTOR_CLASS = Symbol('Application#connectorClass');
module.exports = app => {
const directiveResolvers = {};
const schemaDirectives = {};
const resolvers = {};
const typeDefs = [];
class GraphqlLoader {
constructor(app) {
this.app = app;
}
load() {
const connectorClasses = new Map();
this.loadGraphql(connectorClasses);
this.loadTypeDefs();
/**
* create a GraphQL.js GraphQLSchema instance
*/
Object.defineProperties(this.app, {
schema: {
get() {
if (!this[SYMBOL_SCHEMA]) {
this[SYMBOL_SCHEMA] = makeExecutableSchema({
typeDefs,
resolvers,
directiveResolvers,
schemaDirectives,
});
}
return this[SYMBOL_SCHEMA];
},
},
connectorClass: {
get() {
if (!this[SYMBOL_CONNECTOR_CLASS]) {
this[SYMBOL_CONNECTOR_CLASS] = connectorClasses;
}
return this[SYMBOL_CONNECTOR_CLASS];
},
},
});
}
// 加载graphql
loadGraphql(connectorClasses) {
const loader = this.app.loader;
loader.timing.start('Loader Graphql');
const opt = {
caseStyle: 'lower',
directory: join(this.app.baseDir, 'app/graphql'),
target: {},
initializer: (obj, opt) => {
const pathName = opt.pathName.split('.').pop();
// 加载resolver
if (pathName === 'resolver') {
if (isFunction(obj)) {
obj = obj(this.app);
}
merge(resolvers, obj);
}
// load schemaDirective
if (is.class(obj)) {
const proto = Object.getPrototypeOf(obj);
if (proto === SchemaDirectiveVisitor) {
const name = opt.pathName.split('.').pop();
schemaDirectives[name] = obj;
}
}
if (pathName === 'schemaDirective') {
merge(schemaDirectives, obj);
}
// load directiveResolver
if (pathName === 'directive') {
merge(directiveResolvers, obj);
}
// load connector
if (pathName === 'connector') {
// 获取文件目录名
const type = dirname(opt.path)
.split(/\/|\\/)
.pop();
connectorClasses.set(type, obj);
}
},
};
new this.app.loader.FileLoader(opt).load();
loader.timing.end('Loader Graphql');
}
// 加载typeDefs
loadTypeDefs() {
const opt = {
directory: join(this.app.baseDir, 'app/graphql'),
match: '**/*.graphql',
target: {},
initializer: obj => {
typeDefs.push(obj.toString('utf8'));
},
};
new this.app.loader.FileLoader(opt).load();
}
}
new GraphqlLoader(app).load();
};