@featurevisor/types
Version:
Common Typescript types for Featurevisor
365 lines (364 loc) • 9.86 kB
TypeScript
export type AttributeKey = string;
export type AttributeValue = string | number | boolean | Date | null | undefined;
export interface Context {
[key: AttributeKey]: AttributeValue;
}
export type AttributeType = "boolean" | "string" | "integer" | "double" | "date" | "semver";
export interface Attribute {
archived?: boolean;
key: AttributeKey;
type: AttributeType;
capture?: boolean;
description?: string;
}
export type Operator = "equals" | "notEquals" | "greaterThan" | "greaterThanOrEquals" | "lessThan" | "lessThanOrEquals" | "contains" | "notContains" | "startsWith" | "endsWith" | "semverEquals" | "semverNotEquals" | "semverGreaterThan" | "semverGreaterThanOrEquals" | "semverLessThan" | "semverLessThanOrEquals" | "before" | "after" | "in" | "notIn";
export type ConditionValue = string | number | boolean | Date | null | undefined | string[];
export interface PlainCondition {
attribute: AttributeKey;
operator: Operator;
value: ConditionValue;
}
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;
export type SegmentKey = string;
export interface Segment {
archived?: boolean;
key: SegmentKey;
conditions: Condition | Condition[] | string;
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 interface VariableOverrideBase {
value: VariableValue;
}
export type VariableOverrideSegmentsOrConditions = VariableOverrideSegments | VariableOverrideConditions;
export interface VariableOverride {
value: VariableValue;
conditions?: Condition | Condition[];
segments?: GroupSegment | GroupSegment[];
}
export interface Variable {
key: VariableKey;
value: VariableValue;
description?: string;
overrides?: VariableOverride[];
}
export interface Variation {
description?: string;
value: VariationValue;
weight?: Weight;
variables?: Variable[];
}
export interface VariableSchema {
deprecated?: boolean;
key: VariableKey;
type: VariableType;
defaultValue: VariableValue;
description?: string;
}
export type FeatureKey = string;
export interface Force {
conditions?: Condition | Condition[];
segments?: GroupSegment | GroupSegment[];
enabled?: boolean;
variation?: VariationValue;
variables?: {
[key: string]: VariableValue;
};
}
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;
};
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;
deprecated?: boolean;
required?: Required[];
variablesSchema?: VariableSchema[] | Record<VariableKey, VariableSchema>;
variations?: Variation[];
bucketBy: BucketBy;
traffic: Traffic[];
force?: Force[];
ranges?: Range[];
}
export interface DatafileContentV1 {
schemaVersion: string;
revision: string;
attributes: Attribute[];
segments: Segment[];
features: Feature[];
}
export interface DatafileContentV2 {
schemaVersion: string;
revision: string;
attributes: {
[key: AttributeKey]: Attribute;
};
segments: {
[key: SegmentKey]: Segment;
};
features: {
[key: FeatureKey]: Feature;
};
}
export type DatafileContent = DatafileContentV1 | DatafileContentV2;
export interface OverrideFeature {
enabled: boolean;
variation?: VariationValue;
variables?: {
[key: VariableKey]: VariableValue;
};
}
export interface StickyFeatures {
[key: FeatureKey]: OverrideFeature;
}
export type InitialFeatures = StickyFeatures;
/**
* YAML-only type
*/
export type Weight = number;
export type EnvironmentKey = 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;
};
}
export type Tag = string;
export type Expose = boolean | Tag[];
export interface Environment {
expose?: Expose;
rules: Rule[];
force?: Force[];
}
export interface ParsedFeature {
key: FeatureKey;
archived?: boolean;
deprecated?: boolean;
description: string;
tags: Tag[];
required?: Required[];
bucketBy: BucketBy;
variablesSchema?: VariableSchema[];
variations?: Variation[];
environments?: {
[key: EnvironmentKey]: Environment;
};
expose?: Expose;
rules?: Rule[];
force?: Force[];
}
/**
* For maintaining old allocations info,
* allowing for gradual rollout of new allocations
* with consistent bucketing
*/
export interface ExistingFeature {
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 FeatureAssertion {
matrix?: AssertionMatrix;
description?: string;
environment: EnvironmentKey;
at: Weight;
context: Context;
expectedToBeEnabled: boolean;
expectedVariation?: VariationValue;
expectedVariables?: {
[key: VariableKey]: VariableValue;
};
}
export interface TestFeature {
feature: FeatureKey;
assertions: FeatureAssertion[];
}
export interface SegmentAssertion {
matrix?: AssertionMatrix;
description?: string;
context: Context;
expectedToMatch: boolean;
}
export interface TestSegment {
segment: SegmentKey;
assertions: SegmentAssertion[];
}
export type Test = TestSegment | TestFeature;
export interface TestResultAssertionError {
type: "flag" | "variation" | "variable" | "segment";
expected: string | number | boolean | Date | null | undefined;
actual: string | number | boolean | Date | null | undefined;
message?: string;
details?: object;
}
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[];
}