Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(core): support Headers being passed in fetchOptions (#3505)

authored by

Jovi De Croock and committed by
GitHub
973da7ff 492af087

+80 -3
+5
.changeset/fluffy-poets-protect.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Correctly support the `Headers` class being used in `fetchOptions`
+46
packages/core/src/internal/fetchOptions.test.ts
··· 125 125 `); 126 126 }); 127 127 128 + it('handles the Headers object', () => { 129 + const headers = new Headers(); 130 + headers.append('x-test', 'true'); 131 + const operation = makeOperation(queryOperation.kind, queryOperation, { 132 + ...queryOperation.context, 133 + fetchOptions: { 134 + headers, 135 + }, 136 + }); 137 + const body = makeFetchBody(operation); 138 + 139 + expect(makeFetchOptions(operation, body)).toMatchInlineSnapshot(` 140 + { 141 + "body": "{\\"operationName\\":\\"getUser\\",\\"query\\":\\"query getUser($name: String) {\\\\n user(name: $name) {\\\\n id\\\\n firstName\\\\n lastName\\\\n }\\\\n}\\",\\"variables\\":{\\"name\\":\\"Clara\\"}}", 142 + "headers": { 143 + "accept": "application/graphql-response+json, application/graphql+json, application/json, text/event-stream, multipart/mixed", 144 + "content-type": "application/json", 145 + "x-test": "true", 146 + }, 147 + "method": "POST", 148 + } 149 + `); 150 + }); 151 + 152 + it('handles an Array headers init', () => { 153 + const operation = makeOperation(queryOperation.kind, queryOperation, { 154 + ...queryOperation.context, 155 + fetchOptions: { 156 + headers: [['x-test', 'true']], 157 + }, 158 + }); 159 + const body = makeFetchBody(operation); 160 + 161 + expect(makeFetchOptions(operation, body)).toMatchInlineSnapshot(` 162 + { 163 + "body": "{\\"operationName\\":\\"getUser\\",\\"query\\":\\"query getUser($name: String) {\\\\n user(name: $name) {\\\\n id\\\\n firstName\\\\n lastName\\\\n }\\\\n}\\",\\"variables\\":{\\"name\\":\\"Clara\\"}}", 164 + "headers": { 165 + "accept": "application/graphql-response+json, application/graphql+json, application/json, text/event-stream, multipart/mixed", 166 + "content-type": "application/json", 167 + "x-test": "true", 168 + }, 169 + "method": "POST", 170 + } 171 + `); 172 + }); 173 + 128 174 it('creates a GET request when preferred for query operations', () => { 129 175 const operation = makeOperation(queryOperation.kind, queryOperation, { 130 176 ...queryOperation.context,
+29 -3
packages/core/src/internal/fetchOptions.ts
··· 118 118 } 119 119 }; 120 120 121 + const isHeaders = (headers: HeadersInit): headers is Headers => 122 + 'has' in headers && !Object.keys(headers).length; 123 + 121 124 /** Creates a `RequestInit` object for a given `Operation`. 122 125 * 123 126 * @param operation - An {@link Operation} for which to make the request. ··· 145 148 (typeof operation.context.fetchOptions === 'function' 146 149 ? operation.context.fetchOptions() 147 150 : operation.context.fetchOptions) || {}; 148 - if (extraOptions.headers) 149 - for (const key in extraOptions.headers) 150 - headers[key.toLowerCase()] = extraOptions.headers[key]; 151 + if (extraOptions.headers) { 152 + if (isHeaders(extraOptions.headers)) { 153 + extraOptions.headers.forEach((value, key) => { 154 + headers[key] = value; 155 + }); 156 + } else if (Array.isArray(extraOptions.headers)) { 157 + (extraOptions.headers as Array<[string, string]>).forEach( 158 + (value, key) => { 159 + if (Array.isArray(value)) { 160 + if (headers[value[0]]) { 161 + headers[value[0]] = `${headers[value[0]]},${value[1]}`; 162 + } else { 163 + headers[value[0]] = value[1]; 164 + } 165 + } else { 166 + headers[key] = value; 167 + } 168 + } 169 + ); 170 + } else { 171 + for (const key in extraOptions.headers) { 172 + headers[key.toLowerCase()] = extraOptions.headers[key]; 173 + } 174 + } 175 + } 176 + 151 177 const serializedBody = serializeBody(operation, body); 152 178 if (typeof serializedBody === 'string' && !headers['content-type']) 153 179 headers['content-type'] = 'application/json';