Mirror: The small sibling of the graphql package, slimmed down for client-side libraries.
1import { Kind } from 'graphql';
2import { printBlockString } from './blockString';
3import { printString } from './printString';
4
5export function print(node) {
6 if (Array.isArray(node)) {
7 return node.map(print);
8 } else if (node == null || typeof node !== 'object') {
9 return node ? '' + node : '';
10 }
11
12 switch (node.kind) {
13 case 'OperationDefinition': {
14 const prefix = join(
15 [
16 node.operation,
17 print(node.name) +
18 wrap('(', join(print(node.variableDefinitions), ', '), ')'),
19 join(print(node.directives), ' '),
20 ],
21 ' '
22 );
23
24 return (
25 (prefix === 'query' ? '' : prefix + ' ') + print(node.selectionSet)
26 );
27 }
28
29 case 'VariableDefinition':
30 return (
31 print(node.variable) +
32 ': ' +
33 print(node.type) +
34 wrap(' = ', print(node.defaultValue)) +
35 wrap(' ', join(print(node.directives), ' '))
36 );
37
38 case 'Field':
39 let prefix = wrap('', print(node.alias), ': ') + print(node.name);
40 if (node.required === 'optional') {
41 prefix += '?';
42 } else if (node.required === 'required') {
43 prefix += '!';
44 }
45 return join(
46 [
47 prefix + wrap('(', join(print(node.arguments), ', '), ')'),
48 join(print(node.directives), ' '),
49 print(node.selectionSet),
50 ],
51 ' '
52 );
53
54 case 'StringValue':
55 return node.isBlockString
56 ? printBlockString(node.value)
57 : printString(node.value);
58
59 case 'BooleanValue':
60 return node.value ? 'true' : 'false';
61
62 case 'NullValue':
63 return 'null';
64
65 case 'IntValue':
66 case 'FloatValue':
67 case 'EnumValue':
68 case 'Name':
69 return node.value;
70
71 case 'ListValue':
72 return '[' + join(print(node.values), ', ') + ']';
73
74 case 'ObjectValue':
75 return '{' + join(print(node.fields), ', ') + '}';
76
77 case 'ObjectField':
78 return node.name.value + ': ' + print(node.value);
79
80 case 'Variable':
81 return '$' + node.name.value;
82 case 'Document':
83 return join(print(node.definitions), '\n\n') + '\n';
84 case 'SelectionSet':
85 return block(print(node.selections));
86 case 'Argument':
87 return node.name.value + ': ' + print(node.value);
88
89 case 'FragmentSpread':
90 return (
91 '...' + print(node.name) + wrap(' ', join(print(node.directives), ' '))
92 );
93
94 case 'InlineFragment':
95 return join(
96 [
97 '...',
98 wrap('on ', print(node.typeCondition)),
99 join(print(node.directives), ' '),
100 print(node.selectionSet),
101 ],
102 ' '
103 );
104
105 case 'FragmentDefinition':
106 return (
107 'fragment ' +
108 node.name.value +
109 wrap('(', join(print(node.variableDefinitions), ', '), ')') +
110 ' ' +
111 'on ' +
112 print(node.typeCondition) +
113 ' ' +
114 wrap('', join(print(node.directives), ' '), ' ') +
115 print(node.selectionSet)
116 );
117
118 case 'Directive':
119 return (
120 '@' +
121 node.name.value +
122 wrap('(', join(print(node.arguments), ', '), ')')
123 );
124
125 case 'NamedType':
126 return node.name.value;
127
128 case 'ListType':
129 return '[' + print(node.type) + ']';
130
131 case 'NonNullType':
132 return print(node.type) + '!';
133
134 default:
135 return '';
136 }
137}
138
139const join = (array, separator) =>
140 (array && array.filter((x) => x).join(separator || '')) || '';
141
142const block = (array) =>
143 wrap('{\n ', join(array, '\n').replace(/\n/g, '\n '), '\n}');
144
145const wrap = (start, value, end) => (value ? start + value + (end || '') : '');