UNPKG

5.93 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 *
8 * @format
9 */
10'use strict';
11
12function convertASTDocuments(schema, documents, validationRules, transform) {
13 return require("./GraphQLCompilerProfiler").run('ASTConvert.convertASTDocuments', function () {
14 var definitions = definitionsFromDocuments(documents);
15 var astDefinitions = [];
16 documents.forEach(function (doc) {
17 doc.definitions.forEach(function (definition) {
18 if (require("./GraphQLSchemaUtils").isExecutableDefinitionAST(definition)) {
19 astDefinitions.push(definition);
20 }
21 });
22 });
23 return convertASTDefinitions(schema, definitions, validationRules, transform);
24 });
25}
26
27function convertASTDocumentsWithBase(schema, baseDocuments, documents, validationRules, transform) {
28 return require("./GraphQLCompilerProfiler").run('ASTConvert.convertASTDocumentsWithBase', function () {
29 var baseDefinitions = definitionsFromDocuments(baseDocuments);
30 var definitions = definitionsFromDocuments(documents);
31 var requiredDefinitions = new Map();
32 var baseMap = new Map();
33 baseDefinitions.forEach(function (definition) {
34 if (require("./GraphQLSchemaUtils").isExecutableDefinitionAST(definition)) {
35 var definitionName = definition.name && definition.name.value; // If there's no name, no reason to put in the map
36
37 if (definitionName) {
38 if (baseMap.has(definitionName)) {
39 throw new Error("Duplicate definition of '".concat(definitionName, "'."));
40 }
41
42 baseMap.set(definitionName, definition);
43 }
44 }
45 });
46 var definitionsToVisit = [];
47 definitions.forEach(function (definition) {
48 if (require("./GraphQLSchemaUtils").isExecutableDefinitionAST(definition)) {
49 definitionsToVisit.push(definition);
50 }
51 });
52
53 while (definitionsToVisit.length > 0) {
54 var definition = definitionsToVisit.pop();
55 var name = definition.name && definition.name.value;
56
57 if (!name) {
58 continue;
59 }
60
61 if (requiredDefinitions.has(name)) {
62 if (requiredDefinitions.get(name) !== definition) {
63 throw new Error("Duplicate definition of '".concat(name, "'."));
64 }
65
66 continue;
67 }
68
69 requiredDefinitions.set(name, definition);
70
71 require("graphql").visit(definition, {
72 FragmentSpread: function FragmentSpread(spread) {
73 var baseDefinition = baseMap.get(spread.name.value);
74
75 if (baseDefinition) {
76 // We only need to add those definitions not already included
77 // in definitions
78 definitionsToVisit.push(baseDefinition);
79 }
80 }
81 });
82 }
83
84 var definitionsToConvert = [];
85 requiredDefinitions.forEach(function (definition) {
86 return definitionsToConvert.push(definition);
87 });
88 return convertASTDefinitions(schema, definitionsToConvert, validationRules, transform);
89 });
90}
91
92function convertASTDefinitions(schema, definitions, validationRules, transform) {
93 var operationDefinitions = [];
94 definitions.forEach(function (definition) {
95 if (require("./GraphQLSchemaUtils").isExecutableDefinitionAST(definition)) {
96 operationDefinitions.push(definition);
97 }
98 });
99 var validationAST = {
100 kind: 'Document',
101 definitions: operationDefinitions
102 }; // Will throw an error if there are validation issues
103
104 require("./GraphQLValidator").validate(validationAST, schema, validationRules);
105
106 return transform(schema, operationDefinitions);
107}
108
109function definitionsFromDocuments(documents) {
110 var definitions = [];
111 documents.forEach(function (doc) {
112 doc.definitions.forEach(function (definition) {
113 return definitions.push(definition);
114 });
115 });
116 return definitions;
117}
118/**
119 * Extends a GraphQLSchema with a list of schema extensions in string form.
120 */
121
122
123function transformASTSchema(schema, schemaExtensions) {
124 return require("./GraphQLCompilerProfiler").run('ASTConvert.transformASTSchema', function () {
125 if (schemaExtensions.length === 0) {
126 return schema;
127 }
128
129 var extension = schemaExtensions.join('\n');
130 return cachedExtend(schema, extension, function () {
131 return require("graphql").extendSchema(schema, require("graphql").parse(extension));
132 });
133 });
134}
135/**
136 * Extends a GraphQLSchema with a list of schema extensions in AST form.
137 */
138
139
140function extendASTSchema(baseSchema, documents) {
141 return require("./GraphQLCompilerProfiler").run('ASTConvert.extendASTSchema', function () {
142 var schemaExtensions = [];
143 documents.forEach(function (doc) {
144 doc.definitions.forEach(function (definition) {
145 if (require("./GraphQLSchemaUtils").isSchemaDefinitionAST(definition)) {
146 schemaExtensions.push(definition);
147 }
148 });
149 });
150
151 if (schemaExtensions.length === 0) {
152 return baseSchema;
153 }
154
155 var key = schemaExtensions.map(require("graphql").print).join('\n');
156 return cachedExtend(baseSchema, key, function () {
157 return require("graphql").extendSchema(baseSchema, {
158 kind: 'Document',
159 definitions: schemaExtensions
160 }, // TODO T24511737 figure out if this is dangerous
161 {
162 assumeValid: true
163 });
164 });
165 });
166}
167
168var extendedSchemas = new Map();
169
170function cachedExtend(schema, key, compute) {
171 var cache = extendedSchemas.get(schema);
172
173 if (!cache) {
174 cache = {};
175 extendedSchemas.set(schema, cache);
176 }
177
178 var extendedSchema = cache[key];
179
180 if (!extendedSchema) {
181 extendedSchema = compute();
182 cache[key] = extendedSchema;
183 }
184
185 return extendedSchema;
186}
187
188module.exports = {
189 convertASTDocuments: convertASTDocuments,
190 convertASTDocumentsWithBase: convertASTDocumentsWithBase,
191 extendASTSchema: extendASTSchema,
192 transformASTSchema: transformASTSchema
193};
\No newline at end of file