UNPKG

11.6 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.print = print;
7
8var _visitor = require("./visitor.js");
9
10var _blockString = require("./blockString.js");
11
12/**
13 * Converts an AST into a string, using one set of reasonable
14 * formatting rules.
15 */
16function print(ast) {
17 return (0, _visitor.visit)(ast, {
18 leave: printDocASTReducer
19 });
20}
21
22var MAX_LINE_LENGTH = 80; // TODO: provide better type coverage in future
23
24var printDocASTReducer = {
25 Name: function Name(node) {
26 return node.value;
27 },
28 Variable: function Variable(node) {
29 return '$' + node.name;
30 },
31 // Document
32 Document: function Document(node) {
33 return join(node.definitions, '\n\n') + '\n';
34 },
35 OperationDefinition: function OperationDefinition(node) {
36 var op = node.operation;
37 var name = node.name;
38 var varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
39 var directives = join(node.directives, ' ');
40 var selectionSet = node.selectionSet; // Anonymous queries with no directives or variable definitions can use
41 // the query short form.
42
43 return !name && !directives && !varDefs && op === 'query' ? selectionSet : join([op, join([name, varDefs]), directives, selectionSet], ' ');
44 },
45 VariableDefinition: function VariableDefinition(_ref) {
46 var variable = _ref.variable,
47 type = _ref.type,
48 defaultValue = _ref.defaultValue,
49 directives = _ref.directives;
50 return variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' '));
51 },
52 SelectionSet: function SelectionSet(_ref2) {
53 var selections = _ref2.selections;
54 return block(selections);
55 },
56 Field: function Field(_ref3) {
57 var alias = _ref3.alias,
58 name = _ref3.name,
59 args = _ref3.arguments,
60 directives = _ref3.directives,
61 selectionSet = _ref3.selectionSet;
62 var prefix = wrap('', alias, ': ') + name;
63 var argsLine = prefix + wrap('(', join(args, ', '), ')');
64
65 if (argsLine.length > MAX_LINE_LENGTH) {
66 argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
67 }
68
69 return join([argsLine, join(directives, ' '), selectionSet], ' ');
70 },
71 Argument: function Argument(_ref4) {
72 var name = _ref4.name,
73 value = _ref4.value;
74 return name + ': ' + value;
75 },
76 // Fragments
77 FragmentSpread: function FragmentSpread(_ref5) {
78 var name = _ref5.name,
79 directives = _ref5.directives;
80 return '...' + name + wrap(' ', join(directives, ' '));
81 },
82 InlineFragment: function InlineFragment(_ref6) {
83 var typeCondition = _ref6.typeCondition,
84 directives = _ref6.directives,
85 selectionSet = _ref6.selectionSet;
86 return join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' ');
87 },
88 FragmentDefinition: function FragmentDefinition(_ref7) {
89 var name = _ref7.name,
90 typeCondition = _ref7.typeCondition,
91 variableDefinitions = _ref7.variableDefinitions,
92 directives = _ref7.directives,
93 selectionSet = _ref7.selectionSet;
94 return (// Note: fragment variable definitions are experimental and may be changed
95 // or removed in the future.
96 "fragment ".concat(name).concat(wrap('(', join(variableDefinitions, ', '), ')'), " ") + "on ".concat(typeCondition, " ").concat(wrap('', join(directives, ' '), ' ')) + selectionSet
97 );
98 },
99 // Value
100 IntValue: function IntValue(_ref8) {
101 var value = _ref8.value;
102 return value;
103 },
104 FloatValue: function FloatValue(_ref9) {
105 var value = _ref9.value;
106 return value;
107 },
108 StringValue: function StringValue(_ref10, key) {
109 var value = _ref10.value,
110 isBlockString = _ref10.block;
111 return isBlockString ? (0, _blockString.printBlockString)(value, key === 'description' ? '' : ' ') : JSON.stringify(value);
112 },
113 BooleanValue: function BooleanValue(_ref11) {
114 var value = _ref11.value;
115 return value ? 'true' : 'false';
116 },
117 NullValue: function NullValue() {
118 return 'null';
119 },
120 EnumValue: function EnumValue(_ref12) {
121 var value = _ref12.value;
122 return value;
123 },
124 ListValue: function ListValue(_ref13) {
125 var values = _ref13.values;
126 return '[' + join(values, ', ') + ']';
127 },
128 ObjectValue: function ObjectValue(_ref14) {
129 var fields = _ref14.fields;
130 return '{' + join(fields, ', ') + '}';
131 },
132 ObjectField: function ObjectField(_ref15) {
133 var name = _ref15.name,
134 value = _ref15.value;
135 return name + ': ' + value;
136 },
137 // Directive
138 Directive: function Directive(_ref16) {
139 var name = _ref16.name,
140 args = _ref16.arguments;
141 return '@' + name + wrap('(', join(args, ', '), ')');
142 },
143 // Type
144 NamedType: function NamedType(_ref17) {
145 var name = _ref17.name;
146 return name;
147 },
148 ListType: function ListType(_ref18) {
149 var type = _ref18.type;
150 return '[' + type + ']';
151 },
152 NonNullType: function NonNullType(_ref19) {
153 var type = _ref19.type;
154 return type + '!';
155 },
156 // Type System Definitions
157 SchemaDefinition: addDescription(function (_ref20) {
158 var directives = _ref20.directives,
159 operationTypes = _ref20.operationTypes;
160 return join(['schema', join(directives, ' '), block(operationTypes)], ' ');
161 }),
162 OperationTypeDefinition: function OperationTypeDefinition(_ref21) {
163 var operation = _ref21.operation,
164 type = _ref21.type;
165 return operation + ': ' + type;
166 },
167 ScalarTypeDefinition: addDescription(function (_ref22) {
168 var name = _ref22.name,
169 directives = _ref22.directives;
170 return join(['scalar', name, join(directives, ' ')], ' ');
171 }),
172 ObjectTypeDefinition: addDescription(function (_ref23) {
173 var name = _ref23.name,
174 interfaces = _ref23.interfaces,
175 directives = _ref23.directives,
176 fields = _ref23.fields;
177 return join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
178 }),
179 FieldDefinition: addDescription(function (_ref24) {
180 var name = _ref24.name,
181 args = _ref24.arguments,
182 type = _ref24.type,
183 directives = _ref24.directives;
184 return name + (hasMultilineItems(args) ? wrap('(\n', indent(join(args, '\n')), '\n)') : wrap('(', join(args, ', '), ')')) + ': ' + type + wrap(' ', join(directives, ' '));
185 }),
186 InputValueDefinition: addDescription(function (_ref25) {
187 var name = _ref25.name,
188 type = _ref25.type,
189 defaultValue = _ref25.defaultValue,
190 directives = _ref25.directives;
191 return join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' ');
192 }),
193 InterfaceTypeDefinition: addDescription(function (_ref26) {
194 var name = _ref26.name,
195 interfaces = _ref26.interfaces,
196 directives = _ref26.directives,
197 fields = _ref26.fields;
198 return join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
199 }),
200 UnionTypeDefinition: addDescription(function (_ref27) {
201 var name = _ref27.name,
202 directives = _ref27.directives,
203 types = _ref27.types;
204 return join(['union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' ');
205 }),
206 EnumTypeDefinition: addDescription(function (_ref28) {
207 var name = _ref28.name,
208 directives = _ref28.directives,
209 values = _ref28.values;
210 return join(['enum', name, join(directives, ' '), block(values)], ' ');
211 }),
212 EnumValueDefinition: addDescription(function (_ref29) {
213 var name = _ref29.name,
214 directives = _ref29.directives;
215 return join([name, join(directives, ' ')], ' ');
216 }),
217 InputObjectTypeDefinition: addDescription(function (_ref30) {
218 var name = _ref30.name,
219 directives = _ref30.directives,
220 fields = _ref30.fields;
221 return join(['input', name, join(directives, ' '), block(fields)], ' ');
222 }),
223 DirectiveDefinition: addDescription(function (_ref31) {
224 var name = _ref31.name,
225 args = _ref31.arguments,
226 repeatable = _ref31.repeatable,
227 locations = _ref31.locations;
228 return 'directive @' + name + (hasMultilineItems(args) ? wrap('(\n', indent(join(args, '\n')), '\n)') : wrap('(', join(args, ', '), ')')) + (repeatable ? ' repeatable' : '') + ' on ' + join(locations, ' | ');
229 }),
230 SchemaExtension: function SchemaExtension(_ref32) {
231 var directives = _ref32.directives,
232 operationTypes = _ref32.operationTypes;
233 return join(['extend schema', join(directives, ' '), block(operationTypes)], ' ');
234 },
235 ScalarTypeExtension: function ScalarTypeExtension(_ref33) {
236 var name = _ref33.name,
237 directives = _ref33.directives;
238 return join(['extend scalar', name, join(directives, ' ')], ' ');
239 },
240 ObjectTypeExtension: function ObjectTypeExtension(_ref34) {
241 var name = _ref34.name,
242 interfaces = _ref34.interfaces,
243 directives = _ref34.directives,
244 fields = _ref34.fields;
245 return join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
246 },
247 InterfaceTypeExtension: function InterfaceTypeExtension(_ref35) {
248 var name = _ref35.name,
249 interfaces = _ref35.interfaces,
250 directives = _ref35.directives,
251 fields = _ref35.fields;
252 return join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
253 },
254 UnionTypeExtension: function UnionTypeExtension(_ref36) {
255 var name = _ref36.name,
256 directives = _ref36.directives,
257 types = _ref36.types;
258 return join(['extend union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' ');
259 },
260 EnumTypeExtension: function EnumTypeExtension(_ref37) {
261 var name = _ref37.name,
262 directives = _ref37.directives,
263 values = _ref37.values;
264 return join(['extend enum', name, join(directives, ' '), block(values)], ' ');
265 },
266 InputObjectTypeExtension: function InputObjectTypeExtension(_ref38) {
267 var name = _ref38.name,
268 directives = _ref38.directives,
269 fields = _ref38.fields;
270 return join(['extend input', name, join(directives, ' '), block(fields)], ' ');
271 }
272};
273
274function addDescription(cb) {
275 return function (node) {
276 return join([node.description, cb(node)], '\n');
277 };
278}
279/**
280 * Given maybeArray, print an empty string if it is null or empty, otherwise
281 * print all items together separated by separator if provided
282 */
283
284
285function join(maybeArray) {
286 var _maybeArray$filter$jo;
287
288 var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
289 return (_maybeArray$filter$jo = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.filter(function (x) {
290 return x;
291 }).join(separator)) !== null && _maybeArray$filter$jo !== void 0 ? _maybeArray$filter$jo : '';
292}
293/**
294 * Given array, print each item on its own line, wrapped in an
295 * indented "{ }" block.
296 */
297
298
299function block(array) {
300 return wrap('{\n', indent(join(array, '\n')), '\n}');
301}
302/**
303 * If maybeString is not null or empty, then wrap with start and end, otherwise print an empty string.
304 */
305
306
307function wrap(start, maybeString) {
308 var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
309 return maybeString != null && maybeString !== '' ? start + maybeString + end : '';
310}
311
312function indent(str) {
313 return wrap(' ', str.replace(/\n/g, '\n '));
314}
315
316function isMultiline(str) {
317 return str.indexOf('\n') !== -1;
318}
319
320function hasMultilineItems(maybeArray) {
321 return maybeArray != null && maybeArray.some(isMultiline);
322}