import { EvaluationContext, IdentityEvaluationContext, TraitEvaluationContext } from "./evaluation-context"; import { FlagSource } from "./flagsmith-core"; export type IFlagsmithValue = T export type DynatraceObject = { "javaLongOrObject": Record, "date": Record, "shortString": Record, "javaDouble": Record, } export interface IFlagsmithFeature { id?: number; enabled: boolean; value: Value; variant?: string; } export declare type IFlagsmithTrait = IFlagsmithValue | TraitEvaluationContext; export declare type IFlags = Record; export declare type ITraits = Record; export declare type Traits = Record; export interface ClientIdentityEvaluationContext extends Omit { traits?: null | ITraits; } export interface ClientEvaluationContext extends Omit { identity?: null | ClientIdentityEvaluationContext; } export declare type GetValueOptions | object> = { skipAnalytics?: boolean json?: boolean fallback?: T } export declare type HasFeatureOptions = { skipAnalytics?: boolean fallback?: boolean } | boolean export declare type IIdentity = T; export interface IRetrieveInfo { isFromServer: boolean; flagsChanged: string[] | null; traitsChanged: string[] | null; } export interface IState { api: string; flags?: IFlags>; evaluationContext?: EvaluationContext; evaluationEvent?: Record> | null; ts?: number; identity?: string; } declare type ICacheOptions = { ttl?: number; skipAPI?: boolean; storageKey?: string; loadStale?: boolean; }; export declare type IDatadogRum = { trackTraits: boolean client: { setUser: (newUser: { [x: string]: unknown }) => void; getUser: () => { [x: string]: unknown }; [extraProps: string]: any } } export type ISentryClient = { getIntegrationByName(name:"FeatureFlags"): { addFeatureFlag(flag: string, enabled: boolean): void; } | undefined; } | undefined; export { FlagSource }; export declare type LoadingState = { error: Error | null, // Current error, resets on next attempt to fetch flags isFetching: boolean, // Whether there is a current request to fetch server flags isLoading: boolean, // Whether any flag data exists source: FlagSource // Indicates freshness of flags } export type OnChange = (previousFlags: IFlags> | null, params: IRetrieveInfo, loadingState:LoadingState) => void export type ApplicationMetadata = { name: string; version?: string; } export interface IInitConfig = string, T extends string = string> { AsyncStorage?: any; api?: string; evaluationContext?: ClientEvaluationContext; cacheFlags?: boolean; cacheOptions?: ICacheOptions; datadogRum?: IDatadogRum; sentryClient?: ISentryClient; defaultFlags?: IFlags>; fetch?: any; realtime?: boolean; eventSourceUrl?: string; enableAnalytics?: boolean; enableDynatrace?: boolean; enableLogs?: boolean; angularHttpClient?: any; environmentID?: string; headers?: object; identity?: IIdentity; traits?: ITraits; onChange?: OnChange>; onError?: (err: Error) => void; preventFetch?: boolean; state?: IState; _trigger?: () => void; _triggerLoadingState?: () => void; /** * Customer application metadata */ applicationMetadata?: ApplicationMetadata; /** * @experimental Internal use only — API may change without notice. * Opt-in gate for the events pipeline. When true, an EventProcessor is * started and trackEvent / trackExposureEvent / getExperimentFlag become * available. * @internal */ enableEvents?: boolean; /** * @experimental Optional tuning for the events pipeline. Only valid when * enableEvents is true (passing it without enableEvents throws at init). * @internal */ eventProcessorConfig?: { eventsApiUrl?: string; maxBuffer?: number; flushInterval?: number; }; } export interface IFlagsmithResponse { identifier?: string, traits?: { trait_key: string; trait_value: IFlagsmithValue; transient?: boolean; }[]; flags?: { enabled: boolean; feature_state_value: IFlagsmithValue; variant?: string; feature: { id: number; name: string; }; }[]; } type FKey = F extends string ? F : keyof F; type FValue> = F extends Record ? F[K] | null : IFlagsmithValue; /** * Example usage: * * // A) Using string flags: * import flagsmith from 'flagsmith' as IFlagsmith<"featureOne"|"featureTwo">; * * // B) Using an object for F - this can be generated by our CLI: https://github.com/Flagsmith/flagsmith-cli : * interface MyFeatureInterface { * featureOne: string; * featureTwo: number; * } * import flagsmith from 'flagsmith' as IFlagsmith; */ export interface IFlagsmith< F extends string | Record = string, T extends string = string > { /** * Initialise the sdk against a particular environment */ init: (config: IInitConfig, T>) => Promise; /** * Set evaluation context. Refresh the flags. */ setContext: (context: ClientEvaluationContext) => Promise; /** * Merge current evaluation context with the provided one. Refresh the flags. */ updateContext: (context: ClientEvaluationContext) => Promise; /** /** * Get current context. */ getContext: () => EvaluationContext; /** * Trigger a manual fetch of the environment features */ getFlags: () => Promise; /** * Returns the current flags */ getAllFlags: () => IFlags>; /** * Identify user, triggers a call to get flags if `flagsmith.init` has been called * */ identify: (userId: string, traits?: Record) => Promise; /** * Retrieves the current state of flagsmith */ getState: () => IState; /** * Set the current state of flagsmith */ setState: (state: IState) => void; /** * Clears the identity, triggers a call to getFlags */ logout: () => Promise; /** * Polls the flagsmith API, specify interval in ms */ startListening: (interval?: number) => void; /** * Stops polling */ stopListening: () => void; /** * Returns whether a feature is enabled, or a fallback value if it does not exist. * @param {HasFeatureOptions} [optionsOrSkipAnalytics=false] If `true`, will not track analytics for this flag * evaluation. Using a boolean for this parameter is deprecated - use `{ skipAnalytics: true }` instead. * @param [optionsOrSkipAnalytics.fallback=false] Returns this value if the feature does not exist. * @param [optionsOrSkipAnalytics.skipAnalytics=false] If `true`, do not track analytics for this feature evaluation. * @example * flagsmith.hasFeature("power_user_feature") * @example * flagsmith.hasFeature("enabled_by_default_feature", { fallback: true }) */ hasFeature: (key: FKey, optionsOrSkipAnalytics?: HasFeatureOptions) => boolean; /** * Returns the value of a feature, or a fallback value. * @param [options.json=false] Deserialise the feature value using `JSON.parse` and return the result or `options.fallback`. * @param [options.fallback=null] Return this value in any of these cases: * * The feature does not exist. * * The feature has no value. * * `options.json` is `true` and the feature's value is not valid JSON. * @param [options.skipAnalytics=false] If `true`, do not track analytics for this feature evaluation. * @param [skipAnalytics=false] Deprecated - use `options.skipAnalytics` instead. * @example * flagsmith.getValue("remote_config") // "{\"hello\":\"world\"}" * flagsmith.getValue("remote_config", { json: true }) // { hello: "world" } * @example * flagsmith.getValue("font_size") // "12px" * flagsmith.getValue("font_size", { json: true, fallback: "8px" }) // "8px" */ getValue>( key: K, options?: GetValueOptions>, skipAnalytics?: boolean ): IFlagsmithValue>; /** * Get the value of a particular trait for the identified user */ getTrait: (key: T) => IFlagsmithValue; /** * Get the values of all traits for the identified user */ getAllTraits: () => Record; /** * Set a specific trait for a given user id, triggers a call to get flags * */ setTrait: (key: T, value: IFlagsmithTrait) => Promise; /** * Set a key value set of traits for a given user, triggers a call to get flags */ setTraits: (traits: ITraits) => Promise; /** * Record an arbitrary product event (e.g. "purchase"). No-op when events * are disabled (enableEvents is not set). identifier/traits default to the * current identified context when omitted. * @experimental @internal */ trackEvent: (event: string, opts?: { identifier?: string | null; value?: IFlagsmithValue; traits?: ITraits; metadata?: Record; }) => void; /** * Record that an identity was exposed to a flag/variant (emits the reserved * "$flag_exposure" event). No-op when events are disabled (enableEvents is * not set). Skipped (with a log) when no identifier resolves — identify() * first (optionally with transient: true) or pass opts.identifier. * @experimental @internal */ trackExposureEvent: (featureName: string, opts?: { identifier?: string | null; value?: IFlagsmithValue; traits?: ITraits; metadata?: Record; }) => void; /** * Resolve a flag for the currently identified user and fire one * "$flag_exposure" event with the selected variant as its value (skipped * unless flags were loaded from the server and the flag has a variant). * When events are disabled (enableEvents is not set) this degrades to a * plain flag read. * @experimental @internal */ getExperimentFlag: (featureName: string) => IFlagsmithFeature | null; /** * Force-flush any buffered events. Useful server-side/SSR where the timer * may not fire before the request ends. No-op when events are disabled. * @experimental @internal */ flushEvents: () => Promise; /** * Whether the events pipeline is enabled (enableEvents: true was passed * to init). Used by the React useExperiment hook to skip exposure * recording when events are off. * @experimental @internal */ readonly eventsEnabled: boolean; /** * The stored identity of the user */ identity?: IIdentity; /** * Whether the flagsmith SDK is initialised */ initialised?: boolean; /** * Returns ths current loading state */ loadingState?: LoadingState; /** * Used internally, this function will callback separately to onChange whenever flags are updated */ _trigger?: () => void; /** * Used internally, this function will trigger the useFlagsmithLoading hook when loading state changes */ _triggerLoadingState?: () => void; /** * Used internally, this is the cache options provided in flagsmith.init */ cacheOptions: { ttl: number; skipAPI: boolean; loadStale: boolean; }; /** * Used internally, this is the api provided in flagsmith.init, defaults to our production API */ api: string } export {};