Skip to content

Commit 1e726a9

Browse files
authored
Add option for additional headers (#111)
* Add option for additional headers * bump version
1 parent 1279461 commit 1e726a9

File tree

4 files changed

+104
-3
lines changed

4 files changed

+104
-3
lines changed

js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@schematichq/schematic-js",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"main": "dist/schematic.cjs.js",
55
"module": "dist/schematic.esm.js",
66
"types": "dist/schematic.d.ts",

js/src/index.spec.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,47 @@ describe("Schematic", () => {
206206
});
207207
expect(flagValue).toBe(true);
208208
});
209+
210+
it("should include additional headers", async () => {
211+
const schematicWithHeaders = new Schematic("API_KEY", {
212+
additionalHeaders: { "X-Additional-Header": "foo" },
213+
});
214+
const context = {
215+
company: { companyId: "456" },
216+
user: { userId: "123" },
217+
};
218+
const expectedResponse = {
219+
data: {
220+
companyId: "comp_YRucCyZ3us4",
221+
flag: "FLAG_KEY",
222+
reason: "Matched rule rule_iuBRNdJEjYh",
223+
ruleId: "rule_iuBRNdJEjYh",
224+
userId: "user_6oRr9UTncXf",
225+
value: true,
226+
},
227+
};
228+
mockFetch.mockResolvedValueOnce({
229+
ok: true,
230+
json: jest.fn().mockResolvedValueOnce(expectedResponse),
231+
});
232+
233+
const flagValue = await schematicWithHeaders.checkFlag({
234+
key: "FLAG_KEY",
235+
context,
236+
});
237+
238+
expect(mockFetch).toHaveBeenCalledTimes(1);
239+
expect(mockFetch).toHaveBeenCalledWith(expect.any(String), {
240+
method: "POST",
241+
headers: {
242+
"X-Schematic-Api-Key": "API_KEY",
243+
"Content-Type": "application/json;charset=UTF-8",
244+
"X-Additional-Header": "foo",
245+
},
246+
body: expect.any(String),
247+
});
248+
expect(flagValue).toBe(true);
249+
});
209250
});
210251

211252
describe("checkFlags", () => {
@@ -257,5 +298,56 @@ describe("Schematic", () => {
257298
FLAG_KEY2: false,
258299
});
259300
});
301+
302+
it("should include additional headers", async () => {
303+
const schematicWithHeaders = new Schematic("API_KEY", {
304+
additionalHeaders: { "X-Additional-Header": "foo" },
305+
});
306+
const context = {
307+
company: { companyId: "456" },
308+
user: { userId: "123" },
309+
};
310+
const expectedResponse = {
311+
data: {
312+
flags: [
313+
{
314+
companyId: "comp_YRucCyZ3us4",
315+
flag: "FLAG_KEY1",
316+
reason: "Matched rule rule_iuBRNdJEjYh",
317+
ruleId: "rule_iuBRNdJEjYh",
318+
userId: "user_6oRr9UTncXf",
319+
value: true,
320+
},
321+
{
322+
companyId: "comp_YRucCyZ3us4",
323+
flag: "FLAG_KEY2",
324+
reason: "No rules matched",
325+
ruleId: null,
326+
userId: "user_6oRr9UTncXf",
327+
value: false,
328+
},
329+
],
330+
},
331+
};
332+
mockFetch.mockResolvedValueOnce({
333+
ok: true,
334+
json: jest.fn().mockResolvedValueOnce(expectedResponse),
335+
});
336+
const flagValues = await schematicWithHeaders.checkFlags(context);
337+
expect(mockFetch).toHaveBeenCalledTimes(1);
338+
expect(mockFetch).toHaveBeenCalledWith(expect.any(String), {
339+
method: "POST",
340+
headers: {
341+
"X-Schematic-Api-Key": "API_KEY",
342+
"Content-Type": "application/json;charset=UTF-8",
343+
"X-Additional-Header": "foo",
344+
},
345+
body: expect.any(String),
346+
});
347+
expect(flagValues).toEqual({
348+
FLAG_KEY1: true,
349+
FLAG_KEY2: false,
350+
});
351+
});
260352
});
261353
});

js/src/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const anonymousIdKey = "schematicId";
2222

2323
/* @preserve */
2424
export class Schematic {
25+
private additionalHeaders: Record<string, string> = {};
2526
private apiKey: string;
2627
private apiUrl = "https://api.schematichq.com";
2728
private conn: Promise<WebSocket> | null = null;
@@ -43,6 +44,10 @@ export class Schematic {
4344
this.useWebSocket = options?.useWebSocket ?? false;
4445
this.flagListener = options?.flagListener;
4546

47+
if (options?.additionalHeaders) {
48+
this.additionalHeaders = options.additionalHeaders;
49+
}
50+
4651
if (options?.storage) {
4752
this.storage = options.storage;
4853
} else if (typeof localStorage !== "undefined") {
@@ -86,8 +91,9 @@ export class Schematic {
8691
return fetch(requestUrl, {
8792
method: "POST",
8893
headers: {
89-
"X-Schematic-Api-Key": this.apiKey,
94+
...(this.additionalHeaders ?? {}),
9095
"Content-Type": "application/json;charset=UTF-8",
96+
"X-Schematic-Api-Key": this.apiKey,
9197
},
9298
body: JSON.stringify(context),
9399
})
@@ -117,6 +123,7 @@ export class Schematic {
117123
return fetch(requestUrl, {
118124
method: "POST",
119125
headers: {
126+
...(this.additionalHeaders ?? {}),
120127
"Content-Type": "application/json;charset=UTF-8",
121128
"X-Schematic-Api-Key": this.apiKey,
122129
},
@@ -247,6 +254,7 @@ export class Schematic {
247254
await fetch(captureUrl, {
248255
method: "POST",
249256
headers: {
257+
...(this.additionalHeaders ?? {}),
250258
"Content-Type": "application/json;charset=UTF-8",
251259
},
252260
body: payload,

js/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,13 @@ export type StoragePersister = {
5959
};
6060

6161
export type SchematicOptions = {
62+
additionalHeaders?: Record<string, string>;
6263
apiUrl?: string;
63-
webSocketUrl?: string;
6464
eventUrl?: string;
6565
flagListener?: (values: Record<string, boolean>) => void;
6666
storage?: StoragePersister;
6767
useWebSocket?: boolean;
68+
webSocketUrl?: string;
6869
};
6970

7071
export type CheckOptions = {

0 commit comments

Comments
 (0)