@featurevisor/sdk
Version:
Featurevisor SDK for Node.js and the browser
142 lines (119 loc) • 3.08 kB
text/typescript
import { Allocation, Context, Traffic, Feature, Force } from "@featurevisor/types";
import { DatafileReader } from "./datafileReader";
import { allGroupSegmentsAreMatched } from "./segments";
import { allConditionsAreMatched } from "./conditions";
import { Logger } from "./logger";
export function getMatchedAllocation(
traffic: Traffic,
bucketValue: number,
): Allocation | undefined {
if (!traffic.allocation) {
return undefined;
}
for (const allocation of traffic.allocation) {
const [start, end] = allocation.range;
if (allocation.range && start <= bucketValue && end >= bucketValue) {
return allocation;
}
}
return undefined;
}
export function parseFromStringifiedSegments(value) {
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
return JSON.parse(value);
}
return value;
}
export function getMatchedTraffic(
traffic: Traffic[],
context: Context,
datafileReader: DatafileReader,
logger: Logger,
): Traffic | undefined {
const matchedTraffic = traffic.find((t) => {
if (
!allGroupSegmentsAreMatched(
parseFromStringifiedSegments(t.segments),
context,
datafileReader,
logger,
)
) {
return false;
}
return true;
});
if (matchedTraffic && matchedTraffic.percentage > 0) {
return matchedTraffic;
}
return;
}
export interface MatchedTrafficAndAllocation {
matchedTraffic: Traffic | undefined;
matchedAllocation: Allocation | undefined;
}
export function getMatchedTrafficAndAllocation(
traffic: Traffic[],
context: Context,
bucketValue: number,
datafileReader: DatafileReader,
logger: Logger,
): MatchedTrafficAndAllocation {
const matchedTraffic = traffic.find((t) => {
return allGroupSegmentsAreMatched(
parseFromStringifiedSegments(t.segments),
context,
datafileReader,
logger,
);
});
if (!matchedTraffic) {
return {
matchedTraffic: undefined,
matchedAllocation: undefined,
};
}
const matchedAllocation = getMatchedAllocation(matchedTraffic, bucketValue);
return {
matchedTraffic,
matchedAllocation,
};
}
export interface ForceResult {
force?: Force;
forceIndex?: number;
}
export function findForceFromFeature(
feature: Feature,
context: Context,
datafileReader: DatafileReader,
logger: Logger,
): ForceResult {
const result: ForceResult = {
force: undefined,
forceIndex: undefined,
};
if (!feature.force) {
return result;
}
for (let i = 0; i < feature.force.length; i++) {
const currentForce = feature.force[i];
if (
currentForce.conditions &&
allConditionsAreMatched(currentForce.conditions, context, logger)
) {
result.force = currentForce;
result.forceIndex = i;
break;
}
if (
currentForce.segments &&
allGroupSegmentsAreMatched(currentForce.segments, context, datafileReader, logger)
) {
result.force = currentForce;
result.forceIndex = i;
break;
}
}
return result;
}