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 return join(
40 [
41 wrap('', print(node.alias), ': ') +
42 print(node.name) +
43 wrap('(', join(print(node.arguments), ', '), ')'),
44 join(print(node.directives), ' '),
45 print(node.selectionSet),
46 ],
47 ' '
48 );
49
50 case 'StringValue':
51 return node.isBlockString
52 ? printBlockString(node.value)
53 : printString(node.value);
54
55 case 'BooleanValue':
56 return node.value ? 'true' : 'false';
57
58 case 'NullValue':
59 return 'null';
60
61 case 'IntValue':
62 case 'FloatValue':
63 case 'EnumValue':
64 case 'Name':
65 return node.value;
66
67 case 'ListValue':
68 return '[' + join(print(node.values), ', ') + ']';
69
70 case 'ObjectValue':
71 return '{' + join(print(node.fields), ', ') + '}';
72
73 case 'ObjectField':
74 return node.name.value + ': ' + print(node.value);
75
76 case 'Variable':
77 return '$' + node.name.value;
78 case 'Document':
79 return join(print(node.definitions), '\n\n') + '\n';
80 case 'SelectionSet':
81 return block(print(node.selections));
82 case 'Argument':
83 return node.name.value + ': ' + print(node.value);
84
85 case 'FragmentSpread':
86 return (
87 '...' + print(node.name) + wrap(' ', join(print(node.directives), ' '))
88 );
89
90 case 'InlineFragment':
91 return join(
92 [
93 '...',
94 wrap('on ', print(node.typeCondition)),
95 join(print(node.directives), ' '),
96 print(node.selectionSet),
97 ],
98 ' '
99 );
100
101 case 'FragmentDefinition':
102 return (
103 'fragment ' +
104 node.name.value +
105 wrap('(', join(print(node.variableDefinitions), ', '), ')') +
106 ' ' +
107 'on ' +
108 print(node.typeCondition) +
109 ' ' +
110 wrap('', join(print(node.directives), ' '), ' ') +
111 print(node.selectionSet)
112 );
113
114 case 'Directive':
115 return (
116 '@' +
117 node.name.value +
118 wrap('(', join(print(node.arguments), ', '), ')')
119 );
120
121 case 'NamedType':
122 return node.name.value;
123
124 case 'ListType':
125 return '[' + print(node.type) + ']';
126
127 case 'NonNullType':
128 return print(node.type) + '!';
129
130 default:
131 return '';
132 }
133}
134
135const join = (array, separator) =>
136 (array && array.filter((x) => x).join(separator || '')) || '';
137
138const block = (array) =>
139 wrap('{\n ', join(array, '\n').replace(/\n/g, '\n '), '\n}');
140
141const wrap = (start, value, end) => (value ? start + value + (end || '') : '');