1 | import { memoize5 } from './memoize.js';
|
2 | import { Kind, getDirectiveValues, GraphQLSkipDirective, GraphQLIncludeDirective, isAbstractType, typeFromAST, } from 'graphql';
|
3 |
|
4 | export function collectFields(schema, fragments, variableValues, runtimeType, selectionSet, fields, visitedFragmentNames) {
|
5 | for (const selection of selectionSet.selections) {
|
6 | switch (selection.kind) {
|
7 | case Kind.FIELD: {
|
8 | if (!shouldIncludeNode(variableValues, selection)) {
|
9 | continue;
|
10 | }
|
11 | const name = getFieldEntryKey(selection);
|
12 | const fieldList = fields.get(name);
|
13 | if (fieldList !== undefined) {
|
14 | fieldList.push(selection);
|
15 | }
|
16 | else {
|
17 | fields.set(name, [selection]);
|
18 | }
|
19 | break;
|
20 | }
|
21 | case Kind.INLINE_FRAGMENT: {
|
22 | if (!shouldIncludeNode(variableValues, selection) ||
|
23 | !doesFragmentConditionMatch(schema, selection, runtimeType)) {
|
24 | continue;
|
25 | }
|
26 | collectFields(schema, fragments, variableValues, runtimeType, selection.selectionSet, fields, visitedFragmentNames);
|
27 | break;
|
28 | }
|
29 | case Kind.FRAGMENT_SPREAD: {
|
30 | const fragName = selection.name.value;
|
31 | if (visitedFragmentNames.has(fragName) || !shouldIncludeNode(variableValues, selection)) {
|
32 | continue;
|
33 | }
|
34 | visitedFragmentNames.add(fragName);
|
35 | const fragment = fragments[fragName];
|
36 | if (!fragment || !doesFragmentConditionMatch(schema, fragment, runtimeType)) {
|
37 | continue;
|
38 | }
|
39 | collectFields(schema, fragments, variableValues, runtimeType, fragment.selectionSet, fields, visitedFragmentNames);
|
40 | break;
|
41 | }
|
42 | }
|
43 | }
|
44 | return fields;
|
45 | }
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | function shouldIncludeNode(variableValues, node) {
|
51 | const skip = getDirectiveValues(GraphQLSkipDirective, node, variableValues);
|
52 | if ((skip === null || skip === void 0 ? void 0 : skip['if']) === true) {
|
53 | return false;
|
54 | }
|
55 | const include = getDirectiveValues(GraphQLIncludeDirective, node, variableValues);
|
56 | if ((include === null || include === void 0 ? void 0 : include['if']) === false) {
|
57 | return false;
|
58 | }
|
59 | return true;
|
60 | }
|
61 |
|
62 |
|
63 |
|
64 | function doesFragmentConditionMatch(schema, fragment, type) {
|
65 | const typeConditionNode = fragment.typeCondition;
|
66 | if (!typeConditionNode) {
|
67 | return true;
|
68 | }
|
69 | const conditionalType = typeFromAST(schema, typeConditionNode);
|
70 | if (conditionalType === type) {
|
71 | return true;
|
72 | }
|
73 | if (isAbstractType(conditionalType)) {
|
74 | const possibleTypes = schema.getPossibleTypes(conditionalType);
|
75 | return possibleTypes.includes(type);
|
76 | }
|
77 | return false;
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 | function getFieldEntryKey(node) {
|
83 | return node.alias ? node.alias.value : node.name.value;
|
84 | }
|
85 | export const collectSubFields = memoize5(function collectSubFields(schema, fragments, variableValues, type, fieldNodes) {
|
86 | const subFieldNodes = new Map();
|
87 | const visitedFragmentNames = new Set();
|
88 | for (const fieldNode of fieldNodes) {
|
89 | if (fieldNode.selectionSet) {
|
90 | collectFields(schema, fragments, variableValues, type, fieldNode.selectionSet, subFieldNodes, visitedFragmentNames);
|
91 | }
|
92 | }
|
93 | return subFieldNodes;
|
94 | });
|