-
Notifications
You must be signed in to change notification settings - Fork 2
/
Flags.ts
101 lines (89 loc) · 3.15 KB
/
Flags.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { FLAG_METADATA, NO_FLAG_METADATA } from '../enum/index.ts'
import { IFlagMetadata } from '../types.ts'
import { hasSameType, logDebugSprintf } from '../utils/utils.ts'
import { VisitorDelegate } from '../visitor/index.ts'
import { FlagMetadata } from './FlagMetadata.ts'
export type FlagValue<S> = {
defaultValue: S,
userExposed?: boolean
}
export interface IFlag<T>{
/**
* Return the current flag value if the flag key exists in Flagship and expose it if needed.
* @param visitorExposed Default True, if true it will report the flag exposure
*/
getValue(visitorExposed?:boolean):T
/**
* Return true if the flag exists, false otherwise.
*/
exists:()=>boolean
/**
* Tells Flagship the user have been exposed and have seen this flag
* @deprecated use **visitorExposed** instead
*/
userExposed:()=>Promise<void>
/**
* Tells Flagship the visitor have been exposed and have seen this flag
* @returns
*/
visitorExposed:()=>Promise<void>
/**
* Return The campaign metadata object.
*/
metadata:IFlagMetadata
}
export class Flag<T> implements IFlag<T> {
private _visitor:VisitorDelegate
private _key:string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private _defaultValue:any
constructor (param: {key:string, visitor:VisitorDelegate, defaultValue:T}) {
const { key, visitor, defaultValue } = param
this._key = key
this._visitor = visitor
this._defaultValue = defaultValue
}
exists ():boolean {
const flagDTO = this._visitor.flagsData.get(this._key)
return !!(flagDTO?.campaignId && flagDTO.variationId && flagDTO.variationGroupId)
}
get metadata ():IFlagMetadata {
const flagDTO = this._visitor.flagsData.get(this._key)
const metadata = new FlagMetadata({
campaignId: flagDTO?.campaignId || '',
campaignName: flagDTO?.campaignName || '',
variationGroupId: flagDTO?.variationGroupId || '',
variationGroupName: flagDTO?.variationGroupName || '',
variationId: flagDTO?.variationId || '',
variationName: flagDTO?.variationName || '',
isReference: !!flagDTO?.isReference,
campaignType: flagDTO?.campaignType || '',
slug: flagDTO?.slug
})
if (!flagDTO) {
logDebugSprintf(this._visitor.config, FLAG_METADATA, NO_FLAG_METADATA, this._visitor.visitorId, this._key, metadata)
return metadata
}
return this._visitor.getFlagMetadata({
metadata,
hasSameType: flagDTO.value === null || this._defaultValue === null || this._defaultValue === undefined || hasSameType(flagDTO.value, this._defaultValue),
key: flagDTO.key
})
}
userExposed ():Promise<void> {
return this.visitorExposed()
}
visitorExposed () : Promise<void> {
const flagDTO = this._visitor.flagsData.get(this._key)
return this._visitor.visitorExposed({ key: this._key, flag: flagDTO, defaultValue: this._defaultValue })
}
getValue (userExposed = true) : T {
const flagDTO = this._visitor.flagsData.get(this._key)
return this._visitor.getFlagValue({
key: this._key,
defaultValue: this._defaultValue,
flag: flagDTO,
userExposed
})
}
}