@envelop/testing 1.2.0-alpha-d7e3951.0 → 2.1.0-alpha-290f8ac.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -1
- package/index.js +235 -246
- package/index.mjs +235 -246
- package/package.json +7 -2
package/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="jest" />
|
|
2
2
|
import { DocumentNode, ExecutionResult, GraphQLSchema } from 'graphql';
|
|
3
|
+
import { PluginOrDisabledPlugin } from '@envelop/core';
|
|
3
4
|
import { GetEnvelopedFn, Plugin } from '@envelop/types';
|
|
4
5
|
export declare type ModifyPluginsFn = (plugins: Plugin<any>[]) => Plugin<any>[];
|
|
5
6
|
export declare type PhaseReplacementParams = {
|
|
@@ -47,7 +48,7 @@ export declare type TestkitInstance = {
|
|
|
47
48
|
mockPhase: (phaseReplacement: PhaseReplacementParams) => void;
|
|
48
49
|
wait: (ms: number) => Promise<void>;
|
|
49
50
|
};
|
|
50
|
-
export declare function createTestkit(pluginsOrEnvelop: GetEnvelopedFn<any> |
|
|
51
|
+
export declare function createTestkit(pluginsOrEnvelop: GetEnvelopedFn<any> | Array<PluginOrDisabledPlugin>, schema?: GraphQLSchema): TestkitInstance;
|
|
51
52
|
export declare function assertSingleExecutionValue(input: ExecutionReturn): asserts input is ExecutionResult;
|
|
52
53
|
export declare function assertStreamExecutionValue(input: ExecutionReturn): asserts input is AsyncIterableIterator<ExecutionResult>;
|
|
53
54
|
export declare const collectAsyncIteratorValues: <TType>(asyncIterable: AsyncIterableIterator<TType>) => Promise<TType[]>;
|
package/index.js
CHANGED
|
@@ -5,9 +5,227 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
const graphql = require('graphql');
|
|
6
6
|
const core = require('@envelop/core');
|
|
7
7
|
const types = require('@envelop/types');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
|
|
9
|
+
const MAX_LINE_LENGTH = 80;
|
|
10
|
+
let commentsRegistry = {};
|
|
11
|
+
function printComment(comment) {
|
|
12
|
+
return '\n# ' + comment.replace(/\n/g, '\n# ');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the MIT license found in the
|
|
18
|
+
* LICENSE file in the root directory of this source tree.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* NOTE: ==> This file has been modified just to add comments to the printed AST
|
|
22
|
+
* This is a temp measure, we will move to using the original non modified printer.js ASAP.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Given maybeArray, print an empty string if it is null or empty, otherwise
|
|
26
|
+
* print all items together separated by separator if provided
|
|
27
|
+
*/
|
|
28
|
+
function join(maybeArray, separator) {
|
|
29
|
+
return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
|
|
30
|
+
}
|
|
31
|
+
function hasMultilineItems(maybeArray) {
|
|
32
|
+
var _a;
|
|
33
|
+
return (_a = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.some(str => str.includes('\n'))) !== null && _a !== void 0 ? _a : false;
|
|
34
|
+
}
|
|
35
|
+
function addDescription(cb) {
|
|
36
|
+
return (node, _key, _parent, path, ancestors) => {
|
|
37
|
+
var _a;
|
|
38
|
+
const keys = [];
|
|
39
|
+
const parent = path.reduce((prev, key) => {
|
|
40
|
+
if (['fields', 'arguments', 'values'].includes(key) && prev.name) {
|
|
41
|
+
keys.push(prev.name.value);
|
|
42
|
+
}
|
|
43
|
+
return prev[key];
|
|
44
|
+
}, ancestors[0]);
|
|
45
|
+
const key = [...keys, (_a = parent === null || parent === void 0 ? void 0 : parent.name) === null || _a === void 0 ? void 0 : _a.value].filter(Boolean).join('.');
|
|
46
|
+
const items = [];
|
|
47
|
+
if (node.kind.includes('Definition') && commentsRegistry[key]) {
|
|
48
|
+
items.push(...commentsRegistry[key]);
|
|
49
|
+
}
|
|
50
|
+
return join([...items.map(printComment), node.description, cb(node, _key, _parent, path, ancestors)], '\n');
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function indent(maybeString) {
|
|
54
|
+
return maybeString && ` ${maybeString.replace(/\n/g, '\n ')}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Given array, print each item on its own line, wrapped in an
|
|
58
|
+
* indented "{ }" block.
|
|
59
|
+
*/
|
|
60
|
+
function block(array) {
|
|
61
|
+
return array && array.length !== 0 ? `{\n${indent(join(array, '\n'))}\n}` : '';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* If maybeString is not null or empty, then wrap with start and end, otherwise
|
|
65
|
+
* print an empty string.
|
|
66
|
+
*/
|
|
67
|
+
function wrap(start, maybeString, end) {
|
|
68
|
+
return maybeString ? start + maybeString + (end || '') : '';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Print a block string in the indented block form by adding a leading and
|
|
72
|
+
* trailing blank line. However, if a block string starts with whitespace and is
|
|
73
|
+
* a single-line, adding a leading blank line would strip that whitespace.
|
|
74
|
+
*/
|
|
75
|
+
function printBlockString(value, isDescription = false) {
|
|
76
|
+
const escaped = value.replace(/"""/g, '\\"""');
|
|
77
|
+
return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1
|
|
78
|
+
? `"""${escaped.replace(/"$/, '"\n')}"""`
|
|
79
|
+
: `"""\n${isDescription ? escaped : indent(escaped)}\n"""`;
|
|
80
|
+
}
|
|
81
|
+
const printDocASTReducer = {
|
|
82
|
+
Name: { leave: node => node.value },
|
|
83
|
+
Variable: { leave: node => '$' + node.name },
|
|
84
|
+
// Document
|
|
85
|
+
Document: {
|
|
86
|
+
leave: node => join(node.definitions, '\n\n'),
|
|
87
|
+
},
|
|
88
|
+
OperationDefinition: {
|
|
89
|
+
leave: node => {
|
|
90
|
+
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
91
|
+
const prefix = join([node.operation, join([node.name, varDefs]), join(node.directives, ' ')], ' ');
|
|
92
|
+
// the query short form.
|
|
93
|
+
return prefix + ' ' + node.selectionSet;
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
VariableDefinition: {
|
|
97
|
+
leave: ({ variable, type, defaultValue, directives }) => variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')),
|
|
98
|
+
},
|
|
99
|
+
SelectionSet: { leave: ({ selections }) => block(selections) },
|
|
100
|
+
Field: {
|
|
101
|
+
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
102
|
+
const prefix = wrap('', alias, ': ') + name;
|
|
103
|
+
let argsLine = prefix + wrap('(', join(args, ', '), ')');
|
|
104
|
+
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
105
|
+
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
|
|
106
|
+
}
|
|
107
|
+
return join([argsLine, join(directives, ' '), selectionSet], ' ');
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
Argument: { leave: ({ name, value }) => name + ': ' + value },
|
|
111
|
+
// Fragments
|
|
112
|
+
FragmentSpread: {
|
|
113
|
+
leave: ({ name, directives }) => '...' + name + wrap(' ', join(directives, ' ')),
|
|
114
|
+
},
|
|
115
|
+
InlineFragment: {
|
|
116
|
+
leave: ({ typeCondition, directives, selectionSet }) => join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '),
|
|
117
|
+
},
|
|
118
|
+
FragmentDefinition: {
|
|
119
|
+
leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet }) =>
|
|
120
|
+
// Note: fragment variable definitions are experimental and may be changed
|
|
121
|
+
// or removed in the future.
|
|
122
|
+
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
123
|
+
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
124
|
+
selectionSet,
|
|
125
|
+
},
|
|
126
|
+
// Value
|
|
127
|
+
IntValue: { leave: ({ value }) => value },
|
|
128
|
+
FloatValue: { leave: ({ value }) => value },
|
|
129
|
+
StringValue: {
|
|
130
|
+
leave: ({ value, block: isBlockString }) => {
|
|
131
|
+
if (isBlockString) {
|
|
132
|
+
return printBlockString(value);
|
|
133
|
+
}
|
|
134
|
+
return JSON.stringify(value);
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
|
|
138
|
+
NullValue: { leave: () => 'null' },
|
|
139
|
+
EnumValue: { leave: ({ value }) => value },
|
|
140
|
+
ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
|
|
141
|
+
ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
|
|
142
|
+
ObjectField: { leave: ({ name, value }) => name + ': ' + value },
|
|
143
|
+
// Directive
|
|
144
|
+
Directive: {
|
|
145
|
+
leave: ({ name, arguments: args }) => '@' + name + wrap('(', join(args, ', '), ')'),
|
|
146
|
+
},
|
|
147
|
+
// Type
|
|
148
|
+
NamedType: { leave: ({ name }) => name },
|
|
149
|
+
ListType: { leave: ({ type }) => '[' + type + ']' },
|
|
150
|
+
NonNullType: { leave: ({ type }) => type + '!' },
|
|
151
|
+
// Type System Definitions
|
|
152
|
+
SchemaDefinition: {
|
|
153
|
+
leave: ({ directives, operationTypes }) => join(['schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
154
|
+
},
|
|
155
|
+
OperationTypeDefinition: {
|
|
156
|
+
leave: ({ operation, type }) => operation + ': ' + type,
|
|
157
|
+
},
|
|
158
|
+
ScalarTypeDefinition: {
|
|
159
|
+
leave: ({ name, directives }) => join(['scalar', name, join(directives, ' ')], ' '),
|
|
160
|
+
},
|
|
161
|
+
ObjectTypeDefinition: {
|
|
162
|
+
leave: ({ name, interfaces, directives, fields }) => join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
163
|
+
},
|
|
164
|
+
FieldDefinition: {
|
|
165
|
+
leave: ({ name, arguments: args, type, directives }) => name +
|
|
166
|
+
(hasMultilineItems(args)
|
|
167
|
+
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
168
|
+
: wrap('(', join(args, ', '), ')')) +
|
|
169
|
+
': ' +
|
|
170
|
+
type +
|
|
171
|
+
wrap(' ', join(directives, ' ')),
|
|
172
|
+
},
|
|
173
|
+
InputValueDefinition: {
|
|
174
|
+
leave: ({ name, type, defaultValue, directives }) => join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '),
|
|
175
|
+
},
|
|
176
|
+
InterfaceTypeDefinition: {
|
|
177
|
+
leave: ({ name, interfaces, directives, fields }) => join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
178
|
+
},
|
|
179
|
+
UnionTypeDefinition: {
|
|
180
|
+
leave: ({ name, directives, types }) => join(['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
181
|
+
},
|
|
182
|
+
EnumTypeDefinition: {
|
|
183
|
+
leave: ({ name, directives, values }) => join(['enum', name, join(directives, ' '), block(values)], ' '),
|
|
184
|
+
},
|
|
185
|
+
EnumValueDefinition: {
|
|
186
|
+
leave: ({ name, directives }) => join([name, join(directives, ' ')], ' '),
|
|
187
|
+
},
|
|
188
|
+
InputObjectTypeDefinition: {
|
|
189
|
+
leave: ({ name, directives, fields }) => join(['input', name, join(directives, ' '), block(fields)], ' '),
|
|
190
|
+
},
|
|
191
|
+
DirectiveDefinition: {
|
|
192
|
+
leave: ({ name, arguments: args, repeatable, locations }) => 'directive @' +
|
|
193
|
+
name +
|
|
194
|
+
(hasMultilineItems(args)
|
|
195
|
+
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
196
|
+
: wrap('(', join(args, ', '), ')')) +
|
|
197
|
+
(repeatable ? ' repeatable' : '') +
|
|
198
|
+
' on ' +
|
|
199
|
+
join(locations, ' | '),
|
|
200
|
+
},
|
|
201
|
+
SchemaExtension: {
|
|
202
|
+
leave: ({ directives, operationTypes }) => join(['extend schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
203
|
+
},
|
|
204
|
+
ScalarTypeExtension: {
|
|
205
|
+
leave: ({ name, directives }) => join(['extend scalar', name, join(directives, ' ')], ' '),
|
|
206
|
+
},
|
|
207
|
+
ObjectTypeExtension: {
|
|
208
|
+
leave: ({ name, interfaces, directives, fields }) => join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
209
|
+
},
|
|
210
|
+
InterfaceTypeExtension: {
|
|
211
|
+
leave: ({ name, interfaces, directives, fields }) => join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
212
|
+
},
|
|
213
|
+
UnionTypeExtension: {
|
|
214
|
+
leave: ({ name, directives, types }) => join(['extend union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
215
|
+
},
|
|
216
|
+
EnumTypeExtension: {
|
|
217
|
+
leave: ({ name, directives, values }) => join(['extend enum', name, join(directives, ' '), block(values)], ' '),
|
|
218
|
+
},
|
|
219
|
+
InputObjectTypeExtension: {
|
|
220
|
+
leave: ({ name, directives, fields }) => join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
const printDocASTReducerWithComments = Object.keys(printDocASTReducer).reduce((prev, key) => ({
|
|
224
|
+
...prev,
|
|
225
|
+
[key]: {
|
|
226
|
+
leave: addDescription(printDocASTReducer[key].leave),
|
|
227
|
+
},
|
|
228
|
+
}), {});
|
|
11
229
|
|
|
12
230
|
var MapperKind;
|
|
13
231
|
(function (MapperKind) {
|
|
@@ -724,227 +942,6 @@ function isDocumentNode(object) {
|
|
|
724
942
|
return object && typeof object === 'object' && 'kind' in object && object.kind === graphql.Kind.DOCUMENT;
|
|
725
943
|
}
|
|
726
944
|
|
|
727
|
-
const MAX_LINE_LENGTH = 80;
|
|
728
|
-
let commentsRegistry = {};
|
|
729
|
-
function printComment(comment) {
|
|
730
|
-
return '\n# ' + comment.replace(/\n/g, '\n# ');
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
734
|
-
*
|
|
735
|
-
* This source code is licensed under the MIT license found in the
|
|
736
|
-
* LICENSE file in the root directory of this source tree.
|
|
737
|
-
*/
|
|
738
|
-
/**
|
|
739
|
-
* NOTE: ==> This file has been modified just to add comments to the printed AST
|
|
740
|
-
* This is a temp measure, we will move to using the original non modified printer.js ASAP.
|
|
741
|
-
*/
|
|
742
|
-
// import { visit, VisitFn } from 'graphql';
|
|
743
|
-
/**
|
|
744
|
-
* Given maybeArray, print an empty string if it is null or empty, otherwise
|
|
745
|
-
* print all items together separated by separator if provided
|
|
746
|
-
*/
|
|
747
|
-
function join(maybeArray, separator) {
|
|
748
|
-
return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
|
|
749
|
-
}
|
|
750
|
-
function hasMultilineItems(maybeArray) {
|
|
751
|
-
var _a;
|
|
752
|
-
return (_a = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.some(str => str.includes('\n'))) !== null && _a !== void 0 ? _a : false;
|
|
753
|
-
}
|
|
754
|
-
function addDescription(cb) {
|
|
755
|
-
return (node, _key, _parent, path, ancestors) => {
|
|
756
|
-
var _a;
|
|
757
|
-
const keys = [];
|
|
758
|
-
const parent = path.reduce((prev, key) => {
|
|
759
|
-
if (['fields', 'arguments', 'values'].includes(key) && prev.name) {
|
|
760
|
-
keys.push(prev.name.value);
|
|
761
|
-
}
|
|
762
|
-
return prev[key];
|
|
763
|
-
}, ancestors[0]);
|
|
764
|
-
const key = [...keys, (_a = parent === null || parent === void 0 ? void 0 : parent.name) === null || _a === void 0 ? void 0 : _a.value].filter(Boolean).join('.');
|
|
765
|
-
const items = [];
|
|
766
|
-
if (node.kind.includes('Definition') && commentsRegistry[key]) {
|
|
767
|
-
items.push(...commentsRegistry[key]);
|
|
768
|
-
}
|
|
769
|
-
return join([...items.map(printComment), node.description, cb(node)], '\n');
|
|
770
|
-
};
|
|
771
|
-
}
|
|
772
|
-
function indent(maybeString) {
|
|
773
|
-
return maybeString && ` ${maybeString.replace(/\n/g, '\n ')}`;
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Given array, print each item on its own line, wrapped in an
|
|
777
|
-
* indented "{ }" block.
|
|
778
|
-
*/
|
|
779
|
-
function block(array) {
|
|
780
|
-
return array && array.length !== 0 ? `{\n${indent(join(array, '\n'))}\n}` : '';
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* If maybeString is not null or empty, then wrap with start and end, otherwise
|
|
784
|
-
* print an empty string.
|
|
785
|
-
*/
|
|
786
|
-
function wrap(start, maybeString, end) {
|
|
787
|
-
return maybeString ? start + maybeString + (end || '') : '';
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Print a block string in the indented block form by adding a leading and
|
|
791
|
-
* trailing blank line. However, if a block string starts with whitespace and is
|
|
792
|
-
* a single-line, adding a leading blank line would strip that whitespace.
|
|
793
|
-
*/
|
|
794
|
-
function printBlockString(value, isDescription = false) {
|
|
795
|
-
const escaped = value.replace(/"""/g, '\\"""');
|
|
796
|
-
return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1
|
|
797
|
-
? `"""${escaped.replace(/"$/, '"\n')}"""`
|
|
798
|
-
: `"""\n${isDescription ? escaped : indent(escaped)}\n"""`;
|
|
799
|
-
}
|
|
800
|
-
const printDocASTReducer = {
|
|
801
|
-
Name: { leave: node => node.value },
|
|
802
|
-
Variable: { leave: node => '$' + node.name },
|
|
803
|
-
// Document
|
|
804
|
-
Document: {
|
|
805
|
-
leave: node => join(node.definitions, '\n\n'),
|
|
806
|
-
},
|
|
807
|
-
OperationDefinition: {
|
|
808
|
-
leave: node => {
|
|
809
|
-
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
810
|
-
const prefix = join([node.operation, join([node.name, varDefs]), join(node.directives, ' ')], ' ');
|
|
811
|
-
// the query short form.
|
|
812
|
-
return prefix + ' ' + node.selectionSet;
|
|
813
|
-
},
|
|
814
|
-
},
|
|
815
|
-
VariableDefinition: {
|
|
816
|
-
leave: ({ variable, type, defaultValue, directives }) => variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')),
|
|
817
|
-
},
|
|
818
|
-
SelectionSet: { leave: ({ selections }) => block(selections) },
|
|
819
|
-
Field: {
|
|
820
|
-
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
821
|
-
const prefix = wrap('', alias, ': ') + name;
|
|
822
|
-
let argsLine = prefix + wrap('(', join(args, ', '), ')');
|
|
823
|
-
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
824
|
-
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
|
|
825
|
-
}
|
|
826
|
-
return join([argsLine, join(directives, ' '), selectionSet], ' ');
|
|
827
|
-
},
|
|
828
|
-
},
|
|
829
|
-
Argument: { leave: ({ name, value }) => name + ': ' + value },
|
|
830
|
-
// Fragments
|
|
831
|
-
FragmentSpread: {
|
|
832
|
-
leave: ({ name, directives }) => '...' + name + wrap(' ', join(directives, ' ')),
|
|
833
|
-
},
|
|
834
|
-
InlineFragment: {
|
|
835
|
-
leave: ({ typeCondition, directives, selectionSet }) => join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '),
|
|
836
|
-
},
|
|
837
|
-
FragmentDefinition: {
|
|
838
|
-
leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet }) =>
|
|
839
|
-
// Note: fragment variable definitions are experimental and may be changed
|
|
840
|
-
// or removed in the future.
|
|
841
|
-
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
842
|
-
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
843
|
-
selectionSet,
|
|
844
|
-
},
|
|
845
|
-
// Value
|
|
846
|
-
IntValue: { leave: ({ value }) => value },
|
|
847
|
-
FloatValue: { leave: ({ value }) => value },
|
|
848
|
-
StringValue: {
|
|
849
|
-
leave: ({ value, block: isBlockString }) => (isBlockString ? printBlockString(value) : JSON.stringify(value)),
|
|
850
|
-
},
|
|
851
|
-
BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
|
|
852
|
-
NullValue: { leave: () => 'null' },
|
|
853
|
-
EnumValue: { leave: ({ value }) => value },
|
|
854
|
-
ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
|
|
855
|
-
ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
|
|
856
|
-
ObjectField: { leave: ({ name, value }) => name + ': ' + value },
|
|
857
|
-
// Directive
|
|
858
|
-
Directive: {
|
|
859
|
-
leave: ({ name, arguments: args }) => '@' + name + wrap('(', join(args, ', '), ')'),
|
|
860
|
-
},
|
|
861
|
-
// Type
|
|
862
|
-
NamedType: { leave: ({ name }) => name },
|
|
863
|
-
ListType: { leave: ({ type }) => '[' + type + ']' },
|
|
864
|
-
NonNullType: { leave: ({ type }) => type + '!' },
|
|
865
|
-
// Type System Definitions
|
|
866
|
-
SchemaDefinition: {
|
|
867
|
-
leave: ({ description, directives, operationTypes }) => wrap('', description, '\n') + join(['schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
868
|
-
},
|
|
869
|
-
OperationTypeDefinition: {
|
|
870
|
-
leave: ({ operation, type }) => operation + ': ' + type,
|
|
871
|
-
},
|
|
872
|
-
ScalarTypeDefinition: {
|
|
873
|
-
leave: ({ description, name, directives }) => wrap('', description, '\n') + join(['scalar', name, join(directives, ' ')], ' '),
|
|
874
|
-
},
|
|
875
|
-
ObjectTypeDefinition: {
|
|
876
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
|
|
877
|
-
join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
878
|
-
},
|
|
879
|
-
FieldDefinition: {
|
|
880
|
-
leave: ({ description, name, arguments: args, type, directives }) => wrap('', description, '\n') +
|
|
881
|
-
name +
|
|
882
|
-
(hasMultilineItems(args)
|
|
883
|
-
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
884
|
-
: wrap('(', join(args, ', '), ')')) +
|
|
885
|
-
': ' +
|
|
886
|
-
type +
|
|
887
|
-
wrap(' ', join(directives, ' ')),
|
|
888
|
-
},
|
|
889
|
-
InputValueDefinition: {
|
|
890
|
-
leave: ({ description, name, type, defaultValue, directives }) => wrap('', description, '\n') + join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '),
|
|
891
|
-
},
|
|
892
|
-
InterfaceTypeDefinition: {
|
|
893
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
|
|
894
|
-
join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
895
|
-
},
|
|
896
|
-
UnionTypeDefinition: {
|
|
897
|
-
leave: ({ description, name, directives, types }) => wrap('', description, '\n') + join(['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
898
|
-
},
|
|
899
|
-
EnumTypeDefinition: {
|
|
900
|
-
leave: ({ description, name, directives, values }) => wrap('', description, '\n') + join(['enum', name, join(directives, ' '), block(values)], ' '),
|
|
901
|
-
},
|
|
902
|
-
EnumValueDefinition: {
|
|
903
|
-
leave: ({ description, name, directives }) => wrap('', description, '\n') + join([name, join(directives, ' ')], ' '),
|
|
904
|
-
},
|
|
905
|
-
InputObjectTypeDefinition: {
|
|
906
|
-
leave: ({ description, name, directives, fields }) => wrap('', description, '\n') + join(['input', name, join(directives, ' '), block(fields)], ' '),
|
|
907
|
-
},
|
|
908
|
-
DirectiveDefinition: {
|
|
909
|
-
leave: ({ description, name, arguments: args, repeatable, locations }) => wrap('', description, '\n') +
|
|
910
|
-
'directive @' +
|
|
911
|
-
name +
|
|
912
|
-
(hasMultilineItems(args)
|
|
913
|
-
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
914
|
-
: wrap('(', join(args, ', '), ')')) +
|
|
915
|
-
(repeatable ? ' repeatable' : '') +
|
|
916
|
-
' on ' +
|
|
917
|
-
join(locations, ' | '),
|
|
918
|
-
},
|
|
919
|
-
SchemaExtension: {
|
|
920
|
-
leave: ({ directives, operationTypes }) => join(['extend schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
921
|
-
},
|
|
922
|
-
ScalarTypeExtension: {
|
|
923
|
-
leave: ({ name, directives }) => join(['extend scalar', name, join(directives, ' ')], ' '),
|
|
924
|
-
},
|
|
925
|
-
ObjectTypeExtension: {
|
|
926
|
-
leave: ({ name, interfaces, directives, fields }) => join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
927
|
-
},
|
|
928
|
-
InterfaceTypeExtension: {
|
|
929
|
-
leave: ({ name, interfaces, directives, fields }) => join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
930
|
-
},
|
|
931
|
-
UnionTypeExtension: {
|
|
932
|
-
leave: ({ name, directives, types }) => join(['extend union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
933
|
-
},
|
|
934
|
-
EnumTypeExtension: {
|
|
935
|
-
leave: ({ name, directives, values }) => join(['extend enum', name, join(directives, ' '), block(values)], ' '),
|
|
936
|
-
},
|
|
937
|
-
InputObjectTypeExtension: {
|
|
938
|
-
leave: ({ name, directives, fields }) => join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
939
|
-
},
|
|
940
|
-
};
|
|
941
|
-
const printDocASTReducerWithComments = Object.keys(printDocASTReducer).reduce((prev, key) => ({
|
|
942
|
-
...prev,
|
|
943
|
-
[key]: {
|
|
944
|
-
leave: addDescription(printDocASTReducer[key].leave),
|
|
945
|
-
},
|
|
946
|
-
}), {});
|
|
947
|
-
|
|
948
945
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
949
946
|
function createSpiedPlugin() {
|
|
950
947
|
const afterResolver = jest.fn();
|
|
@@ -1056,29 +1053,21 @@ function createTestkit(pluginsOrEnvelop, schema) {
|
|
|
1056
1053
|
errors: [new graphql.GraphQLError('Could not identify main operation.')],
|
|
1057
1054
|
};
|
|
1058
1055
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
query:
|
|
1066
|
-
|
|
1067
|
-
query: graphql.print(document),
|
|
1068
|
-
variables: variableValues,
|
|
1069
|
-
},
|
|
1056
|
+
const contextValue = await proxy.contextFactory({
|
|
1057
|
+
request: {
|
|
1058
|
+
headers: {},
|
|
1059
|
+
method: 'POST',
|
|
1060
|
+
query: '',
|
|
1061
|
+
body: {
|
|
1062
|
+
query: graphql.print(document),
|
|
1063
|
+
variables: variableValues,
|
|
1070
1064
|
},
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
}
|
|
1077
|
-
catch (err) {
|
|
1078
|
-
return {
|
|
1079
|
-
errors: [toGraphQLErrorOrThrow(err)],
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1065
|
+
},
|
|
1066
|
+
document,
|
|
1067
|
+
operation: graphql.print(document),
|
|
1068
|
+
variables: variableValues,
|
|
1069
|
+
...initialContext,
|
|
1070
|
+
});
|
|
1082
1071
|
if (mainOperation.operation === 'subscription') {
|
|
1083
1072
|
return proxy.subscribe({
|
|
1084
1073
|
variableValues,
|
package/index.mjs
CHANGED
|
@@ -1,9 +1,227 @@
|
|
|
1
1
|
import { GraphQLSchema, Kind, isObjectType, isEnumType, GraphQLEnumType, isListType, GraphQLList, isNonNullType, GraphQLNonNull, isNamedType, isInterfaceType, isInputObjectType, GraphQLObjectType, GraphQLInterfaceType, GraphQLInputObjectType, isSpecifiedDirective, GraphQLDirective, isUnionType, GraphQLUnionType, isScalarType, isSpecifiedScalarType, GraphQLScalarType, isLeafType, GraphQLID, GraphQLBoolean, GraphQLString, GraphQLFloat, GraphQLInt, getNullableType, getOperationAST, GraphQLError, print } from 'graphql';
|
|
2
2
|
import { envelop, useSchema } from '@envelop/core';
|
|
3
3
|
import { isAsyncIterable } from '@envelop/types';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
const MAX_LINE_LENGTH = 80;
|
|
6
|
+
let commentsRegistry = {};
|
|
7
|
+
function printComment(comment) {
|
|
8
|
+
return '\n# ' + comment.replace(/\n/g, '\n# ');
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the MIT license found in the
|
|
14
|
+
* LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* NOTE: ==> This file has been modified just to add comments to the printed AST
|
|
18
|
+
* This is a temp measure, we will move to using the original non modified printer.js ASAP.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Given maybeArray, print an empty string if it is null or empty, otherwise
|
|
22
|
+
* print all items together separated by separator if provided
|
|
23
|
+
*/
|
|
24
|
+
function join(maybeArray, separator) {
|
|
25
|
+
return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
|
|
26
|
+
}
|
|
27
|
+
function hasMultilineItems(maybeArray) {
|
|
28
|
+
var _a;
|
|
29
|
+
return (_a = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.some(str => str.includes('\n'))) !== null && _a !== void 0 ? _a : false;
|
|
30
|
+
}
|
|
31
|
+
function addDescription(cb) {
|
|
32
|
+
return (node, _key, _parent, path, ancestors) => {
|
|
33
|
+
var _a;
|
|
34
|
+
const keys = [];
|
|
35
|
+
const parent = path.reduce((prev, key) => {
|
|
36
|
+
if (['fields', 'arguments', 'values'].includes(key) && prev.name) {
|
|
37
|
+
keys.push(prev.name.value);
|
|
38
|
+
}
|
|
39
|
+
return prev[key];
|
|
40
|
+
}, ancestors[0]);
|
|
41
|
+
const key = [...keys, (_a = parent === null || parent === void 0 ? void 0 : parent.name) === null || _a === void 0 ? void 0 : _a.value].filter(Boolean).join('.');
|
|
42
|
+
const items = [];
|
|
43
|
+
if (node.kind.includes('Definition') && commentsRegistry[key]) {
|
|
44
|
+
items.push(...commentsRegistry[key]);
|
|
45
|
+
}
|
|
46
|
+
return join([...items.map(printComment), node.description, cb(node, _key, _parent, path, ancestors)], '\n');
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function indent(maybeString) {
|
|
50
|
+
return maybeString && ` ${maybeString.replace(/\n/g, '\n ')}`;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Given array, print each item on its own line, wrapped in an
|
|
54
|
+
* indented "{ }" block.
|
|
55
|
+
*/
|
|
56
|
+
function block(array) {
|
|
57
|
+
return array && array.length !== 0 ? `{\n${indent(join(array, '\n'))}\n}` : '';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* If maybeString is not null or empty, then wrap with start and end, otherwise
|
|
61
|
+
* print an empty string.
|
|
62
|
+
*/
|
|
63
|
+
function wrap(start, maybeString, end) {
|
|
64
|
+
return maybeString ? start + maybeString + (end || '') : '';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Print a block string in the indented block form by adding a leading and
|
|
68
|
+
* trailing blank line. However, if a block string starts with whitespace and is
|
|
69
|
+
* a single-line, adding a leading blank line would strip that whitespace.
|
|
70
|
+
*/
|
|
71
|
+
function printBlockString(value, isDescription = false) {
|
|
72
|
+
const escaped = value.replace(/"""/g, '\\"""');
|
|
73
|
+
return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1
|
|
74
|
+
? `"""${escaped.replace(/"$/, '"\n')}"""`
|
|
75
|
+
: `"""\n${isDescription ? escaped : indent(escaped)}\n"""`;
|
|
76
|
+
}
|
|
77
|
+
const printDocASTReducer = {
|
|
78
|
+
Name: { leave: node => node.value },
|
|
79
|
+
Variable: { leave: node => '$' + node.name },
|
|
80
|
+
// Document
|
|
81
|
+
Document: {
|
|
82
|
+
leave: node => join(node.definitions, '\n\n'),
|
|
83
|
+
},
|
|
84
|
+
OperationDefinition: {
|
|
85
|
+
leave: node => {
|
|
86
|
+
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
87
|
+
const prefix = join([node.operation, join([node.name, varDefs]), join(node.directives, ' ')], ' ');
|
|
88
|
+
// the query short form.
|
|
89
|
+
return prefix + ' ' + node.selectionSet;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
VariableDefinition: {
|
|
93
|
+
leave: ({ variable, type, defaultValue, directives }) => variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')),
|
|
94
|
+
},
|
|
95
|
+
SelectionSet: { leave: ({ selections }) => block(selections) },
|
|
96
|
+
Field: {
|
|
97
|
+
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
98
|
+
const prefix = wrap('', alias, ': ') + name;
|
|
99
|
+
let argsLine = prefix + wrap('(', join(args, ', '), ')');
|
|
100
|
+
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
101
|
+
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
|
|
102
|
+
}
|
|
103
|
+
return join([argsLine, join(directives, ' '), selectionSet], ' ');
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
Argument: { leave: ({ name, value }) => name + ': ' + value },
|
|
107
|
+
// Fragments
|
|
108
|
+
FragmentSpread: {
|
|
109
|
+
leave: ({ name, directives }) => '...' + name + wrap(' ', join(directives, ' ')),
|
|
110
|
+
},
|
|
111
|
+
InlineFragment: {
|
|
112
|
+
leave: ({ typeCondition, directives, selectionSet }) => join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '),
|
|
113
|
+
},
|
|
114
|
+
FragmentDefinition: {
|
|
115
|
+
leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet }) =>
|
|
116
|
+
// Note: fragment variable definitions are experimental and may be changed
|
|
117
|
+
// or removed in the future.
|
|
118
|
+
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
119
|
+
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
120
|
+
selectionSet,
|
|
121
|
+
},
|
|
122
|
+
// Value
|
|
123
|
+
IntValue: { leave: ({ value }) => value },
|
|
124
|
+
FloatValue: { leave: ({ value }) => value },
|
|
125
|
+
StringValue: {
|
|
126
|
+
leave: ({ value, block: isBlockString }) => {
|
|
127
|
+
if (isBlockString) {
|
|
128
|
+
return printBlockString(value);
|
|
129
|
+
}
|
|
130
|
+
return JSON.stringify(value);
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
|
|
134
|
+
NullValue: { leave: () => 'null' },
|
|
135
|
+
EnumValue: { leave: ({ value }) => value },
|
|
136
|
+
ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
|
|
137
|
+
ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
|
|
138
|
+
ObjectField: { leave: ({ name, value }) => name + ': ' + value },
|
|
139
|
+
// Directive
|
|
140
|
+
Directive: {
|
|
141
|
+
leave: ({ name, arguments: args }) => '@' + name + wrap('(', join(args, ', '), ')'),
|
|
142
|
+
},
|
|
143
|
+
// Type
|
|
144
|
+
NamedType: { leave: ({ name }) => name },
|
|
145
|
+
ListType: { leave: ({ type }) => '[' + type + ']' },
|
|
146
|
+
NonNullType: { leave: ({ type }) => type + '!' },
|
|
147
|
+
// Type System Definitions
|
|
148
|
+
SchemaDefinition: {
|
|
149
|
+
leave: ({ directives, operationTypes }) => join(['schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
150
|
+
},
|
|
151
|
+
OperationTypeDefinition: {
|
|
152
|
+
leave: ({ operation, type }) => operation + ': ' + type,
|
|
153
|
+
},
|
|
154
|
+
ScalarTypeDefinition: {
|
|
155
|
+
leave: ({ name, directives }) => join(['scalar', name, join(directives, ' ')], ' '),
|
|
156
|
+
},
|
|
157
|
+
ObjectTypeDefinition: {
|
|
158
|
+
leave: ({ name, interfaces, directives, fields }) => join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
159
|
+
},
|
|
160
|
+
FieldDefinition: {
|
|
161
|
+
leave: ({ name, arguments: args, type, directives }) => name +
|
|
162
|
+
(hasMultilineItems(args)
|
|
163
|
+
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
164
|
+
: wrap('(', join(args, ', '), ')')) +
|
|
165
|
+
': ' +
|
|
166
|
+
type +
|
|
167
|
+
wrap(' ', join(directives, ' ')),
|
|
168
|
+
},
|
|
169
|
+
InputValueDefinition: {
|
|
170
|
+
leave: ({ name, type, defaultValue, directives }) => join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '),
|
|
171
|
+
},
|
|
172
|
+
InterfaceTypeDefinition: {
|
|
173
|
+
leave: ({ name, interfaces, directives, fields }) => join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
174
|
+
},
|
|
175
|
+
UnionTypeDefinition: {
|
|
176
|
+
leave: ({ name, directives, types }) => join(['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
177
|
+
},
|
|
178
|
+
EnumTypeDefinition: {
|
|
179
|
+
leave: ({ name, directives, values }) => join(['enum', name, join(directives, ' '), block(values)], ' '),
|
|
180
|
+
},
|
|
181
|
+
EnumValueDefinition: {
|
|
182
|
+
leave: ({ name, directives }) => join([name, join(directives, ' ')], ' '),
|
|
183
|
+
},
|
|
184
|
+
InputObjectTypeDefinition: {
|
|
185
|
+
leave: ({ name, directives, fields }) => join(['input', name, join(directives, ' '), block(fields)], ' '),
|
|
186
|
+
},
|
|
187
|
+
DirectiveDefinition: {
|
|
188
|
+
leave: ({ name, arguments: args, repeatable, locations }) => 'directive @' +
|
|
189
|
+
name +
|
|
190
|
+
(hasMultilineItems(args)
|
|
191
|
+
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
192
|
+
: wrap('(', join(args, ', '), ')')) +
|
|
193
|
+
(repeatable ? ' repeatable' : '') +
|
|
194
|
+
' on ' +
|
|
195
|
+
join(locations, ' | '),
|
|
196
|
+
},
|
|
197
|
+
SchemaExtension: {
|
|
198
|
+
leave: ({ directives, operationTypes }) => join(['extend schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
199
|
+
},
|
|
200
|
+
ScalarTypeExtension: {
|
|
201
|
+
leave: ({ name, directives }) => join(['extend scalar', name, join(directives, ' ')], ' '),
|
|
202
|
+
},
|
|
203
|
+
ObjectTypeExtension: {
|
|
204
|
+
leave: ({ name, interfaces, directives, fields }) => join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
205
|
+
},
|
|
206
|
+
InterfaceTypeExtension: {
|
|
207
|
+
leave: ({ name, interfaces, directives, fields }) => join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
208
|
+
},
|
|
209
|
+
UnionTypeExtension: {
|
|
210
|
+
leave: ({ name, directives, types }) => join(['extend union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
211
|
+
},
|
|
212
|
+
EnumTypeExtension: {
|
|
213
|
+
leave: ({ name, directives, values }) => join(['extend enum', name, join(directives, ' '), block(values)], ' '),
|
|
214
|
+
},
|
|
215
|
+
InputObjectTypeExtension: {
|
|
216
|
+
leave: ({ name, directives, fields }) => join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
const printDocASTReducerWithComments = Object.keys(printDocASTReducer).reduce((prev, key) => ({
|
|
220
|
+
...prev,
|
|
221
|
+
[key]: {
|
|
222
|
+
leave: addDescription(printDocASTReducer[key].leave),
|
|
223
|
+
},
|
|
224
|
+
}), {});
|
|
7
225
|
|
|
8
226
|
var MapperKind;
|
|
9
227
|
(function (MapperKind) {
|
|
@@ -720,227 +938,6 @@ function isDocumentNode(object) {
|
|
|
720
938
|
return object && typeof object === 'object' && 'kind' in object && object.kind === Kind.DOCUMENT;
|
|
721
939
|
}
|
|
722
940
|
|
|
723
|
-
const MAX_LINE_LENGTH = 80;
|
|
724
|
-
let commentsRegistry = {};
|
|
725
|
-
function printComment(comment) {
|
|
726
|
-
return '\n# ' + comment.replace(/\n/g, '\n# ');
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
730
|
-
*
|
|
731
|
-
* This source code is licensed under the MIT license found in the
|
|
732
|
-
* LICENSE file in the root directory of this source tree.
|
|
733
|
-
*/
|
|
734
|
-
/**
|
|
735
|
-
* NOTE: ==> This file has been modified just to add comments to the printed AST
|
|
736
|
-
* This is a temp measure, we will move to using the original non modified printer.js ASAP.
|
|
737
|
-
*/
|
|
738
|
-
// import { visit, VisitFn } from 'graphql';
|
|
739
|
-
/**
|
|
740
|
-
* Given maybeArray, print an empty string if it is null or empty, otherwise
|
|
741
|
-
* print all items together separated by separator if provided
|
|
742
|
-
*/
|
|
743
|
-
function join(maybeArray, separator) {
|
|
744
|
-
return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
|
|
745
|
-
}
|
|
746
|
-
function hasMultilineItems(maybeArray) {
|
|
747
|
-
var _a;
|
|
748
|
-
return (_a = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.some(str => str.includes('\n'))) !== null && _a !== void 0 ? _a : false;
|
|
749
|
-
}
|
|
750
|
-
function addDescription(cb) {
|
|
751
|
-
return (node, _key, _parent, path, ancestors) => {
|
|
752
|
-
var _a;
|
|
753
|
-
const keys = [];
|
|
754
|
-
const parent = path.reduce((prev, key) => {
|
|
755
|
-
if (['fields', 'arguments', 'values'].includes(key) && prev.name) {
|
|
756
|
-
keys.push(prev.name.value);
|
|
757
|
-
}
|
|
758
|
-
return prev[key];
|
|
759
|
-
}, ancestors[0]);
|
|
760
|
-
const key = [...keys, (_a = parent === null || parent === void 0 ? void 0 : parent.name) === null || _a === void 0 ? void 0 : _a.value].filter(Boolean).join('.');
|
|
761
|
-
const items = [];
|
|
762
|
-
if (node.kind.includes('Definition') && commentsRegistry[key]) {
|
|
763
|
-
items.push(...commentsRegistry[key]);
|
|
764
|
-
}
|
|
765
|
-
return join([...items.map(printComment), node.description, cb(node)], '\n');
|
|
766
|
-
};
|
|
767
|
-
}
|
|
768
|
-
function indent(maybeString) {
|
|
769
|
-
return maybeString && ` ${maybeString.replace(/\n/g, '\n ')}`;
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* Given array, print each item on its own line, wrapped in an
|
|
773
|
-
* indented "{ }" block.
|
|
774
|
-
*/
|
|
775
|
-
function block(array) {
|
|
776
|
-
return array && array.length !== 0 ? `{\n${indent(join(array, '\n'))}\n}` : '';
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* If maybeString is not null or empty, then wrap with start and end, otherwise
|
|
780
|
-
* print an empty string.
|
|
781
|
-
*/
|
|
782
|
-
function wrap(start, maybeString, end) {
|
|
783
|
-
return maybeString ? start + maybeString + (end || '') : '';
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Print a block string in the indented block form by adding a leading and
|
|
787
|
-
* trailing blank line. However, if a block string starts with whitespace and is
|
|
788
|
-
* a single-line, adding a leading blank line would strip that whitespace.
|
|
789
|
-
*/
|
|
790
|
-
function printBlockString(value, isDescription = false) {
|
|
791
|
-
const escaped = value.replace(/"""/g, '\\"""');
|
|
792
|
-
return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1
|
|
793
|
-
? `"""${escaped.replace(/"$/, '"\n')}"""`
|
|
794
|
-
: `"""\n${isDescription ? escaped : indent(escaped)}\n"""`;
|
|
795
|
-
}
|
|
796
|
-
const printDocASTReducer = {
|
|
797
|
-
Name: { leave: node => node.value },
|
|
798
|
-
Variable: { leave: node => '$' + node.name },
|
|
799
|
-
// Document
|
|
800
|
-
Document: {
|
|
801
|
-
leave: node => join(node.definitions, '\n\n'),
|
|
802
|
-
},
|
|
803
|
-
OperationDefinition: {
|
|
804
|
-
leave: node => {
|
|
805
|
-
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
|
|
806
|
-
const prefix = join([node.operation, join([node.name, varDefs]), join(node.directives, ' ')], ' ');
|
|
807
|
-
// the query short form.
|
|
808
|
-
return prefix + ' ' + node.selectionSet;
|
|
809
|
-
},
|
|
810
|
-
},
|
|
811
|
-
VariableDefinition: {
|
|
812
|
-
leave: ({ variable, type, defaultValue, directives }) => variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' ')),
|
|
813
|
-
},
|
|
814
|
-
SelectionSet: { leave: ({ selections }) => block(selections) },
|
|
815
|
-
Field: {
|
|
816
|
-
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
817
|
-
const prefix = wrap('', alias, ': ') + name;
|
|
818
|
-
let argsLine = prefix + wrap('(', join(args, ', '), ')');
|
|
819
|
-
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
820
|
-
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
|
|
821
|
-
}
|
|
822
|
-
return join([argsLine, join(directives, ' '), selectionSet], ' ');
|
|
823
|
-
},
|
|
824
|
-
},
|
|
825
|
-
Argument: { leave: ({ name, value }) => name + ': ' + value },
|
|
826
|
-
// Fragments
|
|
827
|
-
FragmentSpread: {
|
|
828
|
-
leave: ({ name, directives }) => '...' + name + wrap(' ', join(directives, ' ')),
|
|
829
|
-
},
|
|
830
|
-
InlineFragment: {
|
|
831
|
-
leave: ({ typeCondition, directives, selectionSet }) => join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' '),
|
|
832
|
-
},
|
|
833
|
-
FragmentDefinition: {
|
|
834
|
-
leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet }) =>
|
|
835
|
-
// Note: fragment variable definitions are experimental and may be changed
|
|
836
|
-
// or removed in the future.
|
|
837
|
-
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
|
|
838
|
-
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
|
|
839
|
-
selectionSet,
|
|
840
|
-
},
|
|
841
|
-
// Value
|
|
842
|
-
IntValue: { leave: ({ value }) => value },
|
|
843
|
-
FloatValue: { leave: ({ value }) => value },
|
|
844
|
-
StringValue: {
|
|
845
|
-
leave: ({ value, block: isBlockString }) => (isBlockString ? printBlockString(value) : JSON.stringify(value)),
|
|
846
|
-
},
|
|
847
|
-
BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
|
|
848
|
-
NullValue: { leave: () => 'null' },
|
|
849
|
-
EnumValue: { leave: ({ value }) => value },
|
|
850
|
-
ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
|
|
851
|
-
ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
|
|
852
|
-
ObjectField: { leave: ({ name, value }) => name + ': ' + value },
|
|
853
|
-
// Directive
|
|
854
|
-
Directive: {
|
|
855
|
-
leave: ({ name, arguments: args }) => '@' + name + wrap('(', join(args, ', '), ')'),
|
|
856
|
-
},
|
|
857
|
-
// Type
|
|
858
|
-
NamedType: { leave: ({ name }) => name },
|
|
859
|
-
ListType: { leave: ({ type }) => '[' + type + ']' },
|
|
860
|
-
NonNullType: { leave: ({ type }) => type + '!' },
|
|
861
|
-
// Type System Definitions
|
|
862
|
-
SchemaDefinition: {
|
|
863
|
-
leave: ({ description, directives, operationTypes }) => wrap('', description, '\n') + join(['schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
864
|
-
},
|
|
865
|
-
OperationTypeDefinition: {
|
|
866
|
-
leave: ({ operation, type }) => operation + ': ' + type,
|
|
867
|
-
},
|
|
868
|
-
ScalarTypeDefinition: {
|
|
869
|
-
leave: ({ description, name, directives }) => wrap('', description, '\n') + join(['scalar', name, join(directives, ' ')], ' '),
|
|
870
|
-
},
|
|
871
|
-
ObjectTypeDefinition: {
|
|
872
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
|
|
873
|
-
join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
874
|
-
},
|
|
875
|
-
FieldDefinition: {
|
|
876
|
-
leave: ({ description, name, arguments: args, type, directives }) => wrap('', description, '\n') +
|
|
877
|
-
name +
|
|
878
|
-
(hasMultilineItems(args)
|
|
879
|
-
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
880
|
-
: wrap('(', join(args, ', '), ')')) +
|
|
881
|
-
': ' +
|
|
882
|
-
type +
|
|
883
|
-
wrap(' ', join(directives, ' ')),
|
|
884
|
-
},
|
|
885
|
-
InputValueDefinition: {
|
|
886
|
-
leave: ({ description, name, type, defaultValue, directives }) => wrap('', description, '\n') + join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' '),
|
|
887
|
-
},
|
|
888
|
-
InterfaceTypeDefinition: {
|
|
889
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap('', description, '\n') +
|
|
890
|
-
join(['interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
891
|
-
},
|
|
892
|
-
UnionTypeDefinition: {
|
|
893
|
-
leave: ({ description, name, directives, types }) => wrap('', description, '\n') + join(['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
894
|
-
},
|
|
895
|
-
EnumTypeDefinition: {
|
|
896
|
-
leave: ({ description, name, directives, values }) => wrap('', description, '\n') + join(['enum', name, join(directives, ' '), block(values)], ' '),
|
|
897
|
-
},
|
|
898
|
-
EnumValueDefinition: {
|
|
899
|
-
leave: ({ description, name, directives }) => wrap('', description, '\n') + join([name, join(directives, ' ')], ' '),
|
|
900
|
-
},
|
|
901
|
-
InputObjectTypeDefinition: {
|
|
902
|
-
leave: ({ description, name, directives, fields }) => wrap('', description, '\n') + join(['input', name, join(directives, ' '), block(fields)], ' '),
|
|
903
|
-
},
|
|
904
|
-
DirectiveDefinition: {
|
|
905
|
-
leave: ({ description, name, arguments: args, repeatable, locations }) => wrap('', description, '\n') +
|
|
906
|
-
'directive @' +
|
|
907
|
-
name +
|
|
908
|
-
(hasMultilineItems(args)
|
|
909
|
-
? wrap('(\n', indent(join(args, '\n')), '\n)')
|
|
910
|
-
: wrap('(', join(args, ', '), ')')) +
|
|
911
|
-
(repeatable ? ' repeatable' : '') +
|
|
912
|
-
' on ' +
|
|
913
|
-
join(locations, ' | '),
|
|
914
|
-
},
|
|
915
|
-
SchemaExtension: {
|
|
916
|
-
leave: ({ directives, operationTypes }) => join(['extend schema', join(directives, ' '), block(operationTypes)], ' '),
|
|
917
|
-
},
|
|
918
|
-
ScalarTypeExtension: {
|
|
919
|
-
leave: ({ name, directives }) => join(['extend scalar', name, join(directives, ' ')], ' '),
|
|
920
|
-
},
|
|
921
|
-
ObjectTypeExtension: {
|
|
922
|
-
leave: ({ name, interfaces, directives, fields }) => join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
923
|
-
},
|
|
924
|
-
InterfaceTypeExtension: {
|
|
925
|
-
leave: ({ name, interfaces, directives, fields }) => join(['extend interface', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' '),
|
|
926
|
-
},
|
|
927
|
-
UnionTypeExtension: {
|
|
928
|
-
leave: ({ name, directives, types }) => join(['extend union', name, join(directives, ' '), wrap('= ', join(types, ' | '))], ' '),
|
|
929
|
-
},
|
|
930
|
-
EnumTypeExtension: {
|
|
931
|
-
leave: ({ name, directives, values }) => join(['extend enum', name, join(directives, ' '), block(values)], ' '),
|
|
932
|
-
},
|
|
933
|
-
InputObjectTypeExtension: {
|
|
934
|
-
leave: ({ name, directives, fields }) => join(['extend input', name, join(directives, ' '), block(fields)], ' '),
|
|
935
|
-
},
|
|
936
|
-
};
|
|
937
|
-
const printDocASTReducerWithComments = Object.keys(printDocASTReducer).reduce((prev, key) => ({
|
|
938
|
-
...prev,
|
|
939
|
-
[key]: {
|
|
940
|
-
leave: addDescription(printDocASTReducer[key].leave),
|
|
941
|
-
},
|
|
942
|
-
}), {});
|
|
943
|
-
|
|
944
941
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
945
942
|
function createSpiedPlugin() {
|
|
946
943
|
const afterResolver = jest.fn();
|
|
@@ -1052,29 +1049,21 @@ function createTestkit(pluginsOrEnvelop, schema) {
|
|
|
1052
1049
|
errors: [new GraphQLError('Could not identify main operation.')],
|
|
1053
1050
|
};
|
|
1054
1051
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
query:
|
|
1062
|
-
|
|
1063
|
-
query: print(document),
|
|
1064
|
-
variables: variableValues,
|
|
1065
|
-
},
|
|
1052
|
+
const contextValue = await proxy.contextFactory({
|
|
1053
|
+
request: {
|
|
1054
|
+
headers: {},
|
|
1055
|
+
method: 'POST',
|
|
1056
|
+
query: '',
|
|
1057
|
+
body: {
|
|
1058
|
+
query: print(document),
|
|
1059
|
+
variables: variableValues,
|
|
1066
1060
|
},
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
}
|
|
1073
|
-
catch (err) {
|
|
1074
|
-
return {
|
|
1075
|
-
errors: [toGraphQLErrorOrThrow(err)],
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1061
|
+
},
|
|
1062
|
+
document,
|
|
1063
|
+
operation: print(document),
|
|
1064
|
+
variables: variableValues,
|
|
1065
|
+
...initialContext,
|
|
1066
|
+
});
|
|
1078
1067
|
if (mainOperation.operation === 'subscription') {
|
|
1079
1068
|
return proxy.subscribe({
|
|
1080
1069
|
variableValues,
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/testing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0-alpha-290f8ac.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"graphql": "^14.0.0 || ^15.0.0
|
|
6
|
+
"graphql": "^14.0.0 || ^15.0.0"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/dotansimha/envelop.git",
|
|
11
|
+
"directory": "packages/testing"
|
|
7
12
|
},
|
|
8
13
|
"author": "Dotan Simha <dotansimha@gmail.com>",
|
|
9
14
|
"license": "MIT",
|