1 | import { getMainDefinition, getFragmentDefinitions, createFragmentMap, shouldInclude, isField, resultKeyNameFromField, isInlineFragment, argumentsObjectFromField, getDirectiveInfoFromField, getInclusionDirectives } from 'apollo-utilities';
|
2 | import { invariant } from 'ts-invariant';
|
3 |
|
4 | function graphql(resolver, document, rootValue, contextValue, variableValues, execOptions) {
|
5 | if (variableValues === void 0) { variableValues = {}; }
|
6 | if (execOptions === void 0) { execOptions = {}; }
|
7 | var mainDefinition = getMainDefinition(document);
|
8 | var fragments = getFragmentDefinitions(document);
|
9 | var fragmentMap = createFragmentMap(fragments);
|
10 | var resultMapper = execOptions.resultMapper;
|
11 | var fragmentMatcher = execOptions.fragmentMatcher || (function () { return true; });
|
12 | var execContext = {
|
13 | fragmentMap: fragmentMap,
|
14 | contextValue: contextValue,
|
15 | variableValues: variableValues,
|
16 | resultMapper: resultMapper,
|
17 | resolver: resolver,
|
18 | fragmentMatcher: fragmentMatcher,
|
19 | };
|
20 | return executeSelectionSet(mainDefinition.selectionSet, rootValue, execContext);
|
21 | }
|
22 | function executeSelectionSet(selectionSet, rootValue, execContext) {
|
23 | var fragmentMap = execContext.fragmentMap, contextValue = execContext.contextValue, variables = execContext.variableValues;
|
24 | var result = {};
|
25 | selectionSet.selections.forEach(function (selection) {
|
26 | if (variables && !shouldInclude(selection, variables)) {
|
27 | return;
|
28 | }
|
29 | if (isField(selection)) {
|
30 | var fieldResult = executeField(selection, rootValue, execContext);
|
31 | var resultFieldKey = resultKeyNameFromField(selection);
|
32 | if (fieldResult !== undefined) {
|
33 | if (result[resultFieldKey] === undefined) {
|
34 | result[resultFieldKey] = fieldResult;
|
35 | }
|
36 | else {
|
37 | merge(result[resultFieldKey], fieldResult);
|
38 | }
|
39 | }
|
40 | }
|
41 | else {
|
42 | var fragment = void 0;
|
43 | if (isInlineFragment(selection)) {
|
44 | fragment = selection;
|
45 | }
|
46 | else {
|
47 | fragment = fragmentMap[selection.name.value];
|
48 | if (!fragment) {
|
49 | throw new Error("No fragment named " + selection.name.value);
|
50 | }
|
51 | }
|
52 | var typeCondition = fragment.typeCondition.name.value;
|
53 | if (execContext.fragmentMatcher(rootValue, typeCondition, contextValue)) {
|
54 | var fragmentResult = executeSelectionSet(fragment.selectionSet, rootValue, execContext);
|
55 | merge(result, fragmentResult);
|
56 | }
|
57 | }
|
58 | });
|
59 | if (execContext.resultMapper) {
|
60 | return execContext.resultMapper(result, rootValue);
|
61 | }
|
62 | return result;
|
63 | }
|
64 | function executeField(field, rootValue, execContext) {
|
65 | var variables = execContext.variableValues, contextValue = execContext.contextValue, resolver = execContext.resolver;
|
66 | var fieldName = field.name.value;
|
67 | var args = argumentsObjectFromField(field, variables);
|
68 | var info = {
|
69 | isLeaf: !field.selectionSet,
|
70 | resultKey: resultKeyNameFromField(field),
|
71 | directives: getDirectiveInfoFromField(field, variables),
|
72 | field: field,
|
73 | };
|
74 | var result = resolver(fieldName, rootValue, args, contextValue, info);
|
75 | if (!field.selectionSet) {
|
76 | return result;
|
77 | }
|
78 | if (result == null) {
|
79 | return result;
|
80 | }
|
81 | if (Array.isArray(result)) {
|
82 | return executeSubSelectedArray(field, result, execContext);
|
83 | }
|
84 | return executeSelectionSet(field.selectionSet, result, execContext);
|
85 | }
|
86 | function executeSubSelectedArray(field, result, execContext) {
|
87 | return result.map(function (item) {
|
88 | if (item === null) {
|
89 | return null;
|
90 | }
|
91 | if (Array.isArray(item)) {
|
92 | return executeSubSelectedArray(field, item, execContext);
|
93 | }
|
94 | return executeSelectionSet(field.selectionSet, item, execContext);
|
95 | });
|
96 | }
|
97 | var hasOwn = Object.prototype.hasOwnProperty;
|
98 | function merge(dest, src) {
|
99 | if (src !== null && typeof src === 'object') {
|
100 | Object.keys(src).forEach(function (key) {
|
101 | var srcVal = src[key];
|
102 | if (!hasOwn.call(dest, key)) {
|
103 | dest[key] = srcVal;
|
104 | }
|
105 | else {
|
106 | merge(dest[key], srcVal);
|
107 | }
|
108 | });
|
109 | }
|
110 | }
|
111 |
|
112 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
113 | function filter(doc, data, variableValues) {
|
114 | if (variableValues === void 0) { variableValues = {}; }
|
115 | if (data === null)
|
116 | return data;
|
117 | var resolver = function (fieldName, root, args, context, info) {
|
118 | return root[info.resultKey];
|
119 | };
|
120 | return Array.isArray(data)
|
121 | ? data.map(function (dataObj) { return graphql(resolver, doc, dataObj, null, variableValues); })
|
122 | : graphql(resolver, doc, data, null, variableValues);
|
123 | }
|
124 | function check(doc, data, variables) {
|
125 | if (variables === void 0) { variables = {}; }
|
126 | var resolver = function (fieldName, root, args, context, info) {
|
127 | process.env.NODE_ENV === "production" ? invariant(hasOwnProperty.call(root, info.resultKey) ||
|
128 | (!variables && hasVariableInclusions(info.field.directives)), 1) : invariant(hasOwnProperty.call(root, info.resultKey) ||
|
129 | (!variables && hasVariableInclusions(info.field.directives)), info.resultKey + " missing on " + JSON.stringify(root));
|
130 | return root[info.resultKey];
|
131 | };
|
132 | graphql(resolver, doc, data, {}, variables, {
|
133 | fragmentMatcher: function () { return false; },
|
134 | });
|
135 | }
|
136 | function hasVariableInclusions(directives) {
|
137 | return getInclusionDirectives(directives).some(function (_a) {
|
138 | var ifArgument = _a.ifArgument;
|
139 | return ifArgument.value && ifArgument.value.kind === 'Variable';
|
140 | });
|
141 | }
|
142 | var ANONYMOUS = '<<anonymous>>';
|
143 | function PropTypeError(message) {
|
144 | this.message = message;
|
145 | this.stack = '';
|
146 | }
|
147 | PropTypeError.prototype = Error.prototype;
|
148 | var reactPropTypeLocationNames = {
|
149 | prop: 'prop',
|
150 | context: 'context',
|
151 | childContext: 'child context',
|
152 | };
|
153 | function createChainableTypeChecker(validate) {
|
154 | function checkType(isRequired, props, propName, componentName, location, propFullName) {
|
155 | componentName = componentName || ANONYMOUS;
|
156 | propFullName = propFullName || propName;
|
157 | if (props[propName] == null) {
|
158 | var locationName = reactPropTypeLocationNames[location];
|
159 | if (isRequired) {
|
160 | if (props[propName] === null) {
|
161 | return new PropTypeError("The " + locationName + " `" + propFullName + "` is marked as required " +
|
162 | ("in `" + componentName + "`, but its value is `null`."));
|
163 | }
|
164 | return new PropTypeError("The " + locationName + " `" + propFullName + "` is marked as required in " +
|
165 | ("`" + componentName + "`, but its value is `undefined`."));
|
166 | }
|
167 | return null;
|
168 | }
|
169 | else {
|
170 | return validate(props, propName, componentName, location, propFullName);
|
171 | }
|
172 | }
|
173 | var chainedCheckType = checkType.bind(null, false);
|
174 | chainedCheckType.isRequired = checkType.bind(null, true);
|
175 | return chainedCheckType;
|
176 | }
|
177 | function propType(doc, mapPropsToVariables) {
|
178 | if (mapPropsToVariables === void 0) { mapPropsToVariables = function (props) { return null; }; }
|
179 | return createChainableTypeChecker(function (props, propName) {
|
180 | var prop = props[propName];
|
181 | try {
|
182 | if (!prop.loading) {
|
183 | check(doc, prop, mapPropsToVariables(props));
|
184 | }
|
185 | return null;
|
186 | }
|
187 | catch (e) {
|
188 | return e;
|
189 | }
|
190 | });
|
191 | }
|
192 |
|
193 | export default graphql;
|
194 | export { check, filter, propType };
|
195 |
|