Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions packages/toolbar/src/core/services/FlagStateManager.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { DevServerClient, Variation } from './DevServerClient';
import { EnhancedFlag } from '../types/devServer';
import { ApiFlag } from '../ui/Toolbar/types/ldApi';
import { parseUrlOverrides } from '../utils/urlOverrides';

export class FlagStateManager {
private devServerClient: DevServerClient;
private listeners: Set<(flags: Record<string, EnhancedFlag>) => void> = new Set();
private apiFlags: ApiFlag[] = [];
private urlOverrides: Record<string, any> = {};

constructor(devServerClient: DevServerClient) {
this.devServerClient = devServerClient;
this.loadUrlOverrides();
}

private loadUrlOverrides(): void {
try {
this.urlOverrides = parseUrlOverrides();
if (Object.keys(this.urlOverrides).length > 0) {
console.log('FlagStateManager: Loaded URL overrides for flags:', Object.keys(this.urlOverrides));
}
} catch (error) {
console.error('FlagStateManager: Error loading URL overrides:', error);
}
}

async getEnhancedFlags(): Promise<Record<string, EnhancedFlag>> {
Expand All @@ -25,18 +39,28 @@ export class FlagStateManager {
// Process all flags from the dev server
Object.entries(devServerData.flagsState).forEach(([flagKey, flagState]) => {
const apiFlag = apiFlagsMap.get(flagKey);
const override = devServerData.overrides[flagKey];
const devServerOverride = devServerData.overrides[flagKey];
const urlOverride = this.urlOverrides[flagKey];
const variations = devServerData.availableVariations[flagKey] || [];

// Current value is override if exists, otherwise original value
const currentValue = override ? override.value : flagState.value;
// Priority: URL override > dev server override > original value
let currentValue = flagState.value;
let isOverridden = false;

if (urlOverride !== undefined) {
currentValue = urlOverride;
isOverridden = true;
} else if (devServerOverride) {
currentValue = devServerOverride.value;
isOverridden = true;
}

enhancedFlags[flagKey] = {
key: flagKey,
// Use API flag name if available, otherwise format the key
name: apiFlag?.name || this.formatFlagName(flagKey),
currentValue,
isOverridden: !!override,
isOverridden,
originalValue: flagState.value,
availableVariations: variations,
type: apiFlag?.kind || this.determineFlagType(variations, currentValue),
Expand Down Expand Up @@ -103,6 +127,23 @@ export class FlagStateManager {
this.apiFlags = apiFlags;
}

/**
* Returns only the URL-based overrides
* @returns Record of flag keys to their URL override values
*/
getUrlOverrides(): Record<string, any> {
return { ...this.urlOverrides };
}

/**
* Checks if a specific flag override came from the URL
* @param flagKey - The key of the flag to check
* @returns True if the override came from the URL
*/
isUrlOverride(flagKey: string): boolean {
return flagKey in this.urlOverrides;
}

subscribe(listener: (flags: Record<string, EnhancedFlag>) => void): () => void {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
Expand Down
Loading
Loading