@featurevisor/types
Version:
Common Typescript types for Featurevisor
438 lines (437 loc) • 12.1 kB
TypeScript
export type AttributeKey = string;
export interface AttributeObjectValue {
[key: AttributeKey]: AttributeValue;
}
export type AttributeValue = string | number | boolean | Date | null | undefined | string[] | AttributeObjectValue;
export interface Context {
[key: AttributeKey]: AttributeValue;
}
export type AttributeType = "boolean" | "string" | "integer" | "double" | "date" | "semver" | "object" | "array";
export interface Attribute {
archived?: boolean;
key?: AttributeKey;
type: AttributeType;
description?: string;
properties?: {
[key: AttributeKey]: {
type: "boolean" | "string" | "integer" | "double" | "date" | "semver" | "array";
description?: string;
};
};
}
export type Operator = "equals" | "notEquals" | "exists" | "notExists" | "greaterThan" | "greaterThanOrEquals" | "lessThan" | "lessThanOrEquals" | "contains" | "notContains" | "startsWith" | "endsWith" | "semverEquals" | "semverNotEquals" | "semverGreaterThan" | "semverGreaterThanOrEquals" | "semverLessThan" | "semverLessThanOrEquals" | "before" | "after" | "includes" | "notIncludes" | "matches" | "notMatches" | "in" | "notIn";
export type ConditionValue = string | number | boolean | Date | null | undefined | string[];
export interface PlainCondition {
attribute: AttributeKey;
operator: Operator;
value?: ConditionValue;
regexFlags?: string;
}
export interface AndCondition {
and: Condition[];
}
export interface OrCondition {
or: Condition[];
}
export interface NotCondition {
not: Condition[];
}
export type AndOrNotCondition = AndCondition | OrCondition | NotCondition;
export type Condition = PlainCondition | AndOrNotCondition | string;
export type SegmentKey = string;
export interface Segment {
archived?: boolean;
key?: SegmentKey;
conditions: Condition | Condition[];
description?: string;
}
export type PlainGroupSegment = SegmentKey;
export interface AndGroupSegment {
and: GroupSegment[];
}
export interface OrGroupSegment {
or: GroupSegment[];
}
export interface NotGroupSegment {
not: GroupSegment[];
}
export type AndOrNotGroupSegment = AndGroupSegment | OrGroupSegment | NotGroupSegment;
export type GroupSegment = PlainGroupSegment | AndOrNotGroupSegment;
export type VariationValue = string;
export type VariableKey = string;
export type VariableType = "boolean" | "string" | "integer" | "double" | "array" | "object" | "json";
export interface VariableObjectValue {
[key: string]: VariableValue;
}
export type VariableValue = boolean | string | number | string[] | VariableObjectValue | null | undefined;
export interface VariableOverrideSegments {
segments: GroupSegment | GroupSegment[];
}
export interface VariableOverrideConditions {
conditions: Condition | Condition[];
}
export type VariableOverrideSegmentsOrConditions = VariableOverrideSegments | VariableOverrideConditions;
export interface VariableOverride {
value: VariableValue;
conditions?: Condition | Condition[];
segments?: GroupSegment | GroupSegment[];
}
export interface VariableV1 {
key: VariableKey;
value: VariableValue;
description?: string;
overrides?: VariableOverride[];
}
export interface VariationV1 {
description?: string;
value: VariationValue;
weight?: Weight;
variables?: VariableV1[];
}
export interface Variation {
description?: string;
value: VariationValue;
weight?: Weight;
variables?: {
[key: VariableKey]: VariableValue;
};
variableOverrides?: {
[key: VariableKey]: VariableOverride[];
};
}
export interface VariableSchema {
deprecated?: boolean;
key?: VariableKey;
type: VariableType;
defaultValue: VariableValue;
description?: string;
useDefaultWhenDisabled?: boolean;
disabledValue?: VariableValue;
}
export type FeatureKey = string;
export interface Slot {
feature: FeatureKey | false;
percentage: Weight;
}
export interface Group {
key: string;
description: string;
slots: Slot[];
}
export type BucketKey = string;
export type BucketValue = number;
/**
* Datafile-only types
*/
export type Percentage = number;
export type Range = [Percentage, Percentage];
export interface Allocation {
variation: VariationValue;
range: Range;
}
export interface Traffic {
key: RuleKey;
segments: GroupSegment | GroupSegment[] | "*";
percentage: Percentage;
enabled?: boolean;
variation?: VariationValue;
variables?: {
[key: string]: VariableValue;
};
variationWeights?: {
[key: string]: Weight;
};
allocation?: Allocation[];
}
export type PlainBucketBy = AttributeKey;
export type AndBucketBy = AttributeKey[];
export interface OrBucketBy {
or: AttributeKey[];
}
export type BucketBy = PlainBucketBy | AndBucketBy | OrBucketBy;
export interface RequiredWithVariation {
key: FeatureKey;
variation: VariationValue;
}
export type Required = FeatureKey | RequiredWithVariation;
export interface Feature {
key?: FeatureKey;
hash?: string;
deprecated?: boolean;
required?: Required[];
variablesSchema?: Record<VariableKey, VariableSchema>;
disabledVariationValue?: VariationValue;
variations?: Variation[];
bucketBy: BucketBy;
traffic: Traffic[];
force?: Force[];
ranges?: Range[];
}
export interface FeatureV1 {
key?: FeatureKey;
hash?: string;
deprecated?: boolean;
required?: Required[];
bucketBy: BucketBy;
traffic: Traffic[];
force?: Force[];
ranges?: Range[];
variablesSchema?: VariableSchema[];
variations?: VariationV1[];
}
export interface DatafileContentV1 {
schemaVersion: string;
revision: string;
attributes: Attribute[];
segments: Segment[];
features: FeatureV1[];
}
export interface DatafileContent {
schemaVersion: string;
revision: string;
segments: {
[key: SegmentKey]: Segment;
};
features: {
[key: FeatureKey]: Feature;
};
}
export interface EvaluatedFeature {
enabled: boolean;
variation?: VariationValue;
variables?: {
[key: VariableKey]: VariableValue;
};
}
export interface EvaluatedFeatures {
[key: FeatureKey]: EvaluatedFeature;
}
export type StickyFeatures = EvaluatedFeatures;
/**
* YAML-only type
*/
export type Weight = number;
export type EnvironmentKey = string;
export type Tag = string;
export type RuleKey = string;
export interface Rule {
key: RuleKey;
description?: string;
segments: GroupSegment | GroupSegment[];
percentage: Weight;
enabled?: boolean;
variation?: VariationValue;
variables?: {
[key: string]: VariableValue;
};
variationWeights?: {
[key: string]: Weight;
};
}
export interface RulesByEnvironment {
[key: EnvironmentKey]: Rule[];
}
export interface Force {
conditions?: Condition | Condition[];
segments?: GroupSegment | GroupSegment[];
enabled?: boolean;
variation?: VariationValue;
variables?: {
[key: string]: VariableValue;
};
}
export interface ForceByEnvironment {
[key: EnvironmentKey]: Force[];
}
export type Expose = boolean | Tag[];
export interface ExposeByEnvironment {
[key: EnvironmentKey]: Expose;
}
export interface ParsedFeature {
key: FeatureKey;
archived?: boolean;
deprecated?: boolean;
description: string;
tags: Tag[];
required?: Required[];
bucketBy: BucketBy;
disabledVariationValue?: VariationValue;
variablesSchema?: Record<VariableKey, VariableSchema>;
variations?: Variation[];
expose?: ExposeByEnvironment | Expose;
force?: ForceByEnvironment | Force[];
rules?: RulesByEnvironment | Rule[];
}
/**
* For maintaining old allocations info,
* allowing for gradual rollout of new allocations
* with consistent bucketing
*/
export interface ExistingFeature {
hash?: string;
variations?: {
value: VariationValue;
weight: Weight;
}[];
traffic: {
key: RuleKey;
percentage: Percentage;
allocation?: Allocation[];
}[];
ranges?: Range[];
}
export interface ExistingFeatures {
[key: FeatureKey]: ExistingFeature;
}
export interface ExistingState {
features: ExistingFeatures;
}
/**
* Tests
*/
export interface AssertionMatrix {
[key: string]: AttributeValue[];
}
export interface ExpectedEvaluations {
flag?: Record<string, any>;
variation?: Record<string, any>;
variables?: {
[key: VariableKey]: Record<string, any>;
};
}
export interface FeatureChildAssertion {
sticky?: StickyFeatures;
context?: Context;
defaultVariationValue?: VariationValue;
defaultVariableValues?: {
[key: string]: VariableValue;
};
expectedToBeEnabled?: boolean;
expectedVariation?: VariationValue;
expectedVariables?: {
[key: VariableKey]: VariableValue;
};
expectedEvaluations?: ExpectedEvaluations;
}
export interface FeatureAssertion {
matrix?: AssertionMatrix;
description?: string;
environment: EnvironmentKey;
at?: Weight;
sticky?: StickyFeatures;
context?: Context;
defaultVariationValue?: VariationValue;
defaultVariableValues?: {
[key: string]: VariableValue;
};
expectedToBeEnabled?: boolean;
expectedVariation?: VariationValue;
expectedVariables?: {
[key: VariableKey]: VariableValue;
};
expectedEvaluations?: ExpectedEvaluations;
children?: FeatureChildAssertion[];
}
export interface TestFeature {
key?: string;
feature: FeatureKey;
assertions: FeatureAssertion[];
}
export interface SegmentAssertion {
matrix?: AssertionMatrix;
description?: string;
context: Context;
expectedToMatch: boolean;
}
export interface TestSegment {
key?: string;
segment: SegmentKey;
assertions: SegmentAssertion[];
}
export type Test = TestSegment | TestFeature;
export interface TestResultAssertionError {
type: "flag" | "variation" | "variable" | "segment" | "evaluation";
expected: string | number | boolean | Date | null | undefined;
actual: string | number | boolean | Date | null | undefined;
message?: string;
details?: {
evaluationType?: string;
evaluationKey?: string;
childIndex?: number;
[key: string]: any;
};
}
export interface TestResultAssertion {
description: string;
duration: number;
passed: boolean;
errors?: TestResultAssertionError[];
}
export interface TestResult {
type: "feature" | "segment";
key: string;
notFound?: boolean;
passed: boolean;
duration: number;
assertions: TestResultAssertion[];
}
/**
* Site index and history
*/
export type EntityType = "attribute" | "segment" | "feature" | "group" | "test";
export type CommitHash = string;
export interface HistoryEntity {
type: EntityType;
key: string;
}
export interface HistoryEntry {
commit: CommitHash;
author: string;
timestamp: string;
entities: HistoryEntity[];
}
export interface LastModified {
commit: CommitHash;
timestamp: string;
author: string;
}
export interface SearchIndex {
links?: {
feature: string;
segment: string;
attribute: string;
commit: CommitHash;
};
projectConfig: {
tags: Tag[];
environments: EnvironmentKey[] | false;
};
entities: {
attributes: (Attribute & {
lastModified?: LastModified;
usedInSegments: SegmentKey[];
usedInFeatures: FeatureKey[];
})[];
segments: (Segment & {
lastModified?: LastModified;
usedInFeatures: FeatureKey[];
})[];
features: (ParsedFeature & {
lastModified?: LastModified;
})[];
};
}
export interface EntityDiff {
type: EntityType;
key: string;
created?: boolean;
deleted?: boolean;
updated?: boolean;
content?: string;
}
export interface Commit {
hash: CommitHash;
author: string;
timestamp: string;
entities: EntityDiff[];
}