Skip to content

Commit bc0cf13

Browse files
authored
Merge pull request #2392 from vz-tl/bugfix/defaultcontext-headers
Allow headers type in DefaultContext to be Record or HttpHeaders
2 parents ea0fd02 + 78a8310 commit bc0cf13

File tree

7 files changed

+262
-227
lines changed

7 files changed

+262
-227
lines changed

.changeset/floppy-states-throw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'apollo-angular': patch
3+
---
4+
5+
Allow headers type in DefaultContext to be Record or HttpHeaders

packages/apollo-angular/http/src/http-batch-link.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { BatchLink } from '@apollo/client/link/batch';
88
import type { HttpLink } from './http-link';
99
import { Body, Context, OperationPrinter, Request } from './types';
1010
import {
11+
convertHeadersToArray,
12+
convertToHttpHeaders,
1113
createHeadersWithClientAwareness,
1214
fetch,
1315
mergeHeaders,
@@ -74,7 +76,7 @@ export const defaults = {
7476
*/
7577
export function pick<K extends keyof Omit<typeof defaults, 'batchInterval' | 'batchMax'>>(
7678
context: Context,
77-
options: HttpBatchLink.Options,
79+
options: Omit<HttpBatchLink.Options, 'headers'>,
7880
key: K,
7981
): ReturnType<typeof prioritize<Context[K] | HttpBatchLink.Options[K] | (typeof defaults)[K]>> {
8082
return prioritize(context[key], options[key], defaults[key]);
@@ -201,7 +203,9 @@ export class HttpBatchLinkHandler extends ApolloLink {
201203
return operations.reduce(
202204
(headers: HttpHeaders, operation: ApolloLink.Operation) => {
203205
const { headers: contextHeaders } = operation.getContext();
204-
return contextHeaders ? mergeHeaders(headers, contextHeaders) : headers;
206+
return contextHeaders
207+
? mergeHeaders(headers, convertToHttpHeaders(contextHeaders))
208+
: headers;
205209
},
206210
createHeadersWithClientAwareness({
207211
headers: this.options.headers,
@@ -227,8 +231,7 @@ export class HttpBatchLinkHandler extends ApolloLink {
227231
return Math.random().toString(36).substring(2, 11);
228232
}
229233

230-
const headers =
231-
context.headers && context.headers.keys().map((k: string) => context.headers!.get(k));
234+
const headers = convertHeadersToArray(context.headers);
232235

233236
const opts = JSON.stringify({
234237
includeQuery: context.includeQuery,
@@ -239,7 +242,7 @@ export class HttpBatchLinkHandler extends ApolloLink {
239242
return prioritize(context.uri, this.options.uri, '') + opts;
240243
}
241244

242-
public request(
245+
public override request(
243246
op: ApolloLink.Operation,
244247
forward: ApolloLink.ForwardFunction,
245248
): Observable<ApolloLink.Result> {

packages/apollo-angular/http/src/http-link.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import {
1010
Context,
1111
ExtractFiles,
1212
FetchOptions,
13-
HttpRequestOptions,
1413
OperationPrinter,
1514
Request,
15+
RequestOptions,
1616
} from './types';
1717
import { createHeadersWithClientAwareness, fetch, mergeHeaders, mergeHttpContext } from './utils';
1818

@@ -52,7 +52,7 @@ function convertHttpErrorToApolloError(err: HttpErrorResponse): Error {
5252
}
5353

5454
export declare namespace HttpLink {
55-
export interface Options extends FetchOptions, HttpRequestOptions {
55+
export interface Options extends FetchOptions, RequestOptions {
5656
operationPrinter?: OperationPrinter;
5757
useGETForQueries?: boolean;
5858
extractFiles?: ExtractFiles;
@@ -98,6 +98,11 @@ export class HttpLinkHandler extends ApolloLink {
9898
method = 'GET';
9999
}
100100

101+
const headers = mergeHeaders(
102+
this.options.headers,
103+
createHeadersWithClientAwareness(context),
104+
);
105+
101106
const req: Request = {
102107
method,
103108
url: typeof url === 'function' ? url(operation) : url,
@@ -108,7 +113,7 @@ export class HttpLinkHandler extends ApolloLink {
108113
options: {
109114
withCredentials,
110115
useMultipart,
111-
headers: this.options.headers,
116+
headers,
112117
context: httpContext,
113118
},
114119
};
@@ -121,10 +126,6 @@ export class HttpLinkHandler extends ApolloLink {
121126
(req.body as Body).query = this.print(operation.query);
122127
}
123128

124-
const headers = createHeadersWithClientAwareness(context);
125-
126-
req.options.headers = mergeHeaders(req.options.headers, headers);
127-
128129
const sub = fetch(req, this.httpClient, this.options.extractFiles).subscribe({
129130
next: response => {
130131
operation.setContext({ response });
@@ -146,7 +147,7 @@ export class HttpLinkHandler extends ApolloLink {
146147
});
147148
}
148149

149-
public request(op: ApolloLink.Operation): Observable<ApolloLink.Result> {
150+
public override request(op: ApolloLink.Operation): Observable<ApolloLink.Result> {
150151
return this.requester(op);
151152
}
152153
}

packages/apollo-angular/http/src/types.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ declare module '@apollo/client' {
77
}
88

99
export type HttpRequestOptions = {
10-
headers?: HttpHeaders;
10+
headers?: HttpHeaders | Record<string, string>;
1111
withCredentials?: boolean;
1212
useMultipart?: boolean;
1313
httpContext?: HttpContext;
1414
};
1515

16-
export type RequestOptions = Omit<HttpRequestOptions, 'httpContext'> & {
17-
context?: HttpContext;
16+
export type RequestOptions = Omit<HttpRequestOptions, 'headers'> & {
17+
headers?: HttpHeaders;
1818
};
1919

2020
export type URIFunction = (operation: ApolloLink.Operation) => string;
@@ -37,11 +37,13 @@ export type Body = {
3737

3838
export interface Context extends FetchOptions, HttpRequestOptions {}
3939

40+
type HttpClientRequestOptions = Omit<RequestOptions, 'httpContext'> & { context: HttpContext };
41+
4042
export type Request = {
4143
method: string;
4244
url: string;
4345
body: Body | Body[];
44-
options: RequestOptions;
46+
options: HttpClientRequestOptions;
4547
};
4648

4749
export type ExtractedFiles = {

packages/apollo-angular/http/src/utils.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,25 @@ export const fetch = (
106106
});
107107
};
108108

109+
export const convertToHttpHeaders = (
110+
headers: HttpHeaders | Record<string, string> | undefined,
111+
): HttpHeaders => (headers instanceof HttpHeaders ? headers : new HttpHeaders(headers));
112+
113+
export const convertHeadersToArray = (
114+
headers: HttpHeaders | Record<string, string> | undefined,
115+
): string[] =>
116+
headers instanceof HttpHeaders
117+
? headers.keys().map((k: string) => headers.get(k)!)
118+
: Object.values(headers ?? {});
119+
109120
export const mergeHeaders = (
110121
source: HttpHeaders | undefined,
111122
destination: HttpHeaders,
112123
): HttpHeaders => {
113124
if (source && destination) {
114-
const merged = destination
125+
return destination
115126
.keys()
116127
.reduce((headers, name) => headers.set(name, destination.getAll(name)!), source);
117-
118-
return merged;
119128
}
120129

121130
return destination || source;
@@ -146,10 +155,7 @@ export function createHeadersWithClientAwareness(context: Record<string, any>) {
146155
// `clientAwareness` object is found in the context. These headers are
147156
// set first, followed by the rest of the headers pulled from
148157
// `context.headers`.
149-
let headers =
150-
context.headers && context.headers instanceof HttpHeaders
151-
? context.headers
152-
: new HttpHeaders(context.headers);
158+
let headers = convertToHttpHeaders(context.headers);
153159

154160
if (context.clientAwareness) {
155161
const { name, version } = context.clientAwareness;

0 commit comments

Comments
 (0)