Skip to content

Commit c20e74f

Browse files
refactor: do not mutate FF definitions when parsing matchers
1 parent 5b84df3 commit c20e74f

File tree

4 files changed

+28
-22
lines changed

4 files changed

+28
-22
lines changed

src/evaluator/convertions/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1+
import { IBetweenMatcherData } from '../../dtos/types';
2+
13
export function zeroSinceHH(millisSinceEpoch: number): number {
24
return new Date(millisSinceEpoch).setUTCHours(0, 0, 0, 0);
35
}
46

57
export function zeroSinceSS(millisSinceEpoch: number): number {
68
return new Date(millisSinceEpoch).setUTCSeconds(0, 0);
79
}
10+
11+
export function betweenDateTimeTransform(betweenMatcherData: IBetweenMatcherData): IBetweenMatcherData {
12+
return {
13+
dataType: betweenMatcherData.dataType,
14+
start: zeroSinceSS(betweenMatcherData.start),
15+
end: zeroSinceSS(betweenMatcherData.end)
16+
};
17+
}

src/evaluator/matchersTransform/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/
33
import { segmentTransform } from './segment';
44
import { whitelistTransform } from './whitelist';
55
import { numericTransform } from './unaryNumeric';
6-
import { zeroSinceHH, zeroSinceSS } from '../convertions';
6+
import { zeroSinceHH, zeroSinceSS, betweenDateTimeTransform } from '../convertions';
77
import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData, ISplitMatcher, IUnaryNumericMatcherData } from '../../dtos/types';
88
import { IMatcherDto } from '../types';
99

@@ -32,7 +32,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
3232
let type = matcherTypesMapper(matcherType);
3333
// As default input data type we use string (even for ALL_KEYS)
3434
let dataType = matcherDataTypes.STRING;
35-
let value = undefined;
35+
let value;
3636

3737
if (type === matcherTypes.IN_SEGMENT) {
3838
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
@@ -60,8 +60,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
6060
dataType = matcherDataTypes.NUMBER;
6161

6262
if (value.dataType === 'DATETIME') {
63-
value.start = zeroSinceSS(value.start);
64-
value.end = zeroSinceSS(value.end);
63+
value = betweenDateTimeTransform(value);
6564
dataType = matcherDataTypes.DATETIME;
6665
}
6766
} else if (type === matcherTypes.BETWEEN_SEMVER) {

src/storages/__tests__/dataLoader.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ describe('getRolloutPlan & setRolloutPlan (client-side)', () => {
2121

2222
const expectedRolloutPlan = {
2323
splitChanges: {
24-
ff: { d: [{ name: 'split1' }], t: 123 },
25-
rbs: { d: [{ name: 'rbs1' }], t: 321 }
24+
ff: { d: [{ name: 'split1' }], t: 123, s: -1 },
25+
rbs: { d: [{ name: 'rbs1' }], t: 321, s: -1 }
2626
},
2727
memberships: {
2828
[fullSettings.core.key as string]: { ms: { k: [{ n: 'segment1' }] }, ls: { k: [] } },

src/storages/dataLoader.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,12 @@ export function getRolloutPlan(log: ILogger, storage: IStorageSync, options: Spl
102102
splitChanges: {
103103
ff: {
104104
t: splits.getChangeNumber(),
105+
s: -1,
105106
d: splits.getAll(),
106107
},
107108
rbs: {
108109
t: rbSegments.getChangeNumber(),
110+
s: -1,
109111
d: rbSegments.getAll(),
110112
}
111113
},
@@ -119,27 +121,22 @@ export function getRolloutPlan(log: ILogger, storage: IStorageSync, options: Spl
119121
undefined,
120122
memberships: keys ?
121123
keys.reduce<Record<string, IMembershipsResponse>>((prev, key) => {
122-
if (storage.shared) {
123-
// Client-side segments
124-
// @ts-ignore accessing private prop
125-
const sharedStorage = storage.shared(key);
126-
prev[getMatching(key)] = {
127-
ms: {
128-
// @ts-ignore accessing private prop
124+
const matchingKey = getMatching(key);
125+
if (storage.shared) { // Client-side segments
126+
const sharedStorage = storage.shared(matchingKey);
127+
prev[matchingKey] = {
128+
ms: { // @ts-ignore
129129
k: Object.keys(sharedStorage.segments.segmentCache).map(segmentName => ({ n: segmentName })),
130130
},
131-
ls: sharedStorage.largeSegments ? {
132-
// @ts-ignore accessing private prop
131+
ls: sharedStorage.largeSegments ? { // @ts-ignore
133132
k: Object.keys(sharedStorage.largeSegments.segmentCache).map(segmentName => ({ n: segmentName })),
134133
} : undefined
135134
};
136-
} else {
137-
prev[getMatching(key)] = {
138-
ms: {
139-
// Server-side segments
140-
// @ts-ignore accessing private prop
141-
k: Object.keys(storage.segments.segmentCache).reduce<IMySegmentsResponse['k']>((prev, segmentName) => { // @ts-ignore accessing private prop
142-
return storage.segments.segmentCache[segmentName].has(key) ?
135+
} else { // Server-side segments
136+
prev[matchingKey] = {
137+
ms: { // @ts-ignore
138+
k: Object.keys(storage.segments.segmentCache).reduce<IMySegmentsResponse['k']>((prev, segmentName) => { // @ts-ignore
139+
return storage.segments.segmentCache[segmentName].has(matchingKey) ?
143140
prev!.concat({ n: segmentName }) :
144141
prev;
145142
}, [])

0 commit comments

Comments
 (0)