1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var tslib = require('tslib');
|
6 | var globals = require('../../utilities/globals');
|
7 | var graphql = require('graphql');
|
8 | var core = require('../core');
|
9 | var utilities = require('../../utilities');
|
10 |
|
11 | var VERSION = 1;
|
12 | exports.PersistedQueryLink = void 0;
|
13 | (function (PersistedQueryLink) {
|
14 | })(exports.PersistedQueryLink || (exports.PersistedQueryLink = {}));
|
15 | function collectErrorsByMessage(graphQLErrors) {
|
16 | var collected = Object.create(null);
|
17 | if (utilities.isNonEmptyArray(graphQLErrors)) {
|
18 | graphQLErrors.forEach(function (error) { return collected[error.message] = error; });
|
19 | }
|
20 | return collected;
|
21 | }
|
22 | var defaultOptions = {
|
23 | disable: function (_a) {
|
24 | var graphQLErrors = _a.graphQLErrors, operation = _a.operation;
|
25 | var errorMessages = collectErrorsByMessage(graphQLErrors);
|
26 | if (errorMessages.PersistedQueryNotSupported) {
|
27 | return true;
|
28 | }
|
29 | if (errorMessages.PersistedQueryNotFound) {
|
30 | return false;
|
31 | }
|
32 | var response = operation.getContext().response;
|
33 | if (response &&
|
34 | response.status &&
|
35 | (response.status === 400 || response.status === 500)) {
|
36 | return true;
|
37 | }
|
38 | return false;
|
39 | },
|
40 | useGETForHashedQueries: false,
|
41 | };
|
42 | function operationDefinesMutation(operation) {
|
43 | return operation.query.definitions.some(function (d) { return d.kind === 'OperationDefinition' && d.operation === 'mutation'; });
|
44 | }
|
45 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
46 | var hashesByQuery = new WeakMap();
|
47 | var nextHashesChildKey = 0;
|
48 | var createPersistedQueryLink = function (options) {
|
49 | __DEV__ ? globals.invariant(options && (typeof options.sha256 === 'function' ||
|
50 | typeof options.generateHash === 'function'), 'Missing/invalid "sha256" or "generateHash" function. Please ' +
|
51 | 'configure one using the "createPersistedQueryLink(options)" options ' +
|
52 | 'parameter.') : globals.invariant(options && (typeof options.sha256 === 'function' ||
|
53 | typeof options.generateHash === 'function'), 25);
|
54 | var _a = utilities.compact(defaultOptions, options), sha256 = _a.sha256, _b = _a.generateHash, generateHash = _b === void 0 ? function (query) {
|
55 | return Promise.resolve(sha256(graphql.print(query)));
|
56 | } : _b, disable = _a.disable, useGETForHashedQueries = _a.useGETForHashedQueries;
|
57 | var supportsPersistedQueries = true;
|
58 | var hashesChildKey = 'forLink' + nextHashesChildKey++;
|
59 | var getHashPromise = function (query) {
|
60 | return new Promise(function (resolve) { return resolve(generateHash(query)); });
|
61 | };
|
62 | function getQueryHash(query) {
|
63 | if (!query || typeof query !== 'object') {
|
64 | return getHashPromise(query);
|
65 | }
|
66 | var hashes = hashesByQuery.get(query);
|
67 | if (!hashes)
|
68 | hashesByQuery.set(query, hashes = Object.create(null));
|
69 | return hasOwnProperty.call(hashes, hashesChildKey)
|
70 | ? hashes[hashesChildKey]
|
71 | : hashes[hashesChildKey] = getHashPromise(query);
|
72 | }
|
73 | return new core.ApolloLink(function (operation, forward) {
|
74 | __DEV__ ? globals.invariant(forward, 'PersistedQueryLink cannot be the last link in the chain.') : globals.invariant(forward, 26);
|
75 | var query = operation.query;
|
76 | return new utilities.Observable(function (observer) {
|
77 | var subscription;
|
78 | var retried = false;
|
79 | var originalFetchOptions;
|
80 | var setFetchOptions = false;
|
81 | var retry = function (_a, cb) {
|
82 | var response = _a.response, networkError = _a.networkError;
|
83 | if (!retried && ((response && response.errors) || networkError)) {
|
84 | retried = true;
|
85 | var graphQLErrors = [];
|
86 | var responseErrors = response && response.errors;
|
87 | if (utilities.isNonEmptyArray(responseErrors)) {
|
88 | graphQLErrors.push.apply(graphQLErrors, responseErrors);
|
89 | }
|
90 | var networkErrors = networkError &&
|
91 | networkError.result &&
|
92 | networkError.result.errors;
|
93 | if (utilities.isNonEmptyArray(networkErrors)) {
|
94 | graphQLErrors.push.apply(graphQLErrors, networkErrors);
|
95 | }
|
96 | var disablePayload = {
|
97 | response: response,
|
98 | networkError: networkError,
|
99 | operation: operation,
|
100 | graphQLErrors: utilities.isNonEmptyArray(graphQLErrors) ? graphQLErrors : void 0,
|
101 | };
|
102 | supportsPersistedQueries = !disable(disablePayload);
|
103 | if (collectErrorsByMessage(graphQLErrors).PersistedQueryNotFound ||
|
104 | !supportsPersistedQueries) {
|
105 | if (subscription)
|
106 | subscription.unsubscribe();
|
107 | operation.setContext({
|
108 | http: {
|
109 | includeQuery: true,
|
110 | includeExtensions: supportsPersistedQueries,
|
111 | },
|
112 | fetchOptions: {
|
113 | method: 'POST',
|
114 | },
|
115 | });
|
116 | if (setFetchOptions) {
|
117 | operation.setContext({ fetchOptions: originalFetchOptions });
|
118 | }
|
119 | subscription = forward(operation).subscribe(handler);
|
120 | return;
|
121 | }
|
122 | }
|
123 | cb();
|
124 | };
|
125 | var handler = {
|
126 | next: function (response) {
|
127 | retry({ response: response }, function () { return observer.next(response); });
|
128 | },
|
129 | error: function (networkError) {
|
130 | retry({ networkError: networkError }, function () { return observer.error(networkError); });
|
131 | },
|
132 | complete: observer.complete.bind(observer),
|
133 | };
|
134 | operation.setContext({
|
135 | http: {
|
136 | includeQuery: !supportsPersistedQueries,
|
137 | includeExtensions: supportsPersistedQueries,
|
138 | },
|
139 | });
|
140 | if (useGETForHashedQueries &&
|
141 | supportsPersistedQueries &&
|
142 | !operationDefinesMutation(operation)) {
|
143 | operation.setContext(function (_a) {
|
144 | var _b = _a.fetchOptions, fetchOptions = _b === void 0 ? {} : _b;
|
145 | originalFetchOptions = fetchOptions;
|
146 | return {
|
147 | fetchOptions: tslib.__assign(tslib.__assign({}, fetchOptions), { method: 'GET' }),
|
148 | };
|
149 | });
|
150 | setFetchOptions = true;
|
151 | }
|
152 | if (supportsPersistedQueries) {
|
153 | getQueryHash(query).then(function (sha256Hash) {
|
154 | operation.extensions.persistedQuery = {
|
155 | version: VERSION,
|
156 | sha256Hash: sha256Hash,
|
157 | };
|
158 | subscription = forward(operation).subscribe(handler);
|
159 | }).catch(observer.error.bind(observer));
|
160 | }
|
161 | else {
|
162 | subscription = forward(operation).subscribe(handler);
|
163 | }
|
164 | return function () {
|
165 | if (subscription)
|
166 | subscription.unsubscribe();
|
167 | };
|
168 | });
|
169 | });
|
170 | };
|
171 |
|
172 | exports.VERSION = VERSION;
|
173 | exports.createPersistedQueryLink = createPersistedQueryLink;
|
174 |
|