1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var visitor_1 = require("graphql/language/visitor");
|
5 | var apollo_utilities_1 = require("apollo-utilities");
|
6 | var ts_invariant_1 = require("ts-invariant");
|
7 | var capitalizeFirstLetter_1 = require("../util/capitalizeFirstLetter");
|
8 | var LocalState = (function () {
|
9 | function LocalState(_a) {
|
10 | var cache = _a.cache, client = _a.client, resolvers = _a.resolvers, fragmentMatcher = _a.fragmentMatcher;
|
11 | this.cache = cache;
|
12 | if (client) {
|
13 | this.client = client;
|
14 | }
|
15 | if (resolvers) {
|
16 | this.addResolvers(resolvers);
|
17 | }
|
18 | if (fragmentMatcher) {
|
19 | this.setFragmentMatcher(fragmentMatcher);
|
20 | }
|
21 | }
|
22 | LocalState.prototype.addResolvers = function (resolvers) {
|
23 | var _this = this;
|
24 | this.resolvers = this.resolvers || {};
|
25 | if (Array.isArray(resolvers)) {
|
26 | resolvers.forEach(function (resolverGroup) {
|
27 | _this.resolvers = apollo_utilities_1.mergeDeep(_this.resolvers, resolverGroup);
|
28 | });
|
29 | }
|
30 | else {
|
31 | this.resolvers = apollo_utilities_1.mergeDeep(this.resolvers, resolvers);
|
32 | }
|
33 | };
|
34 | LocalState.prototype.setResolvers = function (resolvers) {
|
35 | this.resolvers = {};
|
36 | this.addResolvers(resolvers);
|
37 | };
|
38 | LocalState.prototype.getResolvers = function () {
|
39 | return this.resolvers || {};
|
40 | };
|
41 | LocalState.prototype.runResolvers = function (_a) {
|
42 | var document = _a.document, remoteResult = _a.remoteResult, context = _a.context, variables = _a.variables, _b = _a.onlyRunForcedResolvers, onlyRunForcedResolvers = _b === void 0 ? false : _b;
|
43 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
44 | return tslib_1.__generator(this, function (_c) {
|
45 | if (document) {
|
46 | return [2, this.resolveDocument(document, remoteResult.data, context, variables, this.fragmentMatcher, onlyRunForcedResolvers).then(function (localResult) { return (tslib_1.__assign(tslib_1.__assign({}, remoteResult), { data: localResult.result })); })];
|
47 | }
|
48 | return [2, remoteResult];
|
49 | });
|
50 | });
|
51 | };
|
52 | LocalState.prototype.setFragmentMatcher = function (fragmentMatcher) {
|
53 | this.fragmentMatcher = fragmentMatcher;
|
54 | };
|
55 | LocalState.prototype.getFragmentMatcher = function () {
|
56 | return this.fragmentMatcher;
|
57 | };
|
58 | LocalState.prototype.clientQuery = function (document) {
|
59 | if (apollo_utilities_1.hasDirectives(['client'], document)) {
|
60 | if (this.resolvers) {
|
61 | return document;
|
62 | }
|
63 | ts_invariant_1.invariant.warn('Found @client directives in a query but no ApolloClient resolvers ' +
|
64 | 'were specified. This means ApolloClient local resolver handling ' +
|
65 | 'has been disabled, and @client directives will be passed through ' +
|
66 | 'to your link chain.');
|
67 | }
|
68 | return null;
|
69 | };
|
70 | LocalState.prototype.serverQuery = function (document) {
|
71 | return this.resolvers ? apollo_utilities_1.removeClientSetsFromDocument(document) : document;
|
72 | };
|
73 | LocalState.prototype.prepareContext = function (context) {
|
74 | if (context === void 0) { context = {}; }
|
75 | var cache = this.cache;
|
76 | var newContext = tslib_1.__assign(tslib_1.__assign({}, context), { cache: cache, getCacheKey: function (obj) {
|
77 | if (cache.config) {
|
78 | return cache.config.dataIdFromObject(obj);
|
79 | }
|
80 | else {
|
81 | ts_invariant_1.invariant(false, 'To use context.getCacheKey, you need to use a cache that has ' +
|
82 | 'a configurable dataIdFromObject, like apollo-cache-inmemory.');
|
83 | }
|
84 | } });
|
85 | return newContext;
|
86 | };
|
87 | LocalState.prototype.addExportedVariables = function (document, variables, context) {
|
88 | if (variables === void 0) { variables = {}; }
|
89 | if (context === void 0) { context = {}; }
|
90 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
91 | return tslib_1.__generator(this, function (_a) {
|
92 | if (document) {
|
93 | return [2, this.resolveDocument(document, this.buildRootValueFromCache(document, variables) || {}, this.prepareContext(context), variables).then(function (data) { return (tslib_1.__assign(tslib_1.__assign({}, variables), data.exportedVariables)); })];
|
94 | }
|
95 | return [2, tslib_1.__assign({}, variables)];
|
96 | });
|
97 | });
|
98 | };
|
99 | LocalState.prototype.shouldForceResolvers = function (document) {
|
100 | var forceResolvers = false;
|
101 | visitor_1.visit(document, {
|
102 | Directive: {
|
103 | enter: function (node) {
|
104 | if (node.name.value === 'client' && node.arguments) {
|
105 | forceResolvers = node.arguments.some(function (arg) {
|
106 | return arg.name.value === 'always' &&
|
107 | arg.value.kind === 'BooleanValue' &&
|
108 | arg.value.value === true;
|
109 | });
|
110 | if (forceResolvers) {
|
111 | return visitor_1.BREAK;
|
112 | }
|
113 | }
|
114 | },
|
115 | },
|
116 | });
|
117 | return forceResolvers;
|
118 | };
|
119 | LocalState.prototype.buildRootValueFromCache = function (document, variables) {
|
120 | return this.cache.diff({
|
121 | query: apollo_utilities_1.buildQueryFromSelectionSet(document),
|
122 | variables: variables,
|
123 | returnPartialData: true,
|
124 | optimistic: false,
|
125 | }).result;
|
126 | };
|
127 | LocalState.prototype.resolveDocument = function (document, rootValue, context, variables, fragmentMatcher, onlyRunForcedResolvers) {
|
128 | if (context === void 0) { context = {}; }
|
129 | if (variables === void 0) { variables = {}; }
|
130 | if (fragmentMatcher === void 0) { fragmentMatcher = function () { return true; }; }
|
131 | if (onlyRunForcedResolvers === void 0) { onlyRunForcedResolvers = false; }
|
132 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
133 | var mainDefinition, fragments, fragmentMap, definitionOperation, defaultOperationType, _a, cache, client, execContext;
|
134 | return tslib_1.__generator(this, function (_b) {
|
135 | mainDefinition = apollo_utilities_1.getMainDefinition(document);
|
136 | fragments = apollo_utilities_1.getFragmentDefinitions(document);
|
137 | fragmentMap = apollo_utilities_1.createFragmentMap(fragments);
|
138 | definitionOperation = mainDefinition
|
139 | .operation;
|
140 | defaultOperationType = definitionOperation
|
141 | ? capitalizeFirstLetter_1.capitalizeFirstLetter(definitionOperation)
|
142 | : 'Query';
|
143 | _a = this, cache = _a.cache, client = _a.client;
|
144 | execContext = {
|
145 | fragmentMap: fragmentMap,
|
146 | context: tslib_1.__assign(tslib_1.__assign({}, context), { cache: cache,
|
147 | client: client }),
|
148 | variables: variables,
|
149 | fragmentMatcher: fragmentMatcher,
|
150 | defaultOperationType: defaultOperationType,
|
151 | exportedVariables: {},
|
152 | onlyRunForcedResolvers: onlyRunForcedResolvers,
|
153 | };
|
154 | return [2, this.resolveSelectionSet(mainDefinition.selectionSet, rootValue, execContext).then(function (result) { return ({
|
155 | result: result,
|
156 | exportedVariables: execContext.exportedVariables,
|
157 | }); })];
|
158 | });
|
159 | });
|
160 | };
|
161 | LocalState.prototype.resolveSelectionSet = function (selectionSet, rootValue, execContext) {
|
162 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
163 | var fragmentMap, context, variables, resultsToMerge, execute;
|
164 | var _this = this;
|
165 | return tslib_1.__generator(this, function (_a) {
|
166 | fragmentMap = execContext.fragmentMap, context = execContext.context, variables = execContext.variables;
|
167 | resultsToMerge = [rootValue];
|
168 | execute = function (selection) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
169 | var fragment, typeCondition;
|
170 | return tslib_1.__generator(this, function (_a) {
|
171 | if (!apollo_utilities_1.shouldInclude(selection, variables)) {
|
172 | return [2];
|
173 | }
|
174 | if (apollo_utilities_1.isField(selection)) {
|
175 | return [2, this.resolveField(selection, rootValue, execContext).then(function (fieldResult) {
|
176 | var _a;
|
177 | if (typeof fieldResult !== 'undefined') {
|
178 | resultsToMerge.push((_a = {},
|
179 | _a[apollo_utilities_1.resultKeyNameFromField(selection)] = fieldResult,
|
180 | _a));
|
181 | }
|
182 | })];
|
183 | }
|
184 | if (apollo_utilities_1.isInlineFragment(selection)) {
|
185 | fragment = selection;
|
186 | }
|
187 | else {
|
188 | fragment = fragmentMap[selection.name.value];
|
189 | ts_invariant_1.invariant(fragment, "No fragment named " + selection.name.value);
|
190 | }
|
191 | if (fragment && fragment.typeCondition) {
|
192 | typeCondition = fragment.typeCondition.name.value;
|
193 | if (execContext.fragmentMatcher(rootValue, typeCondition, context)) {
|
194 | return [2, this.resolveSelectionSet(fragment.selectionSet, rootValue, execContext).then(function (fragmentResult) {
|
195 | resultsToMerge.push(fragmentResult);
|
196 | })];
|
197 | }
|
198 | }
|
199 | return [2];
|
200 | });
|
201 | }); };
|
202 | return [2, Promise.all(selectionSet.selections.map(execute)).then(function () {
|
203 | return apollo_utilities_1.mergeDeepArray(resultsToMerge);
|
204 | })];
|
205 | });
|
206 | });
|
207 | };
|
208 | LocalState.prototype.resolveField = function (field, rootValue, execContext) {
|
209 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
210 | var variables, fieldName, aliasedFieldName, aliasUsed, defaultResult, resultPromise, resolverType, resolverMap, resolve;
|
211 | var _this = this;
|
212 | return tslib_1.__generator(this, function (_a) {
|
213 | variables = execContext.variables;
|
214 | fieldName = field.name.value;
|
215 | aliasedFieldName = apollo_utilities_1.resultKeyNameFromField(field);
|
216 | aliasUsed = fieldName !== aliasedFieldName;
|
217 | defaultResult = rootValue[aliasedFieldName] || rootValue[fieldName];
|
218 | resultPromise = Promise.resolve(defaultResult);
|
219 | if (!execContext.onlyRunForcedResolvers ||
|
220 | this.shouldForceResolvers(field)) {
|
221 | resolverType = rootValue.__typename || execContext.defaultOperationType;
|
222 | resolverMap = this.resolvers && this.resolvers[resolverType];
|
223 | if (resolverMap) {
|
224 | resolve = resolverMap[aliasUsed ? fieldName : aliasedFieldName];
|
225 | if (resolve) {
|
226 | resultPromise = Promise.resolve(resolve(rootValue, apollo_utilities_1.argumentsObjectFromField(field, variables), execContext.context, { field: field, fragmentMap: execContext.fragmentMap }));
|
227 | }
|
228 | }
|
229 | }
|
230 | return [2, resultPromise.then(function (result) {
|
231 | if (result === void 0) { result = defaultResult; }
|
232 | if (field.directives) {
|
233 | field.directives.forEach(function (directive) {
|
234 | if (directive.name.value === 'export' && directive.arguments) {
|
235 | directive.arguments.forEach(function (arg) {
|
236 | if (arg.name.value === 'as' && arg.value.kind === 'StringValue') {
|
237 | execContext.exportedVariables[arg.value.value] = result;
|
238 | }
|
239 | });
|
240 | }
|
241 | });
|
242 | }
|
243 | if (!field.selectionSet) {
|
244 | return result;
|
245 | }
|
246 | if (result == null) {
|
247 | return result;
|
248 | }
|
249 | if (Array.isArray(result)) {
|
250 | return _this.resolveSubSelectedArray(field, result, execContext);
|
251 | }
|
252 | if (field.selectionSet) {
|
253 | return _this.resolveSelectionSet(field.selectionSet, result, execContext);
|
254 | }
|
255 | })];
|
256 | });
|
257 | });
|
258 | };
|
259 | LocalState.prototype.resolveSubSelectedArray = function (field, result, execContext) {
|
260 | var _this = this;
|
261 | return Promise.all(result.map(function (item) {
|
262 | if (item === null) {
|
263 | return null;
|
264 | }
|
265 | if (Array.isArray(item)) {
|
266 | return _this.resolveSubSelectedArray(field, item, execContext);
|
267 | }
|
268 | if (field.selectionSet) {
|
269 | return _this.resolveSelectionSet(field.selectionSet, item, execContext);
|
270 | }
|
271 | }));
|
272 | };
|
273 | return LocalState;
|
274 | }());
|
275 | exports.LocalState = LocalState;
|
276 |
|
\ | No newline at end of file |