1 | var __assign = (this && this.__assign) || function () {
|
2 | __assign = Object.assign || function(t) {
|
3 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4 | s = arguments[i];
|
5 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6 | t[p] = s[p];
|
7 | }
|
8 | return t;
|
9 | };
|
10 | return __assign.apply(this, arguments);
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var graphql_1 = require("graphql");
|
14 | var implementsAbstractType_1 = require("../implementsAbstractType");
|
15 | var FilterToSchema = (function () {
|
16 | function FilterToSchema(targetSchema) {
|
17 | this.targetSchema = targetSchema;
|
18 | }
|
19 | FilterToSchema.prototype.transformRequest = function (originalRequest) {
|
20 | var document = filterDocumentToSchema(this.targetSchema, originalRequest.document);
|
21 | return __assign({}, originalRequest, { document: document });
|
22 | };
|
23 | return FilterToSchema;
|
24 | }());
|
25 | exports.default = FilterToSchema;
|
26 | function filterDocumentToSchema(targetSchema, document) {
|
27 | var operations = document.definitions.filter(function (def) { return def.kind === graphql_1.Kind.OPERATION_DEFINITION; });
|
28 | var fragments = document.definitions.filter(function (def) { return def.kind === graphql_1.Kind.FRAGMENT_DEFINITION; });
|
29 | var usedFragments = [];
|
30 | var newOperations = [];
|
31 | var newFragments = [];
|
32 | var validFragments = fragments.filter(function (fragment) {
|
33 | var typeName = fragment.typeCondition.name.value;
|
34 | return Boolean(targetSchema.getType(typeName));
|
35 | });
|
36 | var validFragmentsWithType = {};
|
37 | validFragments.forEach(function (fragment) {
|
38 | var typeName = fragment.typeCondition.name.value;
|
39 | var type = targetSchema.getType(typeName);
|
40 | validFragmentsWithType[fragment.name.value] = type;
|
41 | });
|
42 | var fragmentSet = Object.create(null);
|
43 | operations.forEach(function (operation) {
|
44 | var type;
|
45 | if (operation.operation === 'subscription') {
|
46 | type = targetSchema.getSubscriptionType();
|
47 | }
|
48 | else if (operation.operation === 'mutation') {
|
49 | type = targetSchema.getMutationType();
|
50 | }
|
51 | else {
|
52 | type = targetSchema.getQueryType();
|
53 | }
|
54 | var _a = filterSelectionSet(targetSchema, type, validFragmentsWithType, operation.selectionSet), selectionSet = _a.selectionSet, operationUsedFragments = _a.usedFragments, operationUsedVariables = _a.usedVariables;
|
55 | usedFragments = union(usedFragments, operationUsedFragments);
|
56 | var _b = collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments), collectedUsedVariables = _b.usedVariables, collectedNewFragments = _b.newFragments, collectedFragmentSet = _b.fragmentSet;
|
57 | var fullUsedVariables = union(operationUsedVariables, collectedUsedVariables);
|
58 | newFragments = collectedNewFragments;
|
59 | fragmentSet = collectedFragmentSet;
|
60 | var variableDefinitions = operation.variableDefinitions.filter(function (variable) {
|
61 | return fullUsedVariables.indexOf(variable.variable.name.value) !== -1;
|
62 | });
|
63 | newOperations.push({
|
64 | kind: graphql_1.Kind.OPERATION_DEFINITION,
|
65 | operation: operation.operation,
|
66 | name: operation.name,
|
67 | directives: operation.directives,
|
68 | variableDefinitions: variableDefinitions,
|
69 | selectionSet: selectionSet,
|
70 | });
|
71 | });
|
72 | return {
|
73 | kind: graphql_1.Kind.DOCUMENT,
|
74 | definitions: newOperations.concat(newFragments),
|
75 | };
|
76 | }
|
77 | function collectFragmentVariables(targetSchema, fragmentSet, validFragments, validFragmentsWithType, usedFragments) {
|
78 | var usedVariables = [];
|
79 | var newFragments = [];
|
80 | var _loop_1 = function () {
|
81 | var nextFragmentName = usedFragments.pop();
|
82 | var fragment = validFragments.find(function (fr) { return fr.name.value === nextFragmentName; });
|
83 | if (fragment) {
|
84 | var name_1 = nextFragmentName;
|
85 | var typeName = fragment.typeCondition.name.value;
|
86 | var type = targetSchema.getType(typeName);
|
87 | var _a = filterSelectionSet(targetSchema, type, validFragmentsWithType, fragment.selectionSet), selectionSet = _a.selectionSet, fragmentUsedFragments = _a.usedFragments, fragmentUsedVariables = _a.usedVariables;
|
88 | usedFragments = union(usedFragments, fragmentUsedFragments);
|
89 | usedVariables = union(usedVariables, fragmentUsedVariables);
|
90 | if (!fragmentSet[name_1]) {
|
91 | fragmentSet[name_1] = true;
|
92 | newFragments.push({
|
93 | kind: graphql_1.Kind.FRAGMENT_DEFINITION,
|
94 | name: {
|
95 | kind: graphql_1.Kind.NAME,
|
96 | value: name_1,
|
97 | },
|
98 | typeCondition: fragment.typeCondition,
|
99 | selectionSet: selectionSet,
|
100 | });
|
101 | }
|
102 | }
|
103 | };
|
104 | while (usedFragments.length !== 0) {
|
105 | _loop_1();
|
106 | }
|
107 | return {
|
108 | usedVariables: usedVariables,
|
109 | newFragments: newFragments,
|
110 | fragmentSet: fragmentSet,
|
111 | };
|
112 | }
|
113 | function filterSelectionSet(schema, type, validFragments, selectionSet) {
|
114 | var _a;
|
115 | var usedFragments = [];
|
116 | var usedVariables = [];
|
117 | var typeStack = [type];
|
118 |
|
119 | var filteredSelectionSet = graphql_1.visit(selectionSet, (_a = {},
|
120 | _a[graphql_1.Kind.FIELD] = {
|
121 | enter: function (node) {
|
122 | var parentType = resolveType(typeStack[typeStack.length - 1]);
|
123 | if (parentType instanceof graphql_1.GraphQLObjectType ||
|
124 | parentType instanceof graphql_1.GraphQLInterfaceType) {
|
125 | var fields = parentType.getFields();
|
126 | var field = node.name.value === '__typename'
|
127 | ? graphql_1.TypeNameMetaFieldDef
|
128 | : fields[node.name.value];
|
129 | if (!field) {
|
130 | return null;
|
131 | }
|
132 | else {
|
133 | typeStack.push(field.type);
|
134 | }
|
135 | var argNames_1 = (field.args || []).map(function (arg) { return arg.name; });
|
136 | if (node.arguments) {
|
137 | var args = node.arguments.filter(function (arg) {
|
138 | return argNames_1.indexOf(arg.name.value) !== -1;
|
139 | });
|
140 | if (args.length !== node.arguments.length) {
|
141 | return __assign({}, node, { arguments: args });
|
142 | }
|
143 | }
|
144 | }
|
145 | else if (parentType instanceof graphql_1.GraphQLUnionType &&
|
146 | node.name.value === '__typename') {
|
147 | typeStack.push(graphql_1.TypeNameMetaFieldDef.type);
|
148 | }
|
149 | },
|
150 | leave: function (node) {
|
151 | var _a;
|
152 | var currentType = typeStack.pop();
|
153 | var resolvedType = resolveType(currentType);
|
154 | if (resolvedType instanceof graphql_1.GraphQLObjectType ||
|
155 | resolvedType instanceof graphql_1.GraphQLInterfaceType) {
|
156 | var selections = node.selectionSet && node.selectionSet.selections || null;
|
157 | if (!selections || selections.length === 0) {
|
158 |
|
159 | graphql_1.visit(node, (_a = {},
|
160 | _a[graphql_1.Kind.VARIABLE] = function (variableNode) {
|
161 | var index = usedVariables.indexOf(variableNode.name.value);
|
162 | if (index !== -1) {
|
163 | usedVariables.splice(index, 1);
|
164 | }
|
165 | },
|
166 | _a));
|
167 | return null;
|
168 | }
|
169 | }
|
170 | },
|
171 | },
|
172 | _a[graphql_1.Kind.FRAGMENT_SPREAD] = function (node) {
|
173 | if (node.name.value in validFragments) {
|
174 | var parentType = resolveType(typeStack[typeStack.length - 1]);
|
175 | var innerType = validFragments[node.name.value];
|
176 | if (!implementsAbstractType_1.default(schema, parentType, innerType)) {
|
177 | return null;
|
178 | }
|
179 | else {
|
180 | usedFragments.push(node.name.value);
|
181 | return;
|
182 | }
|
183 | }
|
184 | else {
|
185 | return null;
|
186 | }
|
187 | },
|
188 | _a[graphql_1.Kind.INLINE_FRAGMENT] = {
|
189 | enter: function (node) {
|
190 | if (node.typeCondition) {
|
191 | var innerType = schema.getType(node.typeCondition.name.value);
|
192 | var parentType = resolveType(typeStack[typeStack.length - 1]);
|
193 | if (implementsAbstractType_1.default(schema, parentType, innerType)) {
|
194 | typeStack.push(innerType);
|
195 | }
|
196 | else {
|
197 | return null;
|
198 | }
|
199 | }
|
200 | },
|
201 | leave: function (node) {
|
202 | typeStack.pop();
|
203 | },
|
204 | },
|
205 | _a[graphql_1.Kind.VARIABLE] = function (node) {
|
206 | usedVariables.push(node.name.value);
|
207 | },
|
208 | _a));
|
209 | return {
|
210 | selectionSet: filteredSelectionSet,
|
211 | usedFragments: usedFragments,
|
212 | usedVariables: usedVariables,
|
213 | };
|
214 | }
|
215 | function resolveType(type) {
|
216 | var lastType = type;
|
217 | while (lastType instanceof graphql_1.GraphQLNonNull ||
|
218 | lastType instanceof graphql_1.GraphQLList) {
|
219 | lastType = lastType.ofType;
|
220 | }
|
221 | return lastType;
|
222 | }
|
223 | function union() {
|
224 | var arrays = [];
|
225 | for (var _i = 0; _i < arguments.length; _i++) {
|
226 | arrays[_i] = arguments[_i];
|
227 | }
|
228 | var cache = {};
|
229 | var result = [];
|
230 | arrays.forEach(function (array) {
|
231 | array.forEach(function (item) {
|
232 | if (!cache[item]) {
|
233 | cache[item] = true;
|
234 | result.push(item);
|
235 | }
|
236 | });
|
237 | });
|
238 | return result;
|
239 | }
|
240 |
|
\ | No newline at end of file |