1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.extendSchema = extendSchema;
|
7 |
|
8 | var _invariant = require('../jsutils/invariant');
|
9 |
|
10 | var _invariant2 = _interopRequireDefault(_invariant);
|
11 |
|
12 | var _keyMap = require('../jsutils/keyMap');
|
13 |
|
14 | var _keyMap2 = _interopRequireDefault(_keyMap);
|
15 |
|
16 | var _buildASTSchema = require('./buildASTSchema');
|
17 |
|
18 | var _GraphQLError = require('../error/GraphQLError');
|
19 |
|
20 | var _schema = require('../type/schema');
|
21 |
|
22 | var _definition = require('../type/definition');
|
23 |
|
24 | var _wrappers = require('../type/wrappers');
|
25 |
|
26 | var _directives = require('../type/directives');
|
27 |
|
28 | var _kinds = require('../language/kinds');
|
29 |
|
30 | var Kind = _interopRequireWildcard(_kinds);
|
31 |
|
32 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
33 |
|
34 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | function extendSchema(schema, documentAST, options) {
|
55 | !(0, _schema.isSchema)(schema) ? (0, _invariant2.default)(0, 'Must provide valid GraphQLSchema') : void 0;
|
56 |
|
57 | !(documentAST && documentAST.kind === Kind.DOCUMENT) ? (0, _invariant2.default)(0, 'Must provide valid Document AST') : void 0;
|
58 |
|
59 |
|
60 | var typeDefinitionMap = Object.create(null);
|
61 | var typeExtensionsMap = Object.create(null);
|
62 |
|
63 |
|
64 |
|
65 | var directiveDefinitions = [];
|
66 |
|
67 | for (var i = 0; i < documentAST.definitions.length; i++) {
|
68 | var def = documentAST.definitions[i];
|
69 | switch (def.kind) {
|
70 | case Kind.OBJECT_TYPE_DEFINITION:
|
71 | case Kind.INTERFACE_TYPE_DEFINITION:
|
72 | case Kind.ENUM_TYPE_DEFINITION:
|
73 | case Kind.UNION_TYPE_DEFINITION:
|
74 | case Kind.SCALAR_TYPE_DEFINITION:
|
75 | case Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
76 |
|
77 |
|
78 | var typeName = def.name.value;
|
79 | if (schema.getType(typeName)) {
|
80 | throw new _GraphQLError.GraphQLError('Type "' + typeName + '" already exists in the schema. It cannot also ' + 'be defined in this type definition.', [def]);
|
81 | }
|
82 | typeDefinitionMap[typeName] = def;
|
83 | break;
|
84 | case Kind.OBJECT_TYPE_EXTENSION:
|
85 |
|
86 |
|
87 | var extendedTypeName = def.name.value;
|
88 | var existingType = schema.getType(extendedTypeName);
|
89 | if (!existingType) {
|
90 | throw new _GraphQLError.GraphQLError('Cannot extend type "' + extendedTypeName + '" because it does not ' + 'exist in the existing schema.', [def]);
|
91 | }
|
92 | if (!(0, _definition.isObjectType)(existingType)) {
|
93 | throw new _GraphQLError.GraphQLError('Cannot extend non-object type "' + extendedTypeName + '".', [def]);
|
94 | }
|
95 | var extensions = typeExtensionsMap[extendedTypeName];
|
96 | if (extensions) {
|
97 | extensions.push(def);
|
98 | } else {
|
99 | extensions = [def];
|
100 | }
|
101 | typeExtensionsMap[extendedTypeName] = extensions;
|
102 | break;
|
103 | case Kind.DIRECTIVE_DEFINITION:
|
104 | var directiveName = def.name.value;
|
105 | var existingDirective = schema.getDirective(directiveName);
|
106 | if (existingDirective) {
|
107 | throw new _GraphQLError.GraphQLError('Directive "' + directiveName + '" already exists in the schema. It ' + 'cannot be redefined.', [def]);
|
108 | }
|
109 | directiveDefinitions.push(def);
|
110 | break;
|
111 | case Kind.SCALAR_TYPE_EXTENSION:
|
112 | case Kind.INTERFACE_TYPE_EXTENSION:
|
113 | case Kind.UNION_TYPE_EXTENSION:
|
114 | case Kind.ENUM_TYPE_EXTENSION:
|
115 | case Kind.INPUT_OBJECT_TYPE_EXTENSION:
|
116 | throw new Error('The ' + def.kind + ' kind is not yet supported by extendSchema().');
|
117 | }
|
118 | }
|
119 |
|
120 |
|
121 |
|
122 | if (Object.keys(typeExtensionsMap).length === 0 && Object.keys(typeDefinitionMap).length === 0 && directiveDefinitions.length === 0) {
|
123 | return schema;
|
124 | }
|
125 |
|
126 | var definitionBuilder = new _buildASTSchema.ASTDefinitionBuilder(typeDefinitionMap, options, function (typeName, node) {
|
127 | var existingType = schema.getType(typeName);
|
128 | if (existingType) {
|
129 | return extendType(existingType);
|
130 | }
|
131 |
|
132 | if (node) {
|
133 | throw new _GraphQLError.GraphQLError('Unknown type: "' + typeName + '". Ensure that this type exists ' + 'either in the original schema, or is added in a type definition.', [node]);
|
134 | }
|
135 | throw (0, _GraphQLError.GraphQLError)('Missing type from schema');
|
136 | });
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 | var existingQueryType = schema.getQueryType();
|
143 | var queryType = existingQueryType ? definitionBuilder.buildType(existingQueryType.name) : null;
|
144 |
|
145 | var existingMutationType = schema.getMutationType();
|
146 | var mutationType = existingMutationType ? definitionBuilder.buildType(existingMutationType.name) : null;
|
147 |
|
148 | var existingSubscriptionType = schema.getSubscriptionType();
|
149 | var subscriptionType = existingSubscriptionType ? definitionBuilder.buildType(existingSubscriptionType.name) : null;
|
150 |
|
151 |
|
152 |
|
153 | var typeMap = schema.getTypeMap();
|
154 | var types = Object.keys(typeMap).map(function (typeName) {
|
155 | return definitionBuilder.buildType(typeName);
|
156 | });
|
157 |
|
158 |
|
159 | Object.keys(typeDefinitionMap).forEach(function (typeName) {
|
160 | types.push(definitionBuilder.buildType(typeName));
|
161 | });
|
162 |
|
163 |
|
164 | return new _schema.GraphQLSchema({
|
165 | query: queryType,
|
166 | mutation: mutationType,
|
167 | subscription: subscriptionType,
|
168 | types: types,
|
169 | directives: getMergedDirectives(),
|
170 | astNode: schema.astNode
|
171 | });
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | function getMergedDirectives() {
|
177 | var existingDirectives = schema.getDirectives();
|
178 | !existingDirectives ? (0, _invariant2.default)(0, 'schema must have default directives') : void 0;
|
179 |
|
180 | var newDirectives = directiveDefinitions.map(function (directiveNode) {
|
181 | return definitionBuilder.buildDirective(directiveNode);
|
182 | });
|
183 | return existingDirectives.concat(newDirectives);
|
184 | }
|
185 |
|
186 | function getTypeFromDef(typeDef) {
|
187 | var type = definitionBuilder.buildType(typeDef.name);
|
188 | return type;
|
189 | }
|
190 |
|
191 |
|
192 |
|
193 | function extendType(type) {
|
194 | if ((0, _definition.isObjectType)(type)) {
|
195 | return extendObjectType(type);
|
196 | }
|
197 | if ((0, _definition.isInterfaceType)(type)) {
|
198 | return extendInterfaceType(type);
|
199 | }
|
200 | if ((0, _definition.isUnionType)(type)) {
|
201 | return extendUnionType(type);
|
202 | }
|
203 | return type;
|
204 | }
|
205 |
|
206 | function extendObjectType(type) {
|
207 | var name = type.name;
|
208 | var extensionASTNodes = typeExtensionsMap[name] ? type.extensionASTNodes ? type.extensionASTNodes.concat(typeExtensionsMap[name]) : typeExtensionsMap[name] : type.extensionASTNodes;
|
209 | return new _definition.GraphQLObjectType({
|
210 | name: name,
|
211 | description: type.description,
|
212 | interfaces: function interfaces() {
|
213 | return extendImplementedInterfaces(type);
|
214 | },
|
215 | fields: function fields() {
|
216 | return extendFieldMap(type);
|
217 | },
|
218 | astNode: type.astNode,
|
219 | extensionASTNodes: extensionASTNodes,
|
220 | isTypeOf: type.isTypeOf
|
221 | });
|
222 | }
|
223 |
|
224 | function extendInterfaceType(type) {
|
225 | return new _definition.GraphQLInterfaceType({
|
226 | name: type.name,
|
227 | description: type.description,
|
228 | fields: function fields() {
|
229 | return extendFieldMap(type);
|
230 | },
|
231 | astNode: type.astNode,
|
232 | resolveType: type.resolveType
|
233 | });
|
234 | }
|
235 |
|
236 | function extendUnionType(type) {
|
237 | return new _definition.GraphQLUnionType({
|
238 | name: type.name,
|
239 | description: type.description,
|
240 | types: type.getTypes().map(getTypeFromDef),
|
241 | astNode: type.astNode,
|
242 | resolveType: type.resolveType
|
243 | });
|
244 | }
|
245 |
|
246 | function extendImplementedInterfaces(type) {
|
247 | var interfaces = type.getInterfaces().map(getTypeFromDef);
|
248 |
|
249 |
|
250 | var extensions = typeExtensionsMap[type.name];
|
251 | if (extensions) {
|
252 | extensions.forEach(function (extension) {
|
253 | extension.interfaces.forEach(function (namedType) {
|
254 |
|
255 |
|
256 |
|
257 | interfaces.push(definitionBuilder.buildType(namedType));
|
258 | });
|
259 | });
|
260 | }
|
261 |
|
262 | return interfaces;
|
263 | }
|
264 |
|
265 | function extendFieldMap(type) {
|
266 | var newFieldMap = Object.create(null);
|
267 | var oldFieldMap = type.getFields();
|
268 | Object.keys(oldFieldMap).forEach(function (fieldName) {
|
269 | var field = oldFieldMap[fieldName];
|
270 | newFieldMap[fieldName] = {
|
271 | description: field.description,
|
272 | deprecationReason: field.deprecationReason,
|
273 | type: extendFieldType(field.type),
|
274 | args: (0, _keyMap2.default)(field.args, function (arg) {
|
275 | return arg.name;
|
276 | }),
|
277 | astNode: field.astNode,
|
278 | resolve: field.resolve
|
279 | };
|
280 | });
|
281 |
|
282 |
|
283 | var extensions = typeExtensionsMap[type.name];
|
284 | if (extensions) {
|
285 | extensions.forEach(function (extension) {
|
286 | extension.fields.forEach(function (field) {
|
287 | var fieldName = field.name.value;
|
288 | if (oldFieldMap[fieldName]) {
|
289 | throw new _GraphQLError.GraphQLError('Field "' + type.name + '.' + fieldName + '" already exists in the ' + 'schema. It cannot also be defined in this type extension.', [field]);
|
290 | }
|
291 | newFieldMap[fieldName] = definitionBuilder.buildField(field);
|
292 | });
|
293 | });
|
294 | }
|
295 |
|
296 | return newFieldMap;
|
297 | }
|
298 |
|
299 | function extendFieldType(typeDef) {
|
300 | if ((0, _definition.isListType)(typeDef)) {
|
301 | return (0, _wrappers.GraphQLList)(extendFieldType(typeDef.ofType));
|
302 | }
|
303 | if ((0, _definition.isNonNullType)(typeDef)) {
|
304 | return (0, _wrappers.GraphQLNonNull)(extendFieldType(typeDef.ofType));
|
305 | }
|
306 | return getTypeFromDef(typeDef);
|
307 | }
|
308 | } |
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
\ | No newline at end of file |