Skip to content

Commit 3533e12

Browse files
committed
Add methods for boolean, integer, numeric, and json types
1 parent 923ad90 commit 3533e12

File tree

1 file changed

+86
-12
lines changed

1 file changed

+86
-12
lines changed

src/client/eppo-precomputed-client.ts

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import { decodePrecomputedFlag } from '../decoding';
1818
import { FlagEvaluationWithoutDetails } from '../evaluator';
1919
import FetchHttpClient from '../http-client';
20-
import { PrecomputedFlag } from '../interfaces';
20+
import { PrecomputedFlag, VariationType } from '../interfaces';
2121
import { getMD5Hash } from '../obfuscation';
2222
import initPoller, { IPoller } from '../poller';
2323
import PrecomputedRequestor from '../precomputed-requestor';
@@ -130,16 +130,12 @@ export default class EppoPrecomputedClient {
130130
}
131131
}
132132

133-
/**
134-
* Maps a subject to a string variation for a given experiment.
135-
*
136-
* @param flagKey feature flag identifier
137-
* @param defaultValue default value to return if the subject is not part of the experiment sample
138-
* The subject attributes are used for evaluating any targeting rules tied to the experiment.
139-
* @returns a variation value if a flag was precomputed for the subject, otherwise the default value
140-
* @public
141-
*/
142-
public getStringAssignment(flagKey: string, defaultValue: string): string {
133+
private getPrecomputedAssignment<T>(
134+
flagKey: string,
135+
defaultValue: T,
136+
expectedType: VariationType,
137+
valueTransformer: (value: unknown) => T = (v) => v as T,
138+
): T {
143139
validateNotBlank(flagKey, 'Invalid argument: flagKey cannot be blank');
144140

145141
const preComputedFlag = this.getPrecomputedFlag(flagKey);
@@ -149,6 +145,14 @@ export default class EppoPrecomputedClient {
149145
return defaultValue;
150146
}
151147

148+
// Check variation type
149+
if (preComputedFlag.variationType !== expectedType) {
150+
logger.error(
151+
`[Eppo SDK] Type mismatch: expected ${expectedType} but flag ${flagKey} has type ${preComputedFlag.variationType}`,
152+
);
153+
return defaultValue;
154+
}
155+
152156
const result: FlagEvaluationWithoutDetails = {
153157
flagKey,
154158
subjectKey: this.precomputedFlagsRequestParameters?.precompute.subjectKey ?? '',
@@ -169,7 +173,77 @@ export default class EppoPrecomputedClient {
169173
} catch (error) {
170174
logger.error(`[Eppo SDK] Error logging assignment event: ${error}`);
171175
}
172-
return (result.variation?.value as string) ?? defaultValue;
176+
177+
try {
178+
return result.variation?.value !== undefined
179+
? valueTransformer(result.variation.value)
180+
: defaultValue;
181+
} catch (error) {
182+
logger.error(`[Eppo SDK] Error transforming value: ${error}`);
183+
return defaultValue;
184+
}
185+
}
186+
187+
/**
188+
* Maps a subject to a string variation for a given experiment.
189+
*
190+
* @param flagKey feature flag identifier
191+
* @param defaultValue default value to return if the subject is not part of the experiment sample
192+
* @returns a variation value if a flag was precomputed for the subject, otherwise the default value
193+
* @public
194+
*/
195+
public getStringAssignment(flagKey: string, defaultValue: string): string {
196+
return this.getPrecomputedAssignment(flagKey, defaultValue, VariationType.STRING);
197+
}
198+
199+
/**
200+
* Maps a subject to a boolean variation for a given experiment.
201+
*
202+
* @param flagKey feature flag identifier
203+
* @param defaultValue default value to return if the subject is not part of the experiment sample
204+
* @returns a variation value if a flag was precomputed for the subject, otherwise the default value
205+
* @public
206+
*/
207+
public getBooleanAssignment(flagKey: string, defaultValue: boolean): boolean {
208+
return this.getPrecomputedAssignment(flagKey, defaultValue, VariationType.BOOLEAN);
209+
}
210+
211+
/**
212+
* Maps a subject to an integer variation for a given experiment.
213+
*
214+
* @param flagKey feature flag identifier
215+
* @param defaultValue default value to return if the subject is not part of the experiment sample
216+
* @returns a variation value if a flag was precomputed for the subject, otherwise the default value
217+
* @public
218+
*/
219+
public getIntegerAssignment(flagKey: string, defaultValue: number): number {
220+
return this.getPrecomputedAssignment(flagKey, defaultValue, VariationType.INTEGER);
221+
}
222+
223+
/**
224+
* Maps a subject to a numeric (floating point) variation for a given experiment.
225+
*
226+
* @param flagKey feature flag identifier
227+
* @param defaultValue default value to return if the subject is not part of the experiment sample
228+
* @returns a variation value if a flag was precomputed for the subject, otherwise the default value
229+
* @public
230+
*/
231+
public getNumericAssignment(flagKey: string, defaultValue: number): number {
232+
return this.getPrecomputedAssignment(flagKey, defaultValue, VariationType.NUMERIC);
233+
}
234+
235+
/**
236+
* Maps a subject to a JSON object variation for a given experiment.
237+
*
238+
* @param flagKey feature flag identifier
239+
* @param defaultValue default value to return if the subject is not part of the experiment sample
240+
* @returns a parsed JSON object if a flag was precomputed for the subject, otherwise the default value
241+
* @public
242+
*/
243+
public getJSONAssignment(flagKey: string, defaultValue: object): object {
244+
return this.getPrecomputedAssignment(flagKey, defaultValue, VariationType.JSON, (value) =>
245+
typeof value === 'string' ? JSON.parse(value) : defaultValue,
246+
);
173247
}
174248

175249
private getPrecomputedFlag(flagKey: string): PrecomputedFlag | null {

0 commit comments

Comments
 (0)