Skip to content

Commit 2816a8a

Browse files
Allow for headers to be passed through
1 parent 23a996a commit 2816a8a

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

Route.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import IMountableItem from './IMountableItem';
2+
import { IncomingHttpHeaders } from 'http';
23
import Router from './Router';
34
import { DocumentNode, parse, print, getOperationAST } from 'graphql';
45
import { AxiosTransformer, AxiosInstance, AxiosRequestConfig } from 'axios';
@@ -14,6 +15,8 @@ export interface IConstructorRouteOptions {
1415
cacheTimeInMs?: number;
1516
method?: string;
1617

18+
passThroughHeaders?: string[];
19+
1720
staticVariables?: {};
1821
defaultVariables?: {};
1922
}
@@ -22,6 +25,7 @@ export interface IRouteOptions {
2225
path?: string;
2326
cacheTimeInMs?: number;
2427
method?: string;
28+
passThroughHeaders?: string[];
2529

2630
staticVariables?: {};
2731
defaultVariables?: {};
@@ -90,8 +94,10 @@ export default class Route implements IMountableItem {
9094
private operationName!: string;
9195
private operationVariables!: IOperationVariable[];
9296

93-
private transformRequestFn?: AxiosTransformer;
94-
private transformResponseFn?: AxiosTransformer;
97+
private transformRequestFn: AxiosTransformer[] = [];
98+
private transformResponseFn: AxiosTransformer[] = [];
99+
100+
private passThroughHeaders: string[] = [];
95101

96102
private staticVariables: {} = {};
97103
private defaultVariables: {} = {};
@@ -124,12 +130,32 @@ export default class Route implements IMountableItem {
124130
this.withOptions(options);
125131
}
126132

133+
private filterHeadersForPassThrough(headers: IncomingHttpHeaders): IncomingHttpHeaders {
134+
const passThroughHeaders: IncomingHttpHeaders = {};
135+
136+
this.passThroughHeaders.forEach(
137+
(header: string) => {
138+
if (headers.hasOwnProperty(header)) {
139+
passThroughHeaders[header] = headers[header];
140+
}
141+
}
142+
);
143+
144+
return passThroughHeaders;
145+
}
146+
127147
setRouter(router: Router): this {
128148
this.router = router;
129149

130150
return this;
131151
}
132152

153+
whitelistHeaderForPassThrough(header: string): this {
154+
this.passThroughHeaders.push(header);
155+
156+
return this
157+
}
158+
133159
at(path: string): this {
134160
this.path = cleanPath(path);
135161

@@ -172,6 +198,7 @@ export default class Route implements IMountableItem {
172198
defaultVariables,
173199
staticVariables,
174200
cacheTimeInMs,
201+
passThroughHeaders,
175202
} = options;
176203

177204
if (path) {
@@ -182,6 +209,10 @@ export default class Route implements IMountableItem {
182209
this.as(httpMethod);
183210
}
184211

212+
if (passThroughHeaders) {
213+
passThroughHeaders.forEach(this.whitelistHeaderForPassThrough.bind(this));
214+
}
215+
185216
if (defaultVariables) {
186217
this.defaultVariables = defaultVariables;
187218
}
@@ -246,6 +277,8 @@ export default class Route implements IMountableItem {
246277
const assembledVariables = this.assembleVariables(providedVariables);
247278
const missingVariables = this.missingVariables(assembledVariables);
248279

280+
const headers = this.filterHeadersForPassThrough(req.headers);
281+
249282
if (missingVariables.length) {
250283
res.json({
251284
error: 'Missing Variables',
@@ -254,7 +287,7 @@ export default class Route implements IMountableItem {
254287
return;
255288
}
256289

257-
const { statusCode, body } = await this.makeRequest(assembledVariables);
290+
const { statusCode, body } = await this.makeRequest(assembledVariables, headers);
258291

259292
res
260293
.status(statusCode)
@@ -273,13 +306,13 @@ export default class Route implements IMountableItem {
273306
// areVariablesValid(variables: {}) {}
274307

275308
transformRequest(fn: AxiosTransformer): this {
276-
this.transformRequestFn = fn;
309+
this.transformRequestFn.push(fn);
277310

278311
return this;
279312
}
280313

281314
transformResponse(fn: AxiosTransformer): this {
282-
this.transformResponseFn = fn;
315+
this.transformResponseFn.push(fn);
283316

284317
return this;
285318
}
@@ -329,7 +362,7 @@ export default class Route implements IMountableItem {
329362
);
330363
}
331364

332-
private async makeRequest(variables: {}): Promise<IResponse> {
365+
private async makeRequest(variables: {}, headers: {} = {}): Promise<IResponse> {
333366
const { axios, schema, operationName } = this;
334367

335368
const config: AxiosRequestConfig = {
@@ -338,15 +371,12 @@ export default class Route implements IMountableItem {
338371
variables,
339372
operationName,
340373
},
341-
};
342374

343-
if (this.transformRequestFn) {
344-
config.transformRequest = this.transformRequestFn;
345-
}
375+
headers,
346376

347-
if (this.transformResponseFn) {
348-
config.transformResponse = this.transformResponseFn;
349-
}
377+
transformRequest: this.transformRequestFn,
378+
transformResponse: this.transformResponseFn,
379+
};
350380

351381
try {
352382
const { data, status } = await axios(config);

Router.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface IGlobalConfiguration {
1313
autoDiscoverEndpoints?: boolean;
1414
optimizeQueryRequest?: boolean;
1515
headers?: {};
16+
passThroughHeaders?: string[];
1617
auth?: AxiosBasicCredentials;
1718
proxy?: AxiosProxyConfig;
1819
}
@@ -35,13 +36,15 @@ export default class Router {
3536
public routes: Route[] = [];
3637
public modules: IMountableItem[] = [];
3738

39+
private passThroughHeaders: string[] = [];
3840
private axios: AxiosInstance;
3941

4042
constructor(public endpoint: string, schema: string, assignedConfiguration?: IGlobalConfiguration) {
4143
const {
4244
auth,
4345
proxy,
4446
defaultTimeoutInMs: timeout,
47+
passThroughHeaders,
4548
...options
4649
} = {
4750
...DEFAULT_CONFIGURATION,
@@ -66,6 +69,11 @@ export default class Router {
6669

6770
this.schema = parse(schema);
6871
this.axios = axios.create(axiosConfig);
72+
73+
if (passThroughHeaders) {
74+
this.passThroughHeaders = passThroughHeaders;
75+
}
76+
6977
this.options = options;
7078
}
7179

@@ -84,20 +92,26 @@ export default class Router {
8492
return schema;
8593
}
8694

87-
mount(operationName: string, options?: {}): Route;
88-
mount(mountableItem: IMountableItem, options?: {}): IMountableItem;
89-
mount(operationNameOrMountableItem: string | IMountableItem, options?: {}): IMountableItem {
95+
mount(operationName: string, options?: any): Route;
96+
mount(mountableItem: IMountableItem, options?: any): IMountableItem;
97+
mount(operationNameOrMountableItem: string | IMountableItem, options?: any): IMountableItem {
9098
if (typeof operationNameOrMountableItem === 'string') {
9199
const { schema, axios } = this;
92100
const operationName = operationNameOrMountableItem;
93101

102+
const passThroughHeaders = Boolean(options)
103+
? [...this.passThroughHeaders, ...options.passThroughHeaders]
104+
: [...this.passThroughHeaders];
105+
94106
const routeOptions: IConstructorRouteOptions = {
95-
operationName: operationNameOrMountableItem,
107+
...options,
108+
109+
operationName,
96110

97111
axios,
98112
schema,
99113

100-
...options,
114+
passThroughHeaders,
101115
};
102116

103117
const graphQLRoute = new Route(routeOptions, this);

0 commit comments

Comments
 (0)