53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
/**
|
|
* Feature flag helper functions for testing
|
|
*/
|
|
|
|
export interface FeatureFlagData {
|
|
features: Record<string, string>;
|
|
timestamp: string;
|
|
}
|
|
|
|
/**
|
|
* Helper to compute enabled flags from feature config
|
|
*/
|
|
export function getEnabledFlags(featureData: FeatureFlagData): string[] {
|
|
if (!featureData.features || typeof featureData.features !== 'object') {
|
|
return [];
|
|
}
|
|
|
|
return Object.entries(featureData.features)
|
|
.filter(([, value]) => value === 'enabled')
|
|
.map(([flag]) => flag);
|
|
}
|
|
|
|
/**
|
|
* Helper to check if a specific flag is enabled
|
|
*/
|
|
export function isFeatureEnabled(featureData: FeatureFlagData, flag: string): boolean {
|
|
return featureData.features?.[flag] === 'enabled';
|
|
}
|
|
|
|
/**
|
|
* Helper to fetch feature flags from the API
|
|
* Note: This is a pure function that takes the fetcher as an argument to avoid network side effects in unit tests
|
|
*/
|
|
export async function fetchFeatureFlags(
|
|
fetcher: (url: string) => Promise<{ ok: boolean; json: () => Promise<unknown>; status: number }>,
|
|
apiBaseUrl: string
|
|
): Promise<FeatureFlagData> {
|
|
const featuresUrl = `${apiBaseUrl}/features`;
|
|
|
|
try {
|
|
const response = await fetcher(featuresUrl);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch feature flags: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json() as FeatureFlagData;
|
|
return data;
|
|
} catch (error) {
|
|
console.error(`[FEATURE FLAGS] Failed to fetch from ${featuresUrl}:`, error);
|
|
throw error;
|
|
}
|
|
}
|