Skip to content

Commit a5ad4f8

Browse files
committed
fix: skip-segment-if-environment-flag-and-moved-flagsmith-id-to-id
1 parent 7c96f48 commit a5ad4f8

File tree

8 files changed

+49
-39
lines changed

8 files changed

+49
-39
lines changed

flagsmith-engine/evaluation/evaluationContext/mappers.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import {
55
GenericEvaluationContext,
66
EnvironmentContext,
77
IdentityContext,
8-
SegmentSource
8+
SegmentSource,
9+
CustomFeatureMetadata,
10+
SegmentsWithMetadata,
11+
CustomSegmentMetadata
912
} from '../models.js';
1013
import { EnvironmentModel } from '../../environments/models.js';
1114
import { IdentityModel } from '../../identities/models.js';
@@ -17,9 +20,13 @@ import { uuidToBigInt } from '../../features/util.js';
1720
export function getEvaluationContext(
1821
environment: EnvironmentModel,
1922
identity?: IdentityModel,
20-
overrideTraits?: TraitModel[]
23+
overrideTraits?: TraitModel[],
24+
isEnvironmentEvaluation: boolean = false
2125
): GenericEvaluationContext {
2226
const environmentContext = mapEnvironmentModelToEvaluationContext(environment);
27+
if (isEnvironmentEvaluation) {
28+
return environmentContext;
29+
}
2330
const identityContext = identity
2431
? mapIdentityModelToIdentityContext(identity, overrideTraits)
2532
: undefined;
@@ -40,7 +47,7 @@ function mapEnvironmentModelToEvaluationContext(
4047
name: environment.project.name
4148
};
4249

43-
const features: FeaturesWithMetadata = {};
50+
const features: FeaturesWithMetadata<CustomFeatureMetadata> = {};
4451
for (const fs of environment.featureStates) {
4552
const variants =
4653
fs.multivariateFeatureStateValues?.length > 0
@@ -59,12 +66,12 @@ function mapEnvironmentModelToEvaluationContext(
5966
variants,
6067
priority: fs.featureSegment?.priority,
6168
metadata: {
62-
flagsmithId: fs.feature.id
69+
id: fs.feature.id
6370
}
6471
};
6572
}
6673

67-
const segmentOverrides: Segments = {};
74+
const segmentOverrides: SegmentsWithMetadata<CustomSegmentMetadata> = {};
6875
for (const segment of environment.project.segments) {
6976
segmentOverrides[segment.id.toString()] = {
7077
key: segment.id.toString(),
@@ -79,18 +86,18 @@ function mapEnvironmentModelToEvaluationContext(
7986
value: fs.getValue(),
8087
priority: fs.featureSegment?.priority,
8188
metadata: {
82-
flagsmithId: fs.feature.id
89+
id: fs.feature.id
8390
}
8491
}))
8592
: [],
8693
metadata: {
8794
source: SegmentSource.API,
88-
flagsmithId: segment.id
95+
id: segment.id
8996
}
9097
};
9198
}
9299

93-
let identityOverrideSegments: Segments = {};
100+
let identityOverrideSegments: SegmentsWithMetadata<CustomSegmentMetadata> = {};
94101
if (environment.identityOverrides && environment.identityOverrides.length > 0) {
95102
identityOverrideSegments = mapIdentityOverridesToSegments(environment.identityOverrides);
96103
}
@@ -140,8 +147,10 @@ function mapSegmentRuleModelToRule(rule: any): any {
140147
};
141148
}
142149

143-
function mapIdentityOverridesToSegments(identityOverrides: IdentityModel[]): Segments {
144-
const segments: Segments = {};
150+
function mapIdentityOverridesToSegments(
151+
identityOverrides: IdentityModel[]
152+
): SegmentsWithMetadata<CustomSegmentMetadata> {
153+
const segments: SegmentsWithMetadata<CustomSegmentMetadata> = {};
145154
const featuresToIdentifiers = new Map<string, { identifiers: string[]; overrides: any[] }>();
146155

147156
for (const identity of identityOverrides) {
@@ -158,7 +167,7 @@ function mapIdentityOverridesToSegments(identityOverrides: IdentityModel[]): Seg
158167
value: fs.getValue(),
159168
priority: -Infinity,
160169
metadata: {
161-
flagsmithId: fs.feature.id
170+
id: fs.feature.id
162171
}
163172
}));
164173

flagsmith-engine/evaluation/models.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export enum SegmentSource {
2525

2626
// Feature types
2727
export interface CustomFeatureMetadata extends FeatureMetadata {
28-
flagsmithId: number;
28+
id: number;
2929
}
3030

3131
export interface FeatureContextWithMetadata<T extends FeatureMetadata = FeatureMetadata>
@@ -49,7 +49,7 @@ export type EvaluationResultFlags<T extends FeatureMetadata = FeatureMetadata> =
4949

5050
// Segment types
5151
export interface CustomSegmentMetadata extends SegmentMetadata {
52-
flagsmithId: number;
52+
id?: number;
5353
source?: SegmentSource;
5454
}
5555

@@ -68,7 +68,7 @@ export interface SegmentResultWithMetadata {
6868
metadata: CustomSegmentMetadata;
6969
}
7070

71-
export type EvaluationResultSegments = EvaluationContextResult['segments'];
71+
export type EvaluationResultSegments = SegmentResultWithMetadata[];
7272

7373
// Evaluation context types
7474
export interface GenericEvaluationContext<

flagsmith-engine/segments/models.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,13 @@ export class SegmentModel {
227227
if (segmentResult.metadata?.source === SegmentSource.IDENTITY_OVERRIDE) {
228228
continue;
229229
}
230-
const flagsmithId = segmentResult.metadata?.flagsmithId;
231-
if (!flagsmithId) {
230+
const segmentMetadataId = segmentResult.metadata?.id;
231+
if (!segmentMetadataId) {
232232
continue;
233233
}
234-
const segmentContext = evaluationContext.segments[flagsmithId.toString()];
234+
const segmentContext = evaluationContext.segments[segmentMetadataId.toString()];
235235
if (segmentContext) {
236-
const segment = new SegmentModel(flagsmithId, segmentContext.name);
236+
const segment = new SegmentModel(segmentMetadataId, segmentContext.name);
237237
segment.rules = segmentContext.rules.map(rule => new SegmentRuleModel(rule.type));
238238
segment.featureStates = SegmentModel.createFeatureStatesFromOverrides(
239239
segmentContext.overrides || []
@@ -249,13 +249,13 @@ export class SegmentModel {
249249
if (!overrides) return [];
250250
return overrides
251251
.filter(override => {
252-
const flagsmithId = override?.metadata?.flagsmithId;
253-
return typeof flagsmithId === 'number';
252+
const overrideMetadataId = override?.metadata?.id;
253+
return typeof overrideMetadataId === 'number';
254254
})
255255
.map(override => {
256-
const flagsmithId = override.metadata!.flagsmithId as number;
256+
const overrideMetadataId = override.metadata!.id as number;
257257
const feature = new FeatureModel(
258-
flagsmithId,
258+
overrideMetadataId,
259259
override.name,
260260
override.variants?.length && override.variants.length > 0
261261
? CONSTANTS.MULTIVARIATE

sdk/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from './types.js';
2626
import { pino, Logger } from 'pino';
2727
import { getEvaluationContext } from '../flagsmith-engine/evaluation/evaluationContext/mappers.js';
28+
import { EvaluationContextWithMetadata } from '../flagsmith-engine/evaluation/models.js';
2829

2930
export { AnalyticsProcessor, AnalyticsProcessorOptions } from './analytics.js';
3031
export { FlagsmithAPIError, FlagsmithClientError } from './errors.js';
@@ -282,7 +283,7 @@ export class Flagsmith {
282283
if (!context) {
283284
throw new FlagsmithClientError('Local evaluation required to obtain identity segments');
284285
}
285-
const evaluationResult = getEvaluationResult(context);
286+
const evaluationResult = getEvaluationResult(context as EvaluationContextWithMetadata);
286287

287288
return SegmentModel.fromSegmentResult(evaluationResult.segments, context);
288289
}
@@ -449,11 +450,11 @@ export class Flagsmith {
449450

450451
private async getEnvironmentFlagsFromDocument(): Promise<Flags> {
451452
const environment = await this.getEnvironment();
452-
const context = getEvaluationContext(environment);
453+
const context = getEvaluationContext(environment, undefined, undefined, true);
453454
if (!context) {
454455
throw new FlagsmithClientError('Unable to get flags. No environment present.');
455456
}
456-
const evaluationResult = getEvaluationResult(context);
457+
const evaluationResult = getEvaluationResult(context as EvaluationContextWithMetadata);
457458
const flags = Flags.fromEvaluationResult(evaluationResult);
458459

459460
if (!!this.cache) {
@@ -481,7 +482,7 @@ export class Flagsmith {
481482
if (!context) {
482483
throw new FlagsmithClientError('Unable to get flags. No environment present.');
483484
}
484-
const evaluationResult = getEvaluationResult(context);
485+
const evaluationResult = getEvaluationResult(context as EvaluationContextWithMetadata);
485486

486487
const flags = Flags.fromEvaluationResult(
487488
evaluationResult,

sdk/models.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,18 @@ export class Flags {
118118
): Flags {
119119
const flags: { [key: string]: Flag } = {};
120120
for (const flag of Object.values(evaluationResult.flags)) {
121-
const flagsmithId = flag.metadata?.flagsmithId;
122-
if (!flagsmithId) {
121+
const flagMetadataId = flag.metadata?.id;
122+
if (!flagMetadataId) {
123123
throw new Error(
124-
`FlagResult metadata.flagsmithId is missing for feature "${flag.name}". ` +
124+
`FlagResult metadata.id is missing for feature "${flag.name}". ` +
125125
`This indicates a bug in the SDK, please report it.`
126126
);
127127
}
128128

129129
flags[flag.name] = new Flag({
130130
enabled: flag.enabled,
131131
value: flag.value ?? null,
132-
featureId: flagsmithId,
132+
featureId: flagMetadataId,
133133
featureName: flag.name,
134134
reason: flag.reason
135135
});

tests/engine/unit/engine.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ test('shouldApplyOverride with priority conflicts', () => {
115115
enabled: true,
116116
value: 'value',
117117
priority: 5,
118-
metadata: { flagsmithId: 1 }
118+
metadata: { id: 1 }
119119
},
120120
segmentName: 'segment1'
121121
}
@@ -185,7 +185,7 @@ test('evaluateSegments handles segments with identity identifier matching', () =
185185
name: 'feature1',
186186
enabled: false,
187187
value: 'default_value',
188-
metadata: { flagsmithId: 1 }
188+
metadata: { id: 1 }
189189
}
190190
}
191191
};
@@ -272,7 +272,7 @@ test('evaluateSegments handles priority conflicts correctly', () => {
272272
name: 'feature1',
273273
enabled: false,
274274
value: 'default_value',
275-
metadata: { flagsmithId: 1 }
275+
metadata: { id: 1 }
276276
}
277277
}
278278
};
@@ -343,7 +343,7 @@ test('evaluateFeatures with multivariate evaluation', () => {
343343
{ value: 'variant_a', weight: 0, priority: 1 },
344344
{ value: 'variant_b', weight: 100, priority: 2 }
345345
],
346-
metadata: { flagsmithId: 1 }
346+
metadata: { id: 1 }
347347
}
348348
},
349349
identity: { key: 'test_user', identifier: 'test_user' },

tests/engine/unit/segments/segments_model.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ test('test_segment_rule_matching_function', () => {
141141
});
142142

143143
test('test_fromSegmentResult_with_multiple_variants', () => {
144-
const segmentResults = [{ name: 'test_segment', metadata: { flagsmithId: '1' } }];
144+
const segmentResults = [{ name: 'test_segment', metadata: { id: '1' } }];
145145

146146
const evaluationContext: EvaluationContext = {
147147
identity: {
@@ -159,7 +159,7 @@ test('test_fromSegmentResult_with_multiple_variants', () => {
159159
name: 'test_segment',
160160
metadata: {
161161
source: SegmentSource.API,
162-
flagsmithId: '1'
162+
id: '1'
163163
},
164164
rules: [
165165
{
@@ -181,7 +181,7 @@ test('test_fromSegmentResult_with_multiple_variants', () => {
181181
value: 'default_value',
182182
priority: 1,
183183
metadata: {
184-
flagsmithId: 1
184+
id: 1
185185
},
186186
variants: [
187187
{ id: 1, value: 'variant_a', weight: 30 },

tests/sdk/flagsmith.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ test('get_user_agent_extracts_version_from_package_json', async () => {
520520
expect(userAgent).toBe(`flagsmith-nodejs-sdk/${packageJson.version}`);
521521
});
522522

523-
test('Flags.fromEvaluationResult throws error when metadata.flagsmithId is missing', () => {
523+
test('Flags.fromEvaluationResult throws error when metadata.id is missing', () => {
524524
const evaluationResult = {
525525
flags: {
526526
test_feature: {
@@ -535,7 +535,7 @@ test('Flags.fromEvaluationResult throws error when metadata.flagsmithId is missi
535535
};
536536

537537
expect(() => Flags.fromEvaluationResult(evaluationResult as any)).toThrow(
538-
'FlagResult metadata.flagsmithId is missing for feature "test_feature". ' +
538+
'FlagResult metadata.id is missing for feature "test_feature". ' +
539539
'This indicates a bug in the SDK, please report it.'
540540
);
541541
});

0 commit comments

Comments
 (0)