flagsmith-nodejs 3.3.3 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +2 -2
- package/.github/workflows/pull_request.yaml +3 -4
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/models.d.ts +3 -3
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/models.js +20 -13
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/util.d.ts +1 -1
- package/build/cjs/flagsmith-engine/environments/util.js +23 -0
- package/build/cjs/flagsmith-engine/features/models.js +118 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/util.d.ts +1 -1
- package/build/cjs/flagsmith-engine/features/util.js +27 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/models.d.ts +2 -2
- package/build/cjs/flagsmith-engine/identities/models.js +48 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/traits/models.js +5 -4
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/util.d.ts +2 -2
- package/build/cjs/flagsmith-engine/identities/util.js +22 -0
- package/build/cjs/flagsmith-engine/index.d.ts +14 -0
- package/build/cjs/flagsmith-engine/index.js +75 -0
- package/build/cjs/flagsmith-engine/organisations/models.js +21 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/organisations/util.d.ts +1 -1
- package/build/cjs/flagsmith-engine/organisations/util.js +8 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/models.d.ts +2 -2
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/models.js +8 -5
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/util.d.ts +1 -1
- package/build/cjs/flagsmith-engine/projects/util.js +15 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/evaluators.d.ts +4 -4
- package/build/cjs/flagsmith-engine/segments/evaluators.js +37 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/models.d.ts +1 -1
- package/build/cjs/flagsmith-engine/segments/models.js +114 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/util.d.ts +1 -1
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/util.js +9 -11
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/collections.d.ts +1 -1
- package/build/cjs/flagsmith-engine/utils/collections.js +6 -0
- package/build/cjs/flagsmith-engine/utils/errors.js +6 -0
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/hashing/index.js +8 -11
- package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/index.js +5 -5
- package/build/{index.d.ts → cjs/index.d.ts} +3 -3
- package/build/{index.js → cjs/index.js} +17 -17
- package/build/cjs/package.json +1 -0
- package/build/{sdk → cjs/sdk}/analytics.d.ts +3 -0
- package/build/cjs/sdk/analytics.js +73 -0
- package/build/cjs/sdk/errors.js +9 -0
- package/build/{sdk → cjs/sdk}/index.d.ts +19 -18
- package/build/cjs/sdk/index.js +400 -0
- package/build/{sdk → cjs/sdk}/models.d.ts +2 -2
- package/build/cjs/sdk/models.js +101 -0
- package/build/{sdk → cjs/sdk}/offline_handlers.d.ts +1 -1
- package/build/cjs/sdk/offline_handlers.js +46 -0
- package/build/{sdk → cjs/sdk}/polling_manager.d.ts +1 -1
- package/build/cjs/sdk/polling_manager.js +29 -0
- package/build/{sdk → cjs/sdk}/types.d.ts +15 -7
- package/build/cjs/sdk/utils.d.ts +36 -0
- package/build/cjs/sdk/utils.js +63 -0
- package/build/esm/flagsmith-engine/environments/models.d.ts +22 -0
- package/build/esm/flagsmith-engine/environments/models.js +32 -0
- package/build/esm/flagsmith-engine/environments/util.d.ts +3 -0
- package/build/esm/flagsmith-engine/environments/util.js +18 -0
- package/build/esm/flagsmith-engine/features/constants.d.ts +4 -0
- package/build/esm/flagsmith-engine/features/constants.js +4 -0
- package/build/esm/flagsmith-engine/features/models.d.ts +37 -0
- package/build/esm/flagsmith-engine/features/models.js +110 -0
- package/build/esm/flagsmith-engine/features/util.d.ts +4 -0
- package/build/esm/flagsmith-engine/features/util.js +21 -0
- package/build/esm/flagsmith-engine/identities/models.d.ts +15 -0
- package/build/esm/flagsmith-engine/identities/models.js +44 -0
- package/build/esm/flagsmith-engine/identities/traits/models.d.ts +5 -0
- package/build/esm/flagsmith-engine/identities/traits/models.js +8 -0
- package/build/esm/flagsmith-engine/identities/util.d.ts +4 -0
- package/build/esm/flagsmith-engine/identities/util.js +17 -0
- package/build/esm/flagsmith-engine/index.d.ts +14 -0
- package/build/esm/flagsmith-engine/index.js +62 -0
- package/build/esm/flagsmith-engine/organisations/models.d.ts +9 -0
- package/build/esm/flagsmith-engine/organisations/models.js +17 -0
- package/build/esm/flagsmith-engine/organisations/util.d.ts +2 -0
- package/build/esm/flagsmith-engine/organisations/util.js +4 -0
- package/build/esm/flagsmith-engine/projects/models.d.ts +10 -0
- package/build/esm/flagsmith-engine/projects/models.js +13 -0
- package/build/esm/flagsmith-engine/projects/util.d.ts +2 -0
- package/build/esm/flagsmith-engine/projects/util.js +11 -0
- package/build/esm/flagsmith-engine/segments/constants.d.ts +34 -0
- package/build/esm/flagsmith-engine/segments/constants.js +36 -0
- package/build/esm/flagsmith-engine/segments/evaluators.d.ts +7 -0
- package/build/esm/flagsmith-engine/segments/evaluators.js +31 -0
- package/build/esm/flagsmith-engine/segments/models.d.ts +37 -0
- package/build/esm/flagsmith-engine/segments/models.js +102 -0
- package/build/esm/flagsmith-engine/segments/util.d.ts +6 -0
- package/build/esm/flagsmith-engine/segments/util.js +23 -0
- package/build/esm/flagsmith-engine/utils/collections.d.ts +3 -0
- package/build/esm/flagsmith-engine/utils/collections.js +2 -0
- package/build/esm/flagsmith-engine/utils/errors.d.ts +2 -0
- package/build/esm/flagsmith-engine/utils/errors.js +2 -0
- package/build/esm/flagsmith-engine/utils/hashing/index.d.ts +9 -0
- package/build/esm/flagsmith-engine/utils/hashing/index.js +50 -0
- package/build/esm/flagsmith-engine/utils/index.d.ts +1 -0
- package/build/esm/flagsmith-engine/utils/index.js +13 -0
- package/build/esm/index.d.ts +3 -0
- package/build/esm/index.js +4 -0
- package/build/esm/sdk/analytics.d.ts +35 -0
- package/build/esm/sdk/analytics.js +69 -0
- package/build/esm/sdk/errors.d.ts +4 -0
- package/build/esm/sdk/errors.js +4 -0
- package/build/esm/sdk/index.d.ts +131 -0
- package/build/esm/sdk/index.js +390 -0
- package/build/esm/sdk/models.d.ts +55 -0
- package/build/esm/sdk/models.js +94 -0
- package/build/esm/sdk/offline_handlers.d.ts +9 -0
- package/build/esm/sdk/offline_handlers.js +18 -0
- package/build/esm/sdk/polling_manager.d.ts +9 -0
- package/build/esm/sdk/polling_manager.js +25 -0
- package/build/esm/sdk/types.d.ts +38 -0
- package/build/esm/sdk/types.js +1 -0
- package/build/esm/sdk/utils.d.ts +36 -0
- package/build/esm/sdk/utils.js +56 -0
- package/flagsmith-engine/environments/models.ts +3 -3
- package/flagsmith-engine/environments/util.ts +4 -4
- package/flagsmith-engine/features/models.ts +1 -1
- package/flagsmith-engine/features/util.ts +1 -1
- package/flagsmith-engine/identities/models.ts +3 -4
- package/flagsmith-engine/identities/traits/models.ts +0 -1
- package/flagsmith-engine/identities/util.ts +4 -4
- package/flagsmith-engine/index.ts +13 -13
- package/flagsmith-engine/organisations/util.ts +1 -1
- package/flagsmith-engine/projects/models.ts +2 -2
- package/flagsmith-engine/projects/util.ts +4 -4
- package/flagsmith-engine/segments/evaluators.ts +6 -6
- package/flagsmith-engine/segments/models.ts +4 -4
- package/flagsmith-engine/segments/util.ts +3 -3
- package/flagsmith-engine/utils/collections.ts +1 -1
- package/flagsmith-engine/utils/index.ts +1 -1
- package/index.ts +4 -4
- package/package.json +21 -9
- package/sdk/analytics.ts +7 -5
- package/sdk/index.ts +55 -46
- package/sdk/models.ts +2 -3
- package/sdk/offline_handlers.ts +2 -2
- package/sdk/polling_manager.ts +2 -3
- package/sdk/types.ts +35 -24
- package/sdk/utils.ts +49 -37
- package/tests/engine/e2e/engine.test.ts +5 -5
- package/tests/engine/unit/engine.test.ts +5 -5
- package/tests/engine/unit/segments/segment_evaluators.test.ts +9 -9
- package/tests/engine/unit/utils/utils.test.ts +1 -1
- package/tests/sdk/analytics.test.ts +8 -13
- package/tests/sdk/data/identity-with-transient-traits.json +41 -0
- package/tests/sdk/data/transient-identity.json +29 -0
- package/tests/sdk/flagsmith-cache.test.ts +16 -32
- package/tests/sdk/flagsmith-environment-flags.test.ts +21 -36
- package/tests/sdk/flagsmith-identity-flags.test.ts +83 -32
- package/tests/sdk/flagsmith.test.ts +67 -99
- package/tests/sdk/offline-handlers.test.ts +4 -5
- package/tests/sdk/polling.test.ts +6 -8
- package/tests/sdk/utils.ts +19 -15
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.esm.json +7 -0
- package/tsconfig.json +7 -3
- package/vitest.config.ts +17 -0
- package/build/flagsmith-engine/environments/util.js +0 -27
- package/build/flagsmith-engine/features/models.js +0 -132
- package/build/flagsmith-engine/features/util.js +0 -27
- package/build/flagsmith-engine/identities/models.js +0 -113
- package/build/flagsmith-engine/identities/util.js +0 -46
- package/build/flagsmith-engine/index.d.ts +0 -14
- package/build/flagsmith-engine/index.js +0 -127
- package/build/flagsmith-engine/organisations/models.js +0 -21
- package/build/flagsmith-engine/organisations/util.js +0 -8
- package/build/flagsmith-engine/projects/util.js +0 -15
- package/build/flagsmith-engine/segments/evaluators.js +0 -45
- package/build/flagsmith-engine/segments/models.js +0 -147
- package/build/flagsmith-engine/utils/collections.js +0 -26
- package/build/flagsmith-engine/utils/errors.js +0 -26
- package/build/sdk/analytics.js +0 -120
- package/build/sdk/errors.js +0 -34
- package/build/sdk/index.js +0 -594
- package/build/sdk/models.js +0 -149
- package/build/sdk/offline_handlers.js +0 -66
- package/build/sdk/polling_manager.js +0 -72
- package/build/sdk/utils.d.ts +0 -12
- package/build/sdk/utils.js +0 -107
- package/jest.config.js +0 -5
- package/tests/index.js +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/constants.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/constants.js +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/models.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/traits/models.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/organisations/models.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/constants.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/constants.js +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/errors.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/hashing/index.d.ts +0 -0
- /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/index.d.ts +0 -0
- /package/build/{sdk → cjs/sdk}/errors.d.ts +0 -0
- /package/build/{sdk → cjs/sdk}/types.js +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Segment Rules
|
|
2
|
+
export const ALL_RULE = 'ALL';
|
|
3
|
+
export const ANY_RULE = 'ANY';
|
|
4
|
+
export const NONE_RULE = 'NONE';
|
|
5
|
+
export const RULE_TYPES = [ALL_RULE, ANY_RULE, NONE_RULE];
|
|
6
|
+
// Segment Condition Operators
|
|
7
|
+
export const EQUAL = 'EQUAL';
|
|
8
|
+
export const GREATER_THAN = 'GREATER_THAN';
|
|
9
|
+
export const LESS_THAN = 'LESS_THAN';
|
|
10
|
+
export const LESS_THAN_INCLUSIVE = 'LESS_THAN_INCLUSIVE';
|
|
11
|
+
export const CONTAINS = 'CONTAINS';
|
|
12
|
+
export const GREATER_THAN_INCLUSIVE = 'GREATER_THAN_INCLUSIVE';
|
|
13
|
+
export const NOT_CONTAINS = 'NOT_CONTAINS';
|
|
14
|
+
export const NOT_EQUAL = 'NOT_EQUAL';
|
|
15
|
+
export const REGEX = 'REGEX';
|
|
16
|
+
export const PERCENTAGE_SPLIT = 'PERCENTAGE_SPLIT';
|
|
17
|
+
export const IS_SET = 'IS_SET';
|
|
18
|
+
export const IS_NOT_SET = 'IS_NOT_SET';
|
|
19
|
+
export const MODULO = 'MODULO';
|
|
20
|
+
export const IN = 'IN';
|
|
21
|
+
export const CONDITION_OPERATORS = {
|
|
22
|
+
EQUAL,
|
|
23
|
+
GREATER_THAN,
|
|
24
|
+
LESS_THAN,
|
|
25
|
+
LESS_THAN_INCLUSIVE,
|
|
26
|
+
CONTAINS,
|
|
27
|
+
GREATER_THAN_INCLUSIVE,
|
|
28
|
+
NOT_CONTAINS,
|
|
29
|
+
NOT_EQUAL,
|
|
30
|
+
REGEX,
|
|
31
|
+
PERCENTAGE_SPLIT,
|
|
32
|
+
IS_SET,
|
|
33
|
+
IS_NOT_SET,
|
|
34
|
+
MODULO,
|
|
35
|
+
IN
|
|
36
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EnvironmentModel } from '../environments/models.js';
|
|
2
|
+
import { IdentityModel } from '../identities/models.js';
|
|
3
|
+
import { TraitModel } from '../identities/traits/models.js';
|
|
4
|
+
import { SegmentConditionModel, SegmentModel } from './models.js';
|
|
5
|
+
export declare function getIdentitySegments(environment: EnvironmentModel, identity: IdentityModel, overrideTraits?: TraitModel[]): SegmentModel[];
|
|
6
|
+
export declare function evaluateIdentityInSegment(identity: IdentityModel, segment: SegmentModel, overrideTraits?: TraitModel[]): boolean;
|
|
7
|
+
export declare function traitsMatchSegmentCondition(identityTraits: TraitModel[], condition: SegmentConditionModel, segmentId: number | string, identityId: number | string): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getHashedPercentateForObjIds } from '../utils/hashing/index.js';
|
|
2
|
+
import { PERCENTAGE_SPLIT, IS_SET, IS_NOT_SET } from './constants.js';
|
|
3
|
+
export function getIdentitySegments(environment, identity, overrideTraits) {
|
|
4
|
+
return environment.project.segments.filter(segment => evaluateIdentityInSegment(identity, segment, overrideTraits));
|
|
5
|
+
}
|
|
6
|
+
export function evaluateIdentityInSegment(identity, segment, overrideTraits) {
|
|
7
|
+
return (segment.rules.length > 0 &&
|
|
8
|
+
segment.rules.filter(rule => traitsMatchSegmentRule(overrideTraits || identity.identityTraits, rule, segment.id, identity.djangoID || identity.compositeKey)).length === segment.rules.length);
|
|
9
|
+
}
|
|
10
|
+
function traitsMatchSegmentRule(identityTraits, rule, segmentId, identityId) {
|
|
11
|
+
const matchesConditions = rule.conditions.length > 0
|
|
12
|
+
? rule.matchingFunction()(rule.conditions.map(condition => traitsMatchSegmentCondition(identityTraits, condition, segmentId, identityId)))
|
|
13
|
+
: true;
|
|
14
|
+
return (matchesConditions &&
|
|
15
|
+
rule.rules.filter(rule => traitsMatchSegmentRule(identityTraits, rule, segmentId, identityId)).length === rule.rules.length);
|
|
16
|
+
}
|
|
17
|
+
export function traitsMatchSegmentCondition(identityTraits, condition, segmentId, identityId) {
|
|
18
|
+
if (condition.operator == PERCENTAGE_SPLIT) {
|
|
19
|
+
var hashedPercentage = getHashedPercentateForObjIds([segmentId, identityId]);
|
|
20
|
+
return hashedPercentage <= parseFloat(String(condition.value));
|
|
21
|
+
}
|
|
22
|
+
const traits = identityTraits.filter(t => t.traitKey === condition.property_);
|
|
23
|
+
const trait = traits.length > 0 ? traits[0] : undefined;
|
|
24
|
+
if (condition.operator === IS_SET) {
|
|
25
|
+
return !!trait;
|
|
26
|
+
}
|
|
27
|
+
else if (condition.operator === IS_NOT_SET) {
|
|
28
|
+
return trait == undefined;
|
|
29
|
+
}
|
|
30
|
+
return trait ? condition.matchesTraitValue(trait.traitValue) : false;
|
|
31
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { FeatureStateModel } from '../features/models.js';
|
|
2
|
+
export declare const all: (iterable: Array<any>) => boolean;
|
|
3
|
+
export declare const any: (iterable: Array<any>) => boolean;
|
|
4
|
+
export declare const matchingFunctions: {
|
|
5
|
+
[x: string]: (thisValue: any, otherValue: any) => any;
|
|
6
|
+
};
|
|
7
|
+
export declare const semverMatchingFunction: {
|
|
8
|
+
[x: string]: ((thisValue: any, otherValue: any) => any) | ((thisValue: any, otherValue: any) => boolean);
|
|
9
|
+
};
|
|
10
|
+
export declare const getMatchingFunctions: (semver: boolean) => {
|
|
11
|
+
[x: string]: (thisValue: any, otherValue: any) => any;
|
|
12
|
+
};
|
|
13
|
+
export declare class SegmentConditionModel {
|
|
14
|
+
EXCEPTION_OPERATOR_METHODS: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
17
|
+
operator: string;
|
|
18
|
+
value: string | null | undefined;
|
|
19
|
+
property_: string | null | undefined;
|
|
20
|
+
constructor(operator: string, value?: string | null | undefined, property?: string | null | undefined);
|
|
21
|
+
matchesTraitValue(traitValue: any): any;
|
|
22
|
+
}
|
|
23
|
+
export declare class SegmentRuleModel {
|
|
24
|
+
type: string;
|
|
25
|
+
rules: SegmentRuleModel[];
|
|
26
|
+
conditions: SegmentConditionModel[];
|
|
27
|
+
constructor(type: string);
|
|
28
|
+
static none(iterable: Array<any>): boolean;
|
|
29
|
+
matchingFunction(): CallableFunction;
|
|
30
|
+
}
|
|
31
|
+
export declare class SegmentModel {
|
|
32
|
+
id: number;
|
|
33
|
+
name: string;
|
|
34
|
+
rules: SegmentRuleModel[];
|
|
35
|
+
featureStates: FeatureStateModel[];
|
|
36
|
+
constructor(id: number, name: string);
|
|
37
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import semver from 'semver';
|
|
2
|
+
import { getCastingFunction as getCastingFunction } from '../utils/index.js';
|
|
3
|
+
import { ALL_RULE, ANY_RULE, NONE_RULE, NOT_CONTAINS, REGEX, MODULO, IN, CONDITION_OPERATORS } from './constants.js';
|
|
4
|
+
import { isSemver } from './util.js';
|
|
5
|
+
export const all = (iterable) => iterable.filter(e => !!e).length === iterable.length;
|
|
6
|
+
export const any = (iterable) => iterable.filter(e => !!e).length > 0;
|
|
7
|
+
export const matchingFunctions = {
|
|
8
|
+
[CONDITION_OPERATORS.EQUAL]: (thisValue, otherValue) => thisValue == otherValue,
|
|
9
|
+
[CONDITION_OPERATORS.GREATER_THAN]: (thisValue, otherValue) => otherValue > thisValue,
|
|
10
|
+
[CONDITION_OPERATORS.GREATER_THAN_INCLUSIVE]: (thisValue, otherValue) => otherValue >= thisValue,
|
|
11
|
+
[CONDITION_OPERATORS.LESS_THAN]: (thisValue, otherValue) => thisValue > otherValue,
|
|
12
|
+
[CONDITION_OPERATORS.LESS_THAN_INCLUSIVE]: (thisValue, otherValue) => thisValue >= otherValue,
|
|
13
|
+
[CONDITION_OPERATORS.NOT_EQUAL]: (thisValue, otherValue) => thisValue != otherValue,
|
|
14
|
+
[CONDITION_OPERATORS.CONTAINS]: (thisValue, otherValue) => !!otherValue && otherValue.includes(thisValue),
|
|
15
|
+
};
|
|
16
|
+
export const semverMatchingFunction = {
|
|
17
|
+
...matchingFunctions,
|
|
18
|
+
[CONDITION_OPERATORS.EQUAL]: (thisValue, otherValue) => semver.eq(thisValue, otherValue),
|
|
19
|
+
[CONDITION_OPERATORS.GREATER_THAN]: (thisValue, otherValue) => semver.gt(otherValue, thisValue),
|
|
20
|
+
[CONDITION_OPERATORS.GREATER_THAN_INCLUSIVE]: (thisValue, otherValue) => semver.gte(otherValue, thisValue),
|
|
21
|
+
[CONDITION_OPERATORS.LESS_THAN]: (thisValue, otherValue) => semver.gt(thisValue, otherValue),
|
|
22
|
+
[CONDITION_OPERATORS.LESS_THAN_INCLUSIVE]: (thisValue, otherValue) => semver.gte(thisValue, otherValue),
|
|
23
|
+
};
|
|
24
|
+
export const getMatchingFunctions = (semver) => (semver ? semverMatchingFunction : matchingFunctions);
|
|
25
|
+
export class SegmentConditionModel {
|
|
26
|
+
EXCEPTION_OPERATOR_METHODS = {
|
|
27
|
+
[NOT_CONTAINS]: 'evaluateNotContains',
|
|
28
|
+
[REGEX]: 'evaluateRegex',
|
|
29
|
+
[MODULO]: 'evaluateModulo',
|
|
30
|
+
[IN]: 'evaluateIn'
|
|
31
|
+
};
|
|
32
|
+
operator;
|
|
33
|
+
value;
|
|
34
|
+
property_;
|
|
35
|
+
constructor(operator, value, property) {
|
|
36
|
+
this.operator = operator;
|
|
37
|
+
this.value = value;
|
|
38
|
+
this.property_ = property;
|
|
39
|
+
}
|
|
40
|
+
matchesTraitValue(traitValue) {
|
|
41
|
+
const evaluators = {
|
|
42
|
+
evaluateNotContains: (traitValue) => {
|
|
43
|
+
return typeof traitValue == "string" &&
|
|
44
|
+
!!this.value &&
|
|
45
|
+
!traitValue.includes(this.value?.toString());
|
|
46
|
+
},
|
|
47
|
+
evaluateRegex: (traitValue) => {
|
|
48
|
+
return !!this.value && !!traitValue?.toString().match(new RegExp(this.value));
|
|
49
|
+
},
|
|
50
|
+
evaluateModulo: (traitValue) => {
|
|
51
|
+
if (isNaN(parseFloat(traitValue)) || !this.value) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const parts = (this.value).split("|");
|
|
55
|
+
const [divisor, reminder] = [parseFloat(parts[0]), parseFloat(parts[1])];
|
|
56
|
+
return traitValue % divisor === reminder;
|
|
57
|
+
},
|
|
58
|
+
evaluateIn: (traitValue) => {
|
|
59
|
+
return this.value?.split(',').includes(traitValue.toString());
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
// TODO: move this logic to the evaluator module
|
|
63
|
+
if (this.EXCEPTION_OPERATOR_METHODS[this.operator]) {
|
|
64
|
+
const evaluatorFunction = evaluators[this.EXCEPTION_OPERATOR_METHODS[this.operator]];
|
|
65
|
+
return evaluatorFunction(traitValue);
|
|
66
|
+
}
|
|
67
|
+
const defaultFunction = (x, y) => false;
|
|
68
|
+
const matchingFunctionSet = getMatchingFunctions(isSemver(this.value));
|
|
69
|
+
const matchingFunction = matchingFunctionSet[this.operator] || defaultFunction;
|
|
70
|
+
const traitType = isSemver(this.value) ? 'semver' : typeof traitValue;
|
|
71
|
+
const castToTypeOfTraitValue = getCastingFunction(traitType);
|
|
72
|
+
return matchingFunction(castToTypeOfTraitValue(this.value), traitValue);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export class SegmentRuleModel {
|
|
76
|
+
type;
|
|
77
|
+
rules = [];
|
|
78
|
+
conditions = [];
|
|
79
|
+
constructor(type) {
|
|
80
|
+
this.type = type;
|
|
81
|
+
}
|
|
82
|
+
static none(iterable) {
|
|
83
|
+
return iterable.filter(e => !!e).length === 0;
|
|
84
|
+
}
|
|
85
|
+
matchingFunction() {
|
|
86
|
+
return {
|
|
87
|
+
[ANY_RULE]: any,
|
|
88
|
+
[ALL_RULE]: all,
|
|
89
|
+
[NONE_RULE]: SegmentRuleModel.none
|
|
90
|
+
}[this.type];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export class SegmentModel {
|
|
94
|
+
id;
|
|
95
|
+
name;
|
|
96
|
+
rules = [];
|
|
97
|
+
featureStates = [];
|
|
98
|
+
constructor(id, name) {
|
|
99
|
+
this.id = id;
|
|
100
|
+
this.name = name;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SegmentConditionModel, SegmentModel, SegmentRuleModel } from './models.js';
|
|
2
|
+
export declare function buildSegmentConditionModel(segmentConditionJSON: any): SegmentConditionModel;
|
|
3
|
+
export declare function buildSegmentRuleModel(ruleModelJSON: any): SegmentRuleModel;
|
|
4
|
+
export declare function buildSegmentModel(segmentModelJSON: any): SegmentModel;
|
|
5
|
+
export declare function isSemver(value: any): boolean;
|
|
6
|
+
export declare function removeSemverSuffix(value: string): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { buildFeatureStateModel } from '../features/util.js';
|
|
2
|
+
import { SegmentConditionModel, SegmentModel, SegmentRuleModel } from './models.js';
|
|
3
|
+
export function buildSegmentConditionModel(segmentConditionJSON) {
|
|
4
|
+
return new SegmentConditionModel(segmentConditionJSON.operator, segmentConditionJSON.value, segmentConditionJSON.property_);
|
|
5
|
+
}
|
|
6
|
+
export function buildSegmentRuleModel(ruleModelJSON) {
|
|
7
|
+
const ruleModel = new SegmentRuleModel(ruleModelJSON.type);
|
|
8
|
+
ruleModel.rules = ruleModelJSON.rules.map((r) => buildSegmentRuleModel(r));
|
|
9
|
+
ruleModel.conditions = ruleModelJSON.conditions.map((c) => buildSegmentConditionModel(c));
|
|
10
|
+
return ruleModel;
|
|
11
|
+
}
|
|
12
|
+
export function buildSegmentModel(segmentModelJSON) {
|
|
13
|
+
const model = new SegmentModel(segmentModelJSON.id, segmentModelJSON.name);
|
|
14
|
+
model.featureStates = segmentModelJSON['feature_states'].map((fs) => buildFeatureStateModel(fs));
|
|
15
|
+
model.rules = segmentModelJSON['rules'].map((r) => buildSegmentRuleModel(r));
|
|
16
|
+
return model;
|
|
17
|
+
}
|
|
18
|
+
export function isSemver(value) {
|
|
19
|
+
return typeof value == 'string' && value.endsWith(':semver');
|
|
20
|
+
}
|
|
21
|
+
export function removeSemverSuffix(value) {
|
|
22
|
+
return value.replace(':semver', '');
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a list of object ids, get a floating point number between 0 and 1 based on
|
|
3
|
+
* the hash of those ids. This should give the same value every time for any list of ids.
|
|
4
|
+
*
|
|
5
|
+
* @param {Array<any>} objectIds list of object ids to calculate the has for
|
|
6
|
+
* @param {} iterations=1 num times to include each id in the generated string to hash
|
|
7
|
+
* @returns number number between 0 (inclusive) and 100 (exclusive)
|
|
8
|
+
*/
|
|
9
|
+
export declare function getHashedPercentateForObjIds(objectIds: Array<any>, iterations?: number): number;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import md5 from 'md5';
|
|
2
|
+
import bigInt from 'big-integer';
|
|
3
|
+
const makeRepeated = (arr, repeats) => Array.from({ length: repeats }, () => arr).flat();
|
|
4
|
+
// https://stackoverflow.com/questions/12532871/how-to-convert-a-very-large-hex-number-to-decimal-in-javascript
|
|
5
|
+
function h2d(s) {
|
|
6
|
+
function add(x, y) {
|
|
7
|
+
var c = 0, r = [];
|
|
8
|
+
var x = x.split('').map(Number);
|
|
9
|
+
var y = y.split('').map(Number);
|
|
10
|
+
while (x.length || y.length) {
|
|
11
|
+
var s = (x.pop() || 0) + (y.pop() || 0) + c;
|
|
12
|
+
r.unshift(s < 10 ? s : s - 10);
|
|
13
|
+
c = s < 10 ? 0 : 1;
|
|
14
|
+
}
|
|
15
|
+
if (c)
|
|
16
|
+
r.unshift(c);
|
|
17
|
+
return r.join('');
|
|
18
|
+
}
|
|
19
|
+
var dec = '0';
|
|
20
|
+
s.split('').forEach(function (chr) {
|
|
21
|
+
var n = parseInt(chr, 16);
|
|
22
|
+
for (var t = 8; t; t >>= 1) {
|
|
23
|
+
dec = add(dec, dec);
|
|
24
|
+
if (n & t)
|
|
25
|
+
dec = add(dec, '1');
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return dec;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Given a list of object ids, get a floating point number between 0 and 1 based on
|
|
32
|
+
* the hash of those ids. This should give the same value every time for any list of ids.
|
|
33
|
+
*
|
|
34
|
+
* @param {Array<any>} objectIds list of object ids to calculate the has for
|
|
35
|
+
* @param {} iterations=1 num times to include each id in the generated string to hash
|
|
36
|
+
* @returns number number between 0 (inclusive) and 100 (exclusive)
|
|
37
|
+
*/
|
|
38
|
+
export function getHashedPercentateForObjIds(objectIds, iterations = 1) {
|
|
39
|
+
let toHash = makeRepeated(objectIds, iterations).join(',');
|
|
40
|
+
const hashedValue = md5(toHash);
|
|
41
|
+
const hashedInt = bigInt(h2d(hashedValue));
|
|
42
|
+
const value = (hashedInt.mod(9999).toJSNumber() / 9998) * 100;
|
|
43
|
+
// we ignore this for it's nearly impossible use case to catch
|
|
44
|
+
/* istanbul ignore next */
|
|
45
|
+
if (value === 100) {
|
|
46
|
+
/* istanbul ignore next */
|
|
47
|
+
return getHashedPercentateForObjIds(objectIds, iterations + 1);
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getCastingFunction(traitType: 'boolean' | 'string' | 'number' | 'semver' | any): CallableFunction;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { removeSemverSuffix } from "../segments/util.js";
|
|
2
|
+
export function getCastingFunction(traitType) {
|
|
3
|
+
switch (traitType) {
|
|
4
|
+
case 'boolean':
|
|
5
|
+
return (x) => !['False', 'false'].includes(x);
|
|
6
|
+
case 'number':
|
|
7
|
+
return (x) => parseFloat(x);
|
|
8
|
+
case 'semver':
|
|
9
|
+
return (x) => removeSemverSuffix(x);
|
|
10
|
+
default:
|
|
11
|
+
return (x) => String(x);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, FlagsmithCache, DefaultFlag, Flags, default } from './sdk/index.js';
|
|
2
|
+
export { FlagsmithConfig } from './sdk/types.js';
|
|
3
|
+
export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine/index.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import Flagsmith from "./sdk/index.js";
|
|
2
|
+
export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, DefaultFlag, Flags, default } from './sdk/index.js';
|
|
3
|
+
export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine/index.js';
|
|
4
|
+
module.exports = Flagsmith;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Logger } from 'pino';
|
|
2
|
+
import { Fetch } from "./types.js";
|
|
3
|
+
export declare class AnalyticsProcessor {
|
|
4
|
+
private analyticsEndpoint;
|
|
5
|
+
private environmentKey;
|
|
6
|
+
private lastFlushed;
|
|
7
|
+
analyticsData: {
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
private requestTimeoutMs;
|
|
11
|
+
private logger;
|
|
12
|
+
private currentFlush;
|
|
13
|
+
private customFetch;
|
|
14
|
+
/**
|
|
15
|
+
* AnalyticsProcessor is used to track how often individual Flags are evaluated within
|
|
16
|
+
* the Flagsmith SDK. Docs: https://docs.flagsmith.com/advanced-use/flag-analytics.
|
|
17
|
+
*
|
|
18
|
+
* @param data.environmentKey environment key obtained from the Flagsmith UI
|
|
19
|
+
* @param data.baseApiUrl base api url to override when using self hosted version
|
|
20
|
+
* @param data.requestTimeoutMs used to tell requests to stop waiting for a response after a
|
|
21
|
+
given number of milliseconds
|
|
22
|
+
*/
|
|
23
|
+
constructor(data: {
|
|
24
|
+
environmentKey: string;
|
|
25
|
+
baseApiUrl: string;
|
|
26
|
+
requestTimeoutMs?: number;
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
fetch?: Fetch;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Sends all the collected data to the api asynchronously and resets the timer
|
|
32
|
+
*/
|
|
33
|
+
flush(): Promise<void>;
|
|
34
|
+
trackFeature(featureName: string): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { pino } from 'pino';
|
|
2
|
+
const ANALYTICS_ENDPOINT = 'analytics/flags/';
|
|
3
|
+
// Used to control how often we send data(in seconds)
|
|
4
|
+
const ANALYTICS_TIMER = 10;
|
|
5
|
+
export class AnalyticsProcessor {
|
|
6
|
+
analyticsEndpoint;
|
|
7
|
+
environmentKey;
|
|
8
|
+
lastFlushed;
|
|
9
|
+
analyticsData;
|
|
10
|
+
requestTimeoutMs = 3000;
|
|
11
|
+
logger;
|
|
12
|
+
currentFlush;
|
|
13
|
+
customFetch;
|
|
14
|
+
/**
|
|
15
|
+
* AnalyticsProcessor is used to track how often individual Flags are evaluated within
|
|
16
|
+
* the Flagsmith SDK. Docs: https://docs.flagsmith.com/advanced-use/flag-analytics.
|
|
17
|
+
*
|
|
18
|
+
* @param data.environmentKey environment key obtained from the Flagsmith UI
|
|
19
|
+
* @param data.baseApiUrl base api url to override when using self hosted version
|
|
20
|
+
* @param data.requestTimeoutMs used to tell requests to stop waiting for a response after a
|
|
21
|
+
given number of milliseconds
|
|
22
|
+
*/
|
|
23
|
+
constructor(data) {
|
|
24
|
+
this.analyticsEndpoint = data.baseApiUrl + ANALYTICS_ENDPOINT;
|
|
25
|
+
this.environmentKey = data.environmentKey;
|
|
26
|
+
this.lastFlushed = Date.now();
|
|
27
|
+
this.analyticsData = {};
|
|
28
|
+
this.requestTimeoutMs = data.requestTimeoutMs || this.requestTimeoutMs;
|
|
29
|
+
this.logger = data.logger || pino();
|
|
30
|
+
this.customFetch = data.fetch ?? fetch;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Sends all the collected data to the api asynchronously and resets the timer
|
|
34
|
+
*/
|
|
35
|
+
async flush() {
|
|
36
|
+
if (this.currentFlush || !Object.keys(this.analyticsData).length) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
this.currentFlush = this.customFetch(this.analyticsEndpoint, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
body: JSON.stringify(this.analyticsData),
|
|
43
|
+
signal: AbortSignal.timeout(this.requestTimeoutMs),
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
'X-Environment-Key': this.environmentKey
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
await this.currentFlush;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// We don't want failing to write analytics to cause any exceptions in the main
|
|
53
|
+
// thread so we just swallow them here.
|
|
54
|
+
this.logger.warn('Failed to post analytics to Flagsmith API. Not clearing data, will retry.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
this.currentFlush = undefined;
|
|
59
|
+
}
|
|
60
|
+
this.analyticsData = {};
|
|
61
|
+
this.lastFlushed = Date.now();
|
|
62
|
+
}
|
|
63
|
+
trackFeature(featureName) {
|
|
64
|
+
this.analyticsData[featureName] = (this.analyticsData[featureName] || 0) + 1;
|
|
65
|
+
if (Date.now() - this.lastFlushed > ANALYTICS_TIMER * 1000) {
|
|
66
|
+
this.flush();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Dispatcher } from 'undici-types';
|
|
2
|
+
import { EnvironmentModel } from '../flagsmith-engine/index.js';
|
|
3
|
+
import { IdentityModel } from '../flagsmith-engine/index.js';
|
|
4
|
+
import { BaseOfflineHandler } from './offline_handlers.js';
|
|
5
|
+
import { DefaultFlag, Flags } from './models.js';
|
|
6
|
+
import { EnvironmentDataPollingManager } from './polling_manager.js';
|
|
7
|
+
import { SegmentModel } from '../flagsmith-engine/index.js';
|
|
8
|
+
import { FlagsmithConfig, FlagsmithTraitValue, ITraitConfig } from './types.js';
|
|
9
|
+
export { AnalyticsProcessor } from './analytics.js';
|
|
10
|
+
export { FlagsmithAPIError, FlagsmithClientError } from './errors.js';
|
|
11
|
+
export { DefaultFlag, Flags } from './models.js';
|
|
12
|
+
export { EnvironmentDataPollingManager } from './polling_manager.js';
|
|
13
|
+
export { FlagsmithCache, FlagsmithConfig } from './types.js';
|
|
14
|
+
export declare class Flagsmith {
|
|
15
|
+
environmentKey?: string;
|
|
16
|
+
apiUrl?: string;
|
|
17
|
+
customHeaders?: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
};
|
|
20
|
+
agent?: Dispatcher;
|
|
21
|
+
requestTimeoutMs?: number;
|
|
22
|
+
enableLocalEvaluation?: boolean;
|
|
23
|
+
environmentRefreshIntervalSeconds: number;
|
|
24
|
+
retries?: number;
|
|
25
|
+
enableAnalytics: boolean;
|
|
26
|
+
defaultFlagHandler?: (featureName: string) => DefaultFlag;
|
|
27
|
+
environmentFlagsUrl?: string;
|
|
28
|
+
identitiesUrl?: string;
|
|
29
|
+
environmentUrl?: string;
|
|
30
|
+
environmentDataPollingManager?: EnvironmentDataPollingManager;
|
|
31
|
+
environment: EnvironmentModel;
|
|
32
|
+
offlineMode: boolean;
|
|
33
|
+
offlineHandler?: BaseOfflineHandler;
|
|
34
|
+
identitiesWithOverridesByIdentifier?: Map<string, IdentityModel>;
|
|
35
|
+
private cache?;
|
|
36
|
+
private onEnvironmentChange?;
|
|
37
|
+
private analyticsProcessor?;
|
|
38
|
+
private logger;
|
|
39
|
+
private customFetch;
|
|
40
|
+
/**
|
|
41
|
+
* A Flagsmith client.
|
|
42
|
+
*
|
|
43
|
+
* Provides an interface for interacting with the Flagsmith http API.
|
|
44
|
+
* Basic Usage::
|
|
45
|
+
*
|
|
46
|
+
* import flagsmith from Flagsmith
|
|
47
|
+
* const flagsmith = new Flagsmith({environmentKey: '<your API key>'});
|
|
48
|
+
* const environmentFlags = flagsmith.getEnvironmentFlags();
|
|
49
|
+
* const featureEnabled = environmentFlags.isFeatureEnabled('foo');
|
|
50
|
+
* const identityFlags = flagsmith.getIdentityFlags('identifier', {'foo': 'bar'});
|
|
51
|
+
* const featureEnabledForIdentity = identityFlags.isFeatureEnabled("foo")
|
|
52
|
+
*
|
|
53
|
+
* @param {string} data.environmentKey: The environment key obtained from Flagsmith interface
|
|
54
|
+
* Required unless offlineMode is True.
|
|
55
|
+
@param {string} data.apiUrl: Override the URL of the Flagsmith API to communicate with
|
|
56
|
+
@param data.customHeaders: Additional headers to add to requests made to the
|
|
57
|
+
Flagsmith API
|
|
58
|
+
@param {number} data.requestTimeoutSeconds: Number of seconds to wait for a request to
|
|
59
|
+
complete before terminating the request
|
|
60
|
+
@param {boolean} data.enableLocalEvaluation: Enables local evaluation of flags
|
|
61
|
+
@param {number} data.environmentRefreshIntervalSeconds: If using local evaluation,
|
|
62
|
+
specify the interval period between refreshes of local environment data
|
|
63
|
+
@param {number} data.retries: a urllib3.Retry object to use on all http requests to the
|
|
64
|
+
Flagsmith API
|
|
65
|
+
@param {boolean} data.enableAnalytics: if enabled, sends additional requests to the Flagsmith
|
|
66
|
+
API to power flag analytics charts
|
|
67
|
+
@param data.defaultFlagHandler: callable which will be used in the case where
|
|
68
|
+
flags cannot be retrieved from the API or a non-existent feature is
|
|
69
|
+
requested
|
|
70
|
+
@param data.logger: an instance of the pino Logger class to use for logging
|
|
71
|
+
@param {boolean} data.offlineMode: sets the client into offline mode. Relies on offlineHandler for
|
|
72
|
+
evaluating flags.
|
|
73
|
+
@param {BaseOfflineHandler} data.offlineHandler: provide a handler for offline logic. Used to get environment
|
|
74
|
+
document from another source when in offlineMode. Works in place of
|
|
75
|
+
defaultFlagHandler if offlineMode is not set and using remote evaluation.
|
|
76
|
+
*/
|
|
77
|
+
constructor(data?: FlagsmithConfig);
|
|
78
|
+
/**
|
|
79
|
+
* Get all the default for flags for the current environment.
|
|
80
|
+
*
|
|
81
|
+
* @returns Flags object holding all the flags for the current environment.
|
|
82
|
+
*/
|
|
83
|
+
getEnvironmentFlags(): Promise<Flags>;
|
|
84
|
+
/**
|
|
85
|
+
* Get all the flags for the current environment for a given identity. Will also
|
|
86
|
+
upsert all traits to the Flagsmith API for future evaluations. Providing a
|
|
87
|
+
trait with a value of None will remove the trait from the identity if it exists.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} identifier a unique identifier for the identity in the current
|
|
90
|
+
environment, e.g. email address, username, uuid
|
|
91
|
+
* @param {{[key:string]:any | ITraitConfig}} traits? a dictionary of traits to add / update on the identity in
|
|
92
|
+
Flagsmith, e.g. {"num_orders": 10} or {age: {value: 30, transient: true}}
|
|
93
|
+
* @returns Flags object holding all the flags for the given identity.
|
|
94
|
+
*/
|
|
95
|
+
getIdentityFlags(identifier: string, traits?: {
|
|
96
|
+
[key: string]: FlagsmithTraitValue | ITraitConfig;
|
|
97
|
+
}, transient?: boolean): Promise<Flags>;
|
|
98
|
+
/**
|
|
99
|
+
* Get the segments for the current environment for a given identity. Will also
|
|
100
|
+
upsert all traits to the Flagsmith API for future evaluations. Providing a
|
|
101
|
+
trait with a value of None will remove the trait from the identity if it exists.
|
|
102
|
+
*
|
|
103
|
+
* @param {string} identifier a unique identifier for the identity in the current
|
|
104
|
+
environment, e.g. email address, username, uuid
|
|
105
|
+
* @param {{[key:string]:any}} traits? a dictionary of traits to add / update on the identity in
|
|
106
|
+
Flagsmith, e.g. {"num_orders": 10}
|
|
107
|
+
* @returns Segments that the given identity belongs to.
|
|
108
|
+
*/
|
|
109
|
+
getIdentitySegments(identifier: string, traits?: {
|
|
110
|
+
[key: string]: any;
|
|
111
|
+
}): Promise<SegmentModel[]>;
|
|
112
|
+
/**
|
|
113
|
+
* Updates the environment state for local flag evaluation.
|
|
114
|
+
* Sets a local promise to prevent race conditions in getIdentityFlags / getIdentitySegments.
|
|
115
|
+
* You only need to call this if you wish to bypass environmentRefreshIntervalSeconds.
|
|
116
|
+
*/
|
|
117
|
+
updateEnvironment(): Promise<void>;
|
|
118
|
+
close(): Promise<void>;
|
|
119
|
+
private getJSONResponse;
|
|
120
|
+
/**
|
|
121
|
+
* This promise ensures that the environment is retrieved before attempting to locally evaluate.
|
|
122
|
+
*/
|
|
123
|
+
private environmentPromise;
|
|
124
|
+
private getEnvironmentFromApi;
|
|
125
|
+
private getEnvironmentFlagsFromDocument;
|
|
126
|
+
private getIdentityFlagsFromDocument;
|
|
127
|
+
private getEnvironmentFlagsFromApi;
|
|
128
|
+
private getIdentityFlagsFromApi;
|
|
129
|
+
private getIdentityModel;
|
|
130
|
+
}
|
|
131
|
+
export default Flagsmith;
|