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