Skip to content

Commit

Permalink
chore: allow for local testing for flag overrides (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
greghuels authored Mar 3, 2025
1 parent a92ad46 commit d3f5d9e
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eppo/js-client-sdk-common",
"version": "4.11.0",
"version": "4.12.0",
"description": "Common library for Eppo JavaScript SDKs (web, react native, and node)",
"main": "dist/index.js",
"files": [
Expand Down
5 changes: 5 additions & 0 deletions src/api-endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
UFC_ENDPOINT,
BANDIT_ENDPOINT,
PRECOMPUTED_FLAGS_ENDPOINT,
FLAG_OVERRIDES_KEY_VALIDATION_URL,
} from './constants';
import { IQueryParams, IQueryParamsWithSubject } from './http-client';

Expand Down Expand Up @@ -36,4 +37,8 @@ export default class ApiEndpoints {
precomputedFlagsEndpoint(): URL {
return this.endpoint(PRECOMPUTED_FLAGS_ENDPOINT);
}

flagOverridesKeyValidationEndpoint(): URL {
return this.endpoint(FLAG_OVERRIDES_KEY_VALIDATION_URL);
}
}
5 changes: 3 additions & 2 deletions src/client/eppo-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ export default class EppoClient {
return undefined;
}
const payload: OverridePayload = this.overrideValidator.parseOverridePayload(overridePayload);
await this.overrideValidator.validateKey(payload.browserExtensionKey);
const baseUrl = this.configurationRequestParameters?.baseUrl;
await this.overrideValidator.validateKey(payload.browserExtensionKey, baseUrl);
return payload.overrides;
}

Expand All @@ -222,7 +223,7 @@ export default class EppoClient {
* to it without affecting the original EppoClient singleton. Useful for
* applying overrides in a shared Node instance, such as a web server.
*/
withOverrides(overrides: Record<FlagKey, Variation>): EppoClient {
withOverrides(overrides: Record<FlagKey, Variation> | undefined): EppoClient {
if (overrides && Object.keys(overrides).length) {
const copy = shallowClone(this);
copy.overrideStore = new MemoryOnlyConfigurationStore<Variation>();
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const DEFAULT_POLL_CONFIG_REQUEST_RETRIES = 7;
export const BASE_URL = 'https://fscdn.eppo.cloud/api';
export const UFC_ENDPOINT = '/flag-config/v1/config';
export const BANDIT_ENDPOINT = '/flag-config/v1/bandits';
export const FLAG_OVERRIDES_KEY_VALIDATION_URL = '/flag-overrides/v1/validate-key';
export const PRECOMPUTED_BASE_URL = 'https://fs-edge-assignment.eppo.cloud';
export const PRECOMPUTED_FLAGS_ENDPOINT = '/assignments';
export const SESSION_ASSIGNMENT_CONFIG_LOADED = 'eppo-session-assignment-config-loaded';
Expand Down
14 changes: 9 additions & 5 deletions src/override-validator.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import ApiEndpoints from './api-endpoints';
import { TLRUCache } from './cache/tlru-cache';
import { Variation } from './interfaces';
import { FlagKey } from './types';

const FIVE_MINUTES_IN_MS = 5 * 3600 * 1000;
const KEY_VALIDATION_URL = 'https://eppo.cloud/api/flag-overrides/v1/validate-key';

export interface OverridePayload {
browserExtensionKey: string;
overrides: Record<FlagKey, Variation>;
}

export const sendValidationRequest = async (browserExtensionKey: string) => {
const response = await fetch(KEY_VALIDATION_URL, {
export const sendValidationRequest = async (
browserExtensionKey: string,
validationEndpoint: string,
) => {
const response = await fetch(validationEndpoint, {
method: 'POST',
body: JSON.stringify({
key: browserExtensionKey,
Expand Down Expand Up @@ -63,11 +66,12 @@ export class OverrideValidator {
}
}

async validateKey(browserExtensionKey: string) {
async validateKey(browserExtensionKey: string, baseUrl: string | undefined) {
if (this.validKeyCache.get(browserExtensionKey) === 'true') {
return true;
}
await sendValidationRequest(browserExtensionKey);
const endpoint = new ApiEndpoints({ baseUrl }).flagOverridesKeyValidationEndpoint().toString();
await sendValidationRequest(browserExtensionKey, endpoint);
this.validKeyCache.set(browserExtensionKey, 'true');
}
}

0 comments on commit d3f5d9e

Please sign in to comment.