Skip to content

Commit

Permalink
add ability to pass custom http headers (#81)
Browse files Browse the repository at this point in the history
* add ability to pass custom http headers

* Update README.md

Fixes: #80 

Co-authored-by: Thomas Heartman <thomasheartman+github@gmail.com>

Co-authored-by: sighphyre <liquidwicked64@gmail.com>
Co-authored-by: Thomas Heartman <thomasheartman+github@gmail.com>
  • Loading branch information
3 people authored Apr 21, 2022
1 parent dc4833b commit 99b186a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ The Unleash SDK takes the following options:
| bootstrap | no | `[]` | Allows you to bootstrap the cached feature toggle configuration. |
| bootstrapOverride | no| `true` | Should the boostrap automatically override cached data in the local-storage. Will only be used if boostrap is not an empty array. |
| headerName | no| `Authorization` | Provides possiblity to specify custom header that is passed to Unleash / Unleash Proxy with the `clientKey` |
| customHeaders | no| `{}` | Additional headers to use when making HTTP requests to the Unleash proxy. In case of name collisions with the default headers, the `customHeaders` value will be used. |


### Listen for updates via the EventEmitter
Expand Down
24 changes: 24 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,30 @@ test('Should call isEnabled event when impressionData is true', (done) => {
});
});

test('Should pass custom headers', async() => {
fetchMock.mockResponses(
[JSON.stringify(data), { status: 200 }],
[JSON.stringify(data), { status: 200 }]
);
const config: IConfig = {
url: 'http://localhost/test',
clientKey: 'extrakey',
appName: 'web',
customHeaders: {
'customheader1': 'header1val',
'customheader2': 'header2val'
}
};
const client = new UnleashClient(config);
await client.start();

jest.advanceTimersByTime(1001);

expect(fetchMock.mock.calls[0][1].headers.customheader2).toEqual(
'header2val'
);
});

test('Should call getVariant event when impressionData is true', (done) => {
const bootstrap = [
{
Expand Down
24 changes: 18 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface IConfig extends IStaticContext {
bootstrap?: IToggle[];
bootstrapOverride?: boolean;
headerName?: string;
customHeaders?: Record<string, string>;
}

interface IVariant {
Expand Down Expand Up @@ -101,6 +102,7 @@ export class UnleashClient extends TinyEmitter {
private bootstrapOverride: boolean;
private headerName: string;
private eventsHandler: EventsHandler;
private customHeaders: Record<string, string>;

constructor({
storageProvider,
Expand All @@ -117,6 +119,8 @@ export class UnleashClient extends TinyEmitter {
bootstrap,
bootstrapOverride = true,
headerName = 'Authorization',
customHeaders = {},

}: IConfig) {
super();
// Validations
Expand All @@ -134,6 +138,7 @@ export class UnleashClient extends TinyEmitter {
this.url = new URL(`${url}`);
this.clientKey = clientKey;
this.headerName = headerName;
this.customHeaders = customHeaders;
this.storage = storageProvider || new LocalStorageProvider();
this.refreshInterval = disableRefresh ? 0 : refreshInterval * 1000;
this.context = { appName, environment, ...context };
Expand Down Expand Up @@ -308,6 +313,18 @@ export class UnleashClient extends TinyEmitter {
}
}

private getHeaders() {
const headers = {[this.headerName]: this.clientKey,
'Accept': 'application/json',
'Content-Type': 'application/json',
'If-None-Match': this.etag
}
Object.entries(this.customHeaders).filter(notNullOrUndefined).forEach(([name, value]) =>
headers[name] = value);
return headers;

}

private async storeToggles(toggles: IToggle[]): Promise<void> {
this.toggles = toggles;
this.emit(EVENTS.UPDATE);
Expand Down Expand Up @@ -346,12 +363,7 @@ export class UnleashClient extends TinyEmitter {
);
const response = await this.fetch(urlWithQuery.toString(), {
cache: 'no-cache',
headers: {
[this.headerName]: this.clientKey,
Accept: 'application/json',
'Content-Type': 'application/json',
'If-None-Match': this.etag,
},
headers: this.getHeaders(),
});
if (response.ok && response.status !== 304) {
this.etag = response.headers.get('ETag') || '';
Expand Down

0 comments on commit 99b186a

Please sign in to comment.