Skip to content

Commit 9a687cb

Browse files
authored
accept consoleApiKey from getProviderData (#77)
1 parent f6cb1ef commit 9a687cb

File tree

3 files changed

+160
-115
lines changed

3 files changed

+160
-115
lines changed

.changeset/thin-feet-laugh.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@flags-sdk/statsig': patch
3+
---
4+
5+
accept consoleApiKey from getProviderData

packages/adapter-statsig/src/provider/index.test.ts

+106-93
Original file line numberDiff line numberDiff line change
@@ -195,114 +195,127 @@ beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
195195
afterAll(() => server.close());
196196
afterEach(() => server.resetHandlers());
197197

198+
const responseFixture = {
199+
hints: [],
200+
definitions: {
201+
show_high_definition_images: {
202+
options: [
203+
{ label: 'Off', value: false },
204+
{ label: 'On', value: true },
205+
],
206+
description: 'Show high definition product images',
207+
origin:
208+
'https://console.statsig.com/project-id-placeholder/gates/show_high_definition_images',
209+
createdAt: 1708981092158,
210+
updatedAt: 1708981874677,
211+
},
212+
show_new_product_details: {
213+
options: [
214+
{ label: 'Off', value: false },
215+
{ label: 'On', value: true },
216+
],
217+
description: 'Shows the new product details.',
218+
origin:
219+
'https://console.statsig.com/project-id-placeholder/gates/show_new_product_details',
220+
createdAt: 1708975725889,
221+
updatedAt: 1708975899169,
222+
},
223+
classroom: {
224+
description: '',
225+
origin:
226+
'https://console.statsig.com/project-id-placeholder/experiments/classroom/setup',
227+
options: [
228+
{
229+
label: 'Class D',
230+
value: {
231+
idealism: 75,
232+
fitness: 'weak',
233+
skilful: false,
234+
proficiency: {
235+
math: 10,
236+
literature: 10,
237+
sport: 10,
238+
},
239+
standouts: [],
240+
},
241+
},
242+
{
243+
label: 'Class C',
244+
value: {
245+
idealism: 40,
246+
fitness: 'lazy',
247+
skilful: false,
248+
proficiency: {
249+
math: 30,
250+
literature: 30,
251+
sport: 40,
252+
},
253+
standouts: ['Craftsmanship', 'Basketball'],
254+
},
255+
},
256+
{
257+
label: 'Class B',
258+
value: {
259+
idealism: 20,
260+
fitness: 'fit',
261+
skilful: true,
262+
proficiency: {
263+
math: 60,
264+
literature: 70,
265+
sport: 80,
266+
},
267+
standouts: ['Chess', 'Aikido'],
268+
},
269+
},
270+
{
271+
label: 'Class A',
272+
value: {
273+
idealism: 0,
274+
fitness: 'strong',
275+
skilful: true,
276+
proficiency: {
277+
math: 100,
278+
literature: 100,
279+
sport: 100,
280+
},
281+
standouts: ['Martial Arts', 'Poetry', 'Politics'],
282+
},
283+
},
284+
],
285+
createdAt: 1707427634717,
286+
updatedAt: 1707427635442,
287+
},
288+
},
289+
} as const;
290+
198291
describe('getProviderData', () => {
199292
describe('when called with valid params', () => {
293+
it('should fetch and return', async () => {
294+
await expect(
295+
getProviderData({
296+
consoleApiKey: 'console-this-is-a-test-token',
297+
projectId: 'project-id-placeholder',
298+
}),
299+
).resolves.toEqual(responseFixture);
300+
});
301+
});
302+
303+
describe('when called with deprecated valid params', () => {
200304
it('should fetch and return', async () => {
201305
await expect(
202306
getProviderData({
203307
statsigConsoleApiKey: 'console-this-is-a-test-token',
204308
projectId: 'project-id-placeholder',
205309
}),
206-
).resolves.toEqual({
207-
hints: [],
208-
definitions: {
209-
show_high_definition_images: {
210-
options: [
211-
{ label: 'Off', value: false },
212-
{ label: 'On', value: true },
213-
],
214-
description: 'Show high definition product images',
215-
origin:
216-
'https://console.statsig.com/project-id-placeholder/gates/show_high_definition_images',
217-
createdAt: 1708981092158,
218-
updatedAt: 1708981874677,
219-
},
220-
show_new_product_details: {
221-
options: [
222-
{ label: 'Off', value: false },
223-
{ label: 'On', value: true },
224-
],
225-
description: 'Shows the new product details.',
226-
origin:
227-
'https://console.statsig.com/project-id-placeholder/gates/show_new_product_details',
228-
createdAt: 1708975725889,
229-
updatedAt: 1708975899169,
230-
},
231-
classroom: {
232-
description: '',
233-
origin:
234-
'https://console.statsig.com/project-id-placeholder/experiments/classroom/setup',
235-
options: [
236-
{
237-
label: 'Class D',
238-
value: {
239-
idealism: 75,
240-
fitness: 'weak',
241-
skilful: false,
242-
proficiency: {
243-
math: 10,
244-
literature: 10,
245-
sport: 10,
246-
},
247-
standouts: [],
248-
},
249-
},
250-
{
251-
label: 'Class C',
252-
value: {
253-
idealism: 40,
254-
fitness: 'lazy',
255-
skilful: false,
256-
proficiency: {
257-
math: 30,
258-
literature: 30,
259-
sport: 40,
260-
},
261-
standouts: ['Craftsmanship', 'Basketball'],
262-
},
263-
},
264-
{
265-
label: 'Class B',
266-
value: {
267-
idealism: 20,
268-
fitness: 'fit',
269-
skilful: true,
270-
proficiency: {
271-
math: 60,
272-
literature: 70,
273-
sport: 80,
274-
},
275-
standouts: ['Chess', 'Aikido'],
276-
},
277-
},
278-
{
279-
label: 'Class A',
280-
value: {
281-
idealism: 0,
282-
fitness: 'strong',
283-
skilful: true,
284-
proficiency: {
285-
math: 100,
286-
literature: 100,
287-
sport: 100,
288-
},
289-
standouts: ['Martial Arts', 'Poetry', 'Politics'],
290-
},
291-
},
292-
],
293-
createdAt: 1707427634717,
294-
updatedAt: 1707427635442,
295-
},
296-
},
297-
});
310+
).resolves.toEqual(responseFixture);
298311
});
299312
});
300313

301314
describe('when called with invalid params', () => {
302315
it('should return appropriate hints', async () => {
303316
await expect(
304317
getProviderData({
305-
statsigConsoleApiKey: '',
318+
consoleApiKey: '',
306319
}),
307320
).resolves.toEqual({
308321
definitions: {},

packages/adapter-statsig/src/provider/index.ts

+49-22
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,55 @@ interface StatsigExperimentsResponse {
4343
};
4444
}
4545

46-
export async function getProviderData(options: {
47-
statsigConsoleApiKey: string;
48-
/**
49-
* Required to set the `origin` property on the flag definitions.
50-
*/
51-
projectId?: string;
52-
}): Promise<ProviderData> {
53-
const hints = [];
54-
55-
if (!options.statsigConsoleApiKey) {
56-
hints.push({
57-
key: 'statsig/missing-api-key',
58-
text: 'Missing Statsig Console API Key',
59-
});
46+
export async function getProviderData(
47+
options: {
48+
/**
49+
* Required to set the `origin` property on the flag definitions.
50+
*/
51+
projectId?: string;
52+
} & (
53+
| {
54+
/**
55+
* The Statsig Console API key.
56+
*/
57+
consoleApiKey: string;
58+
/**
59+
* @deprecated Use `consoleApiKey` instead.
60+
*/
61+
statsigConsoleApiKey?: never;
62+
}
63+
| {
64+
/**
65+
* @deprecated Use `consoleApiKey` instead.
66+
*/
67+
statsigConsoleApiKey: string;
68+
/**
69+
* The Statsig Console API key.
70+
*/
71+
consoleApiKey?: never;
72+
}
73+
),
74+
): Promise<ProviderData> {
75+
const consoleApiKey = options.consoleApiKey || options.statsigConsoleApiKey;
76+
77+
if (!consoleApiKey) {
78+
return {
79+
definitions: {},
80+
hints: [
81+
{
82+
key: 'statsig/missing-api-key',
83+
text: 'Missing Statsig Console API Key',
84+
},
85+
],
86+
};
6087
}
6188

62-
// Abort early if called with incomplete options.
63-
if (hints.length > 0) return { definitions: {}, hints };
89+
const hints: ProviderData['hints'] = [];
6490

91+
// Abort early if called with incomplete options.
6592
const [gates, experiments] = await Promise.allSettled([
66-
getFeatureGates(options),
67-
getExperiments(options),
93+
getFeatureGates({ consoleApiKey }),
94+
getExperiments({ consoleApiKey }),
6895
] as const);
6996

7097
const definitions: ProviderData['definitions'] = {};
@@ -121,7 +148,7 @@ export async function getProviderData(options: {
121148
/**
122149
* Fetch all Feature Gates.
123150
*/
124-
async function getFeatureGates(options: { statsigConsoleApiKey: string }) {
151+
async function getFeatureGates(options: { consoleApiKey: string }) {
125152
const data: StatsigFeatureGateResponse['data'] = [];
126153

127154
let suffix: string | null = '/console/v1/gates';
@@ -131,7 +158,7 @@ async function getFeatureGates(options: { statsigConsoleApiKey: string }) {
131158
method: 'GET',
132159
headers: {
133160
'content-type': 'application/json',
134-
'STATSIG-API-KEY': options.statsigConsoleApiKey,
161+
'STATSIG-API-KEY': options.consoleApiKey,
135162
},
136163
// @ts-expect-error some Next.js versions need this
137164
cache: 'no-store',
@@ -157,7 +184,7 @@ async function getFeatureGates(options: { statsigConsoleApiKey: string }) {
157184
/**
158185
* Fetch all experiments.
159186
*/
160-
async function getExperiments(options: { statsigConsoleApiKey: string }) {
187+
async function getExperiments(options: { consoleApiKey: string }) {
161188
const data: StatsigExperimentsResponse['data'] = [];
162189

163190
let suffix: string | null = '/console/v1/experiments';
@@ -167,7 +194,7 @@ async function getExperiments(options: { statsigConsoleApiKey: string }) {
167194
method: 'GET',
168195
headers: {
169196
'content-type': 'application/json',
170-
'STATSIG-API-KEY': options.statsigConsoleApiKey,
197+
'STATSIG-API-KEY': options.consoleApiKey,
171198
},
172199
// @ts-expect-error some Next.js versions need this
173200
cache: 'no-store',

0 commit comments

Comments
 (0)