1 | import { ApolloLink, Observable } from 'apollo-link';
|
2 | var sha256 = require('hash.js/lib/hash/sha/256');
|
3 | import { print } from 'graphql/language/printer';
|
4 | export var VERSION = 1;
|
5 | export var defaultGenerateHash = function (query) {
|
6 | return sha256()
|
7 | .update(print(query))
|
8 | .digest('hex');
|
9 | };
|
10 | export var defaultOptions = {
|
11 | generateHash: defaultGenerateHash,
|
12 | disable: function (_a) {
|
13 | var graphQLErrors = _a.graphQLErrors, operation = _a.operation;
|
14 | if (graphQLErrors &&
|
15 | graphQLErrors.some(function (_a) {
|
16 | var message = _a.message;
|
17 | return message === 'PersistedQueryNotSupported';
|
18 | })) {
|
19 | return true;
|
20 | }
|
21 | var response = operation.getContext().response;
|
22 | if (response &&
|
23 | response.status &&
|
24 | (response.status === 400 || response.status === 500)) {
|
25 | return true;
|
26 | }
|
27 | return false;
|
28 | },
|
29 | useGETForHashedQueries: false,
|
30 | };
|
31 | function definitionIsMutation(d) {
|
32 | return d.kind === 'OperationDefinition' && d.operation === 'mutation';
|
33 | }
|
34 | function operationIsQuery(operation) {
|
35 | return !operation.query.definitions.some(definitionIsMutation);
|
36 | }
|
37 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
38 | var hashesKeyString = '__createPersistedQueryLink_hashes';
|
39 | var hashesKey = typeof Symbol === 'function' ? Symbol.for(hashesKeyString) : hashesKeyString;
|
40 | var nextHashesChildKey = 0;
|
41 | export var createPersistedQueryLink = function (options) {
|
42 | if (options === void 0) { options = {}; }
|
43 | var _a = Object.assign({}, defaultOptions, options), generateHash = _a.generateHash, disable = _a.disable, useGETForHashedQueries = _a.useGETForHashedQueries;
|
44 | var supportsPersistedQueries = true;
|
45 | var hashesChildKey = 'forLink' + nextHashesChildKey++;
|
46 | function getQueryHash(query) {
|
47 | if (!query || typeof query !== 'object') {
|
48 | return generateHash(query);
|
49 | }
|
50 | if (!hasOwnProperty.call(query, hashesKey)) {
|
51 | Object.defineProperty(query, hashesKey, {
|
52 | value: Object.create(null),
|
53 | enumerable: false,
|
54 | });
|
55 | }
|
56 | var hashes = query[hashesKey];
|
57 | return hasOwnProperty.call(hashes, hashesChildKey)
|
58 | ? hashes[hashesChildKey]
|
59 | : (hashes[hashesChildKey] = generateHash(query));
|
60 | }
|
61 | return new ApolloLink(function (operation, forward) {
|
62 | if (!forward) {
|
63 | throw new Error('PersistedQueryLink cannot be the last link in the chain.');
|
64 | }
|
65 | var query = operation.query;
|
66 | var hashError;
|
67 | if (supportsPersistedQueries) {
|
68 | try {
|
69 | operation.extensions.persistedQuery = {
|
70 | version: VERSION,
|
71 | sha256Hash: getQueryHash(query),
|
72 | };
|
73 | }
|
74 | catch (e) {
|
75 | hashError = e;
|
76 | }
|
77 | }
|
78 | return new Observable(function (observer) {
|
79 | if (hashError) {
|
80 | observer.error(hashError);
|
81 | return;
|
82 | }
|
83 | var subscription;
|
84 | var retried = false;
|
85 | var originalFetchOptions;
|
86 | var setFetchOptions = false;
|
87 | var retry = function (_a, cb) {
|
88 | var response = _a.response, networkError = _a.networkError;
|
89 | if (!retried && ((response && response.errors) || networkError)) {
|
90 | retried = true;
|
91 | supportsPersistedQueries = !disable({
|
92 | response: response,
|
93 | networkError: networkError,
|
94 | operation: operation,
|
95 | graphQLErrors: (response && response.errors) || void 0,
|
96 | });
|
97 | if ((response &&
|
98 | response.errors &&
|
99 | response.errors.some(function (_a) {
|
100 | var message = _a.message;
|
101 | return message === 'PersistedQueryNotFound';
|
102 | })) ||
|
103 | !supportsPersistedQueries) {
|
104 | if (subscription)
|
105 | subscription.unsubscribe();
|
106 | operation.setContext({
|
107 | http: {
|
108 | includeQuery: true,
|
109 | includeExtensions: supportsPersistedQueries,
|
110 | },
|
111 | });
|
112 | if (setFetchOptions) {
|
113 | operation.setContext({ fetchOptions: originalFetchOptions });
|
114 | }
|
115 | subscription = forward(operation).subscribe(handler);
|
116 | return;
|
117 | }
|
118 | }
|
119 | cb();
|
120 | };
|
121 | var handler = {
|
122 | next: function (response) {
|
123 | retry({ response: response }, function () { return observer.next(response); });
|
124 | },
|
125 | error: function (networkError) {
|
126 | retry({ networkError: networkError }, function () { return observer.error(networkError); });
|
127 | },
|
128 | complete: observer.complete.bind(observer),
|
129 | };
|
130 | operation.setContext({
|
131 | http: {
|
132 | includeQuery: !supportsPersistedQueries,
|
133 | includeExtensions: supportsPersistedQueries,
|
134 | },
|
135 | });
|
136 | if (useGETForHashedQueries &&
|
137 | supportsPersistedQueries &&
|
138 | operationIsQuery(operation)) {
|
139 | operation.setContext(function (_a) {
|
140 | var _b = _a.fetchOptions, fetchOptions = _b === void 0 ? {} : _b;
|
141 | originalFetchOptions = fetchOptions;
|
142 | return {
|
143 | fetchOptions: Object.assign({}, fetchOptions, { method: 'GET' }),
|
144 | };
|
145 | });
|
146 | setFetchOptions = true;
|
147 | }
|
148 | subscription = forward(operation).subscribe(handler);
|
149 | return function () {
|
150 | if (subscription)
|
151 | subscription.unsubscribe();
|
152 | };
|
153 | });
|
154 | });
|
155 | };
|
156 |
|
\ | No newline at end of file |