UNPKG

10.3 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.printSchema = printSchema;
7exports.printIntrospectionSchema = printIntrospectionSchema;
8exports.printType = printType;
9
10var _objectValues = _interopRequireDefault(require("../polyfills/objectValues"));
11
12var _isNullish = _interopRequireDefault(require("../jsutils/isNullish"));
13
14var _isInvalid = _interopRequireDefault(require("../jsutils/isInvalid"));
15
16var _astFromValue = require("../utilities/astFromValue");
17
18var _printer = require("../language/printer");
19
20var _definition = require("../type/definition");
21
22var _scalars = require("../type/scalars");
23
24var _directives = require("../type/directives");
25
26var _introspection = require("../type/introspection");
27
28function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
30/**
31 * Copyright (c) 2015-present, Facebook, Inc.
32 *
33 * This source code is licensed under the MIT license found in the
34 * LICENSE file in the root directory of this source tree.
35 *
36 *
37 */
38
39/**
40 * Accepts options as a second argument:
41 *
42 * - commentDescriptions:
43 * Provide true to use preceding comments as the description.
44 *
45 */
46function printSchema(schema, options) {
47 return printFilteredSchema(schema, function (n) {
48 return !(0, _directives.isSpecifiedDirective)(n);
49 }, isDefinedType, options);
50}
51
52function printIntrospectionSchema(schema, options) {
53 return printFilteredSchema(schema, _directives.isSpecifiedDirective, _introspection.isIntrospectionType, options);
54}
55
56function isDefinedType(type) {
57 return !(0, _scalars.isSpecifiedScalarType)(type) && !(0, _introspection.isIntrospectionType)(type);
58}
59
60function printFilteredSchema(schema, directiveFilter, typeFilter, options) {
61 var directives = schema.getDirectives().filter(directiveFilter);
62 var typeMap = schema.getTypeMap();
63 var types = (0, _objectValues.default)(typeMap).sort(function (type1, type2) {
64 return type1.name.localeCompare(type2.name);
65 }).filter(typeFilter);
66 return [printSchemaDefinition(schema)].concat(directives.map(function (directive) {
67 return printDirective(directive, options);
68 }), types.map(function (type) {
69 return printType(type, options);
70 })).filter(Boolean).join('\n\n') + '\n';
71}
72
73function printSchemaDefinition(schema) {
74 if (isSchemaOfCommonNames(schema)) {
75 return;
76 }
77
78 var operationTypes = [];
79 var queryType = schema.getQueryType();
80
81 if (queryType) {
82 operationTypes.push(" query: ".concat(queryType.name));
83 }
84
85 var mutationType = schema.getMutationType();
86
87 if (mutationType) {
88 operationTypes.push(" mutation: ".concat(mutationType.name));
89 }
90
91 var subscriptionType = schema.getSubscriptionType();
92
93 if (subscriptionType) {
94 operationTypes.push(" subscription: ".concat(subscriptionType.name));
95 }
96
97 return "schema {\n".concat(operationTypes.join('\n'), "\n}");
98}
99/**
100 * GraphQL schema define root types for each type of operation. These types are
101 * the same as any other type and can be named in any manner, however there is
102 * a common naming convention:
103 *
104 * schema {
105 * query: Query
106 * mutation: Mutation
107 * }
108 *
109 * When using this naming convention, the schema description can be omitted.
110 */
111
112
113function isSchemaOfCommonNames(schema) {
114 var queryType = schema.getQueryType();
115
116 if (queryType && queryType.name !== 'Query') {
117 return false;
118 }
119
120 var mutationType = schema.getMutationType();
121
122 if (mutationType && mutationType.name !== 'Mutation') {
123 return false;
124 }
125
126 var subscriptionType = schema.getSubscriptionType();
127
128 if (subscriptionType && subscriptionType.name !== 'Subscription') {
129 return false;
130 }
131
132 return true;
133}
134
135function printType(type, options) {
136 if ((0, _definition.isScalarType)(type)) {
137 return printScalar(type, options);
138 } else if ((0, _definition.isObjectType)(type)) {
139 return printObject(type, options);
140 } else if ((0, _definition.isInterfaceType)(type)) {
141 return printInterface(type, options);
142 } else if ((0, _definition.isUnionType)(type)) {
143 return printUnion(type, options);
144 } else if ((0, _definition.isEnumType)(type)) {
145 return printEnum(type, options);
146 } else if ((0, _definition.isInputObjectType)(type)) {
147 return printInputObject(type, options);
148 }
149 /* istanbul ignore next */
150
151
152 throw new Error("Unknown type: ".concat(type, "."));
153}
154
155function printScalar(type, options) {
156 return printDescription(options, type) + "scalar ".concat(type.name);
157}
158
159function printObject(type, options) {
160 var interfaces = type.getInterfaces();
161 var implementedInterfaces = interfaces.length ? ' implements ' + interfaces.map(function (i) {
162 return i.name;
163 }).join(' & ') : '';
164 return printDescription(options, type) + "type ".concat(type.name).concat(implementedInterfaces, " {\n") + printFields(options, type) + '\n' + '}';
165}
166
167function printInterface(type, options) {
168 return printDescription(options, type) + "interface ".concat(type.name, " {\n") + printFields(options, type) + '\n' + '}';
169}
170
171function printUnion(type, options) {
172 return printDescription(options, type) + "union ".concat(type.name, " = ").concat(type.getTypes().join(' | '));
173}
174
175function printEnum(type, options) {
176 return printDescription(options, type) + "enum ".concat(type.name, " {\n") + printEnumValues(type.getValues(), options) + '\n' + '}';
177}
178
179function printEnumValues(values, options) {
180 return values.map(function (value, i) {
181 return printDescription(options, value, ' ', !i) + ' ' + value.name + printDeprecated(value);
182 }).join('\n');
183}
184
185function printInputObject(type, options) {
186 var fields = (0, _objectValues.default)(type.getFields());
187 return printDescription(options, type) + "input ".concat(type.name, " {\n") + fields.map(function (f, i) {
188 return printDescription(options, f, ' ', !i) + ' ' + printInputValue(f);
189 }).join('\n') + '\n' + '}';
190}
191
192function printFields(options, type) {
193 var fields = (0, _objectValues.default)(type.getFields());
194 return fields.map(function (f, i) {
195 return printDescription(options, f, ' ', !i) + ' ' + f.name + printArgs(options, f.args, ' ') + ': ' + String(f.type) + printDeprecated(f);
196 }).join('\n');
197}
198
199function printArgs(options, args) {
200 var indentation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
201
202 if (args.length === 0) {
203 return '';
204 } // If every arg does not have a description, print them on one line.
205
206
207 if (args.every(function (arg) {
208 return !arg.description;
209 })) {
210 return '(' + args.map(printInputValue).join(', ') + ')';
211 }
212
213 return '(\n' + args.map(function (arg, i) {
214 return printDescription(options, arg, ' ' + indentation, !i) + ' ' + indentation + printInputValue(arg);
215 }).join('\n') + '\n' + indentation + ')';
216}
217
218function printInputValue(arg) {
219 var argDecl = arg.name + ': ' + String(arg.type);
220
221 if (!(0, _isInvalid.default)(arg.defaultValue)) {
222 argDecl += " = ".concat((0, _printer.print)((0, _astFromValue.astFromValue)(arg.defaultValue, arg.type)));
223 }
224
225 return argDecl;
226}
227
228function printDirective(directive, options) {
229 return printDescription(options, directive) + 'directive @' + directive.name + printArgs(options, directive.args) + ' on ' + directive.locations.join(' | ');
230}
231
232function printDeprecated(fieldOrEnumVal) {
233 if (!fieldOrEnumVal.isDeprecated) {
234 return '';
235 }
236
237 var reason = fieldOrEnumVal.deprecationReason;
238
239 if ((0, _isNullish.default)(reason) || reason === '' || reason === _directives.DEFAULT_DEPRECATION_REASON) {
240 return ' @deprecated';
241 }
242
243 return ' @deprecated(reason: ' + (0, _printer.print)((0, _astFromValue.astFromValue)(reason, _scalars.GraphQLString)) + ')';
244}
245
246function printDescription(options, def) {
247 var indentation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
248 var firstInBlock = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
249
250 if (!def.description) {
251 return '';
252 }
253
254 var lines = descriptionLines(def.description, 120 - indentation.length);
255
256 if (options && options.commentDescriptions) {
257 return printDescriptionWithComments(lines, indentation, firstInBlock);
258 }
259
260 var description = indentation && !firstInBlock ? '\n' + indentation + '"""' : indentation + '"""'; // In some circumstances, a single line can be used for the description.
261
262 if (lines.length === 1 && lines[0].length < 70 && lines[0][lines[0].length - 1] !== '"') {
263 return description + escapeQuote(lines[0]) + '"""\n';
264 } // Format a multi-line block quote to account for leading space.
265
266
267 var hasLeadingSpace = lines[0][0] === ' ' || lines[0][0] === '\t';
268
269 if (!hasLeadingSpace) {
270 description += '\n';
271 }
272
273 for (var i = 0; i < lines.length; i++) {
274 if (i !== 0 || !hasLeadingSpace) {
275 description += indentation;
276 }
277
278 description += escapeQuote(lines[i]) + '\n';
279 }
280
281 description += indentation + '"""\n';
282 return description;
283}
284
285function escapeQuote(line) {
286 return line.replace(/"""/g, '\\"""');
287}
288
289function printDescriptionWithComments(lines, indentation, firstInBlock) {
290 var description = indentation && !firstInBlock ? '\n' : '';
291
292 for (var i = 0; i < lines.length; i++) {
293 if (lines[i] === '') {
294 description += indentation + '#\n';
295 } else {
296 description += indentation + '# ' + lines[i] + '\n';
297 }
298 }
299
300 return description;
301}
302
303function descriptionLines(description, maxLen) {
304 var lines = [];
305 var rawLines = description.split('\n');
306
307 for (var i = 0; i < rawLines.length; i++) {
308 if (rawLines[i] === '') {
309 lines.push(rawLines[i]);
310 } else {
311 // For > 120 character long lines, cut at space boundaries into sublines
312 // of ~80 chars.
313 var sublines = breakLine(rawLines[i], maxLen);
314
315 for (var j = 0; j < sublines.length; j++) {
316 lines.push(sublines[j]);
317 }
318 }
319 }
320
321 return lines;
322}
323
324function breakLine(line, maxLen) {
325 if (line.length < maxLen + 5) {
326 return [line];
327 }
328
329 var parts = line.split(new RegExp("((?: |^).{15,".concat(maxLen - 40, "}(?= |$))")));
330
331 if (parts.length < 4) {
332 return [line];
333 }
334
335 var sublines = [parts[0] + parts[1] + parts[2]];
336
337 for (var i = 3; i < parts.length; i += 2) {
338 sublines.push(parts[i].slice(1) + parts[i + 1]);
339 }
340
341 return sublines;
342}
\No newline at end of file