1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true,
|
5 | });
|
6 | exports.printIntrospectionSchema = printIntrospectionSchema;
|
7 | exports.printSchema = printSchema;
|
8 | exports.printType = printType;
|
9 |
|
10 | var _inspect = require('../jsutils/inspect.js');
|
11 |
|
12 | var _invariant = require('../jsutils/invariant.js');
|
13 |
|
14 | var _blockString = require('../language/blockString.js');
|
15 |
|
16 | var _kinds = require('../language/kinds.js');
|
17 |
|
18 | var _printer = require('../language/printer.js');
|
19 |
|
20 | var _definition = require('../type/definition.js');
|
21 |
|
22 | var _directives = require('../type/directives.js');
|
23 |
|
24 | var _introspection = require('../type/introspection.js');
|
25 |
|
26 | var _scalars = require('../type/scalars.js');
|
27 |
|
28 | var _astFromValue = require('./astFromValue.js');
|
29 |
|
30 | function printSchema(schema) {
|
31 | return printFilteredSchema(
|
32 | schema,
|
33 | (n) => !(0, _directives.isSpecifiedDirective)(n),
|
34 | isDefinedType,
|
35 | );
|
36 | }
|
37 |
|
38 | function printIntrospectionSchema(schema) {
|
39 | return printFilteredSchema(
|
40 | schema,
|
41 | _directives.isSpecifiedDirective,
|
42 | _introspection.isIntrospectionType,
|
43 | );
|
44 | }
|
45 |
|
46 | function isDefinedType(type) {
|
47 | return (
|
48 | !(0, _scalars.isSpecifiedScalarType)(type) &&
|
49 | !(0, _introspection.isIntrospectionType)(type)
|
50 | );
|
51 | }
|
52 |
|
53 | function printFilteredSchema(schema, directiveFilter, typeFilter) {
|
54 | const directives = schema.getDirectives().filter(directiveFilter);
|
55 | const types = Object.values(schema.getTypeMap()).filter(typeFilter);
|
56 | return [
|
57 | printSchemaDefinition(schema),
|
58 | ...directives.map((directive) => printDirective(directive)),
|
59 | ...types.map((type) => printType(type)),
|
60 | ]
|
61 | .filter(Boolean)
|
62 | .join('\n\n');
|
63 | }
|
64 |
|
65 | function printSchemaDefinition(schema) {
|
66 | if (schema.description == null && isSchemaOfCommonNames(schema)) {
|
67 | return;
|
68 | }
|
69 |
|
70 | const operationTypes = [];
|
71 | const queryType = schema.getQueryType();
|
72 |
|
73 | if (queryType) {
|
74 | operationTypes.push(` query: ${queryType.name}`);
|
75 | }
|
76 |
|
77 | const mutationType = schema.getMutationType();
|
78 |
|
79 | if (mutationType) {
|
80 | operationTypes.push(` mutation: ${mutationType.name}`);
|
81 | }
|
82 |
|
83 | const subscriptionType = schema.getSubscriptionType();
|
84 |
|
85 | if (subscriptionType) {
|
86 | operationTypes.push(` subscription: ${subscriptionType.name}`);
|
87 | }
|
88 |
|
89 | return printDescription(schema) + `schema {\n${operationTypes.join('\n')}\n}`;
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | function isSchemaOfCommonNames(schema) {
|
108 | const queryType = schema.getQueryType();
|
109 |
|
110 | if (queryType && queryType.name !== 'Query') {
|
111 | return false;
|
112 | }
|
113 |
|
114 | const mutationType = schema.getMutationType();
|
115 |
|
116 | if (mutationType && mutationType.name !== 'Mutation') {
|
117 | return false;
|
118 | }
|
119 |
|
120 | const subscriptionType = schema.getSubscriptionType();
|
121 |
|
122 | if (subscriptionType && subscriptionType.name !== 'Subscription') {
|
123 | return false;
|
124 | }
|
125 |
|
126 | return true;
|
127 | }
|
128 |
|
129 | function printType(type) {
|
130 | if ((0, _definition.isScalarType)(type)) {
|
131 | return printScalar(type);
|
132 | }
|
133 |
|
134 | if ((0, _definition.isObjectType)(type)) {
|
135 | return printObject(type);
|
136 | }
|
137 |
|
138 | if ((0, _definition.isInterfaceType)(type)) {
|
139 | return printInterface(type);
|
140 | }
|
141 |
|
142 | if ((0, _definition.isUnionType)(type)) {
|
143 | return printUnion(type);
|
144 | }
|
145 |
|
146 | if ((0, _definition.isEnumType)(type)) {
|
147 | return printEnum(type);
|
148 | }
|
149 |
|
150 | if ((0, _definition.isInputObjectType)(type)) {
|
151 | return printInputObject(type);
|
152 | }
|
153 |
|
154 |
|
155 |
|
156 | false ||
|
157 | (0, _invariant.invariant)(
|
158 | false,
|
159 | 'Unexpected type: ' + (0, _inspect.inspect)(type),
|
160 | );
|
161 | }
|
162 |
|
163 | function printScalar(type) {
|
164 | return (
|
165 | printDescription(type) + `scalar ${type.name}` + printSpecifiedByURL(type)
|
166 | );
|
167 | }
|
168 |
|
169 | function printImplementedInterfaces(type) {
|
170 | const interfaces = type.getInterfaces();
|
171 | return interfaces.length
|
172 | ? ' implements ' + interfaces.map((i) => i.name).join(' & ')
|
173 | : '';
|
174 | }
|
175 |
|
176 | function printObject(type) {
|
177 | return (
|
178 | printDescription(type) +
|
179 | `type ${type.name}` +
|
180 | printImplementedInterfaces(type) +
|
181 | printFields(type)
|
182 | );
|
183 | }
|
184 |
|
185 | function printInterface(type) {
|
186 | return (
|
187 | printDescription(type) +
|
188 | `interface ${type.name}` +
|
189 | printImplementedInterfaces(type) +
|
190 | printFields(type)
|
191 | );
|
192 | }
|
193 |
|
194 | function printUnion(type) {
|
195 | const types = type.getTypes();
|
196 | const possibleTypes = types.length ? ' = ' + types.join(' | ') : '';
|
197 | return printDescription(type) + 'union ' + type.name + possibleTypes;
|
198 | }
|
199 |
|
200 | function printEnum(type) {
|
201 | const values = type
|
202 | .getValues()
|
203 | .map(
|
204 | (value, i) =>
|
205 | printDescription(value, ' ', !i) +
|
206 | ' ' +
|
207 | value.name +
|
208 | printDeprecated(value.deprecationReason),
|
209 | );
|
210 | return printDescription(type) + `enum ${type.name}` + printBlock(values);
|
211 | }
|
212 |
|
213 | function printInputObject(type) {
|
214 | const fields = Object.values(type.getFields()).map(
|
215 | (f, i) => printDescription(f, ' ', !i) + ' ' + printInputValue(f),
|
216 | );
|
217 | return printDescription(type) + `input ${type.name}` + printBlock(fields);
|
218 | }
|
219 |
|
220 | function printFields(type) {
|
221 | const fields = Object.values(type.getFields()).map(
|
222 | (f, i) =>
|
223 | printDescription(f, ' ', !i) +
|
224 | ' ' +
|
225 | f.name +
|
226 | printArgs(f.args, ' ') +
|
227 | ': ' +
|
228 | String(f.type) +
|
229 | printDeprecated(f.deprecationReason),
|
230 | );
|
231 | return printBlock(fields);
|
232 | }
|
233 |
|
234 | function printBlock(items) {
|
235 | return items.length !== 0 ? ' {\n' + items.join('\n') + '\n}' : '';
|
236 | }
|
237 |
|
238 | function printArgs(args, indentation = '') {
|
239 | if (args.length === 0) {
|
240 | return '';
|
241 | }
|
242 |
|
243 | if (args.every((arg) => !arg.description)) {
|
244 | return '(' + args.map(printInputValue).join(', ') + ')';
|
245 | }
|
246 |
|
247 | return (
|
248 | '(\n' +
|
249 | args
|
250 | .map(
|
251 | (arg, i) =>
|
252 | printDescription(arg, ' ' + indentation, !i) +
|
253 | ' ' +
|
254 | indentation +
|
255 | printInputValue(arg),
|
256 | )
|
257 | .join('\n') +
|
258 | '\n' +
|
259 | indentation +
|
260 | ')'
|
261 | );
|
262 | }
|
263 |
|
264 | function printInputValue(arg) {
|
265 | const defaultAST = (0, _astFromValue.astFromValue)(
|
266 | arg.defaultValue,
|
267 | arg.type,
|
268 | );
|
269 | let argDecl = arg.name + ': ' + String(arg.type);
|
270 |
|
271 | if (defaultAST) {
|
272 | argDecl += ` = ${(0, _printer.print)(defaultAST)}`;
|
273 | }
|
274 |
|
275 | return argDecl + printDeprecated(arg.deprecationReason);
|
276 | }
|
277 |
|
278 | function printDirective(directive) {
|
279 | return (
|
280 | printDescription(directive) +
|
281 | 'directive @' +
|
282 | directive.name +
|
283 | printArgs(directive.args) +
|
284 | (directive.isRepeatable ? ' repeatable' : '') +
|
285 | ' on ' +
|
286 | directive.locations.join(' | ')
|
287 | );
|
288 | }
|
289 |
|
290 | function printDeprecated(reason) {
|
291 | if (reason == null) {
|
292 | return '';
|
293 | }
|
294 |
|
295 | if (reason !== _directives.DEFAULT_DEPRECATION_REASON) {
|
296 | const astValue = (0, _printer.print)({
|
297 | kind: _kinds.Kind.STRING,
|
298 | value: reason,
|
299 | });
|
300 | return ` @deprecated(reason: ${astValue})`;
|
301 | }
|
302 |
|
303 | return ' @deprecated';
|
304 | }
|
305 |
|
306 | function printSpecifiedByURL(scalar) {
|
307 | if (scalar.specifiedByURL == null) {
|
308 | return '';
|
309 | }
|
310 |
|
311 | const astValue = (0, _printer.print)({
|
312 | kind: _kinds.Kind.STRING,
|
313 | value: scalar.specifiedByURL,
|
314 | });
|
315 | return ` @specifiedBy(url: ${astValue})`;
|
316 | }
|
317 |
|
318 | function printDescription(def, indentation = '', firstInBlock = true) {
|
319 | const { description } = def;
|
320 |
|
321 | if (description == null) {
|
322 | return '';
|
323 | }
|
324 |
|
325 | const blockString = (0, _printer.print)({
|
326 | kind: _kinds.Kind.STRING,
|
327 | value: description,
|
328 | block: (0, _blockString.isPrintableAsBlockString)(description),
|
329 | });
|
330 | const prefix =
|
331 | indentation && !firstInBlock ? '\n' + indentation : indentation;
|
332 | return prefix + blockString.replace(/\n/g, '\n' + indentation) + '\n';
|
333 | }
|