Skip to content

Commit a31c0c1

Browse files
feat: implement a way to share overrides with others using urls
1 parent f3d0037 commit a31c0c1

File tree

14 files changed

+834
-20
lines changed

14 files changed

+834
-20
lines changed

packages/toolbar/src/core/services/FlagStateManager.ts

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
import { DevServerClient, Variation } from './DevServerClient';
22
import { EnhancedFlag } from '../types/devServer';
33
import { ApiFlag } from '../ui/Toolbar/types/ldApi';
4+
import { parseUrlOverrides } from '../utils/urlOverrides';
45

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

1012
constructor(devServerClient: DevServerClient) {
1113
this.devServerClient = devServerClient;
14+
this.loadUrlOverrides();
15+
}
16+
17+
private loadUrlOverrides(): void {
18+
try {
19+
this.urlOverrides = parseUrlOverrides();
20+
if (Object.keys(this.urlOverrides).length > 0) {
21+
console.log('FlagStateManager: Loaded URL overrides for flags:', Object.keys(this.urlOverrides));
22+
}
23+
} catch (error) {
24+
console.error('FlagStateManager: Error loading URL overrides:', error);
25+
}
1226
}
1327

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

31-
// Current value is override if exists, otherwise original value
32-
const currentValue = override ? override.value : flagState.value;
46+
// Priority: URL override > dev server override > original value
47+
let currentValue = flagState.value;
48+
let isOverridden = false;
49+
50+
if (urlOverride !== undefined) {
51+
currentValue = urlOverride;
52+
isOverridden = true;
53+
} else if (devServerOverride) {
54+
currentValue = devServerOverride.value;
55+
isOverridden = true;
56+
}
3357

3458
enhancedFlags[flagKey] = {
3559
key: flagKey,
3660
// Use API flag name if available, otherwise format the key
3761
name: apiFlag?.name || this.formatFlagName(flagKey),
3862
currentValue,
39-
isOverridden: !!override,
63+
isOverridden,
4064
originalValue: flagState.value,
4165
availableVariations: variations,
4266
type: apiFlag?.kind || this.determineFlagType(variations, currentValue),
@@ -103,6 +127,23 @@ export class FlagStateManager {
103127
this.apiFlags = apiFlags;
104128
}
105129

130+
/**
131+
* Returns only the URL-based overrides
132+
* @returns Record of flag keys to their URL override values
133+
*/
134+
getUrlOverrides(): Record<string, any> {
135+
return { ...this.urlOverrides };
136+
}
137+
138+
/**
139+
* Checks if a specific flag override came from the URL
140+
* @param flagKey - The key of the flag to check
141+
* @returns True if the override came from the URL
142+
*/
143+
isUrlOverride(flagKey: string): boolean {
144+
return flagKey in this.urlOverrides;
145+
}
146+
106147
subscribe(listener: (flags: Record<string, EnhancedFlag>) => void): () => void {
107148
this.listeners.add(listener);
108149
return () => this.listeners.delete(listener);

0 commit comments

Comments
 (0)