UNPKG

@happykit/flags

Version:

Feature Flags for Next.js

228 lines (225 loc) 6.51 kB
import { CookieSerializeOptions } from 'cookie'; /** * A user to load the flags for. A user must at least have a `key`. See the * supported user attributes [here](#supported-user-attributes). * The user information you pass can be used for individual targeting or rules. */ declare type FlagUser = { key: string; email?: string; name?: string; avatar?: string; country?: string; }; /** * Traits * * An object which you have access to in the flag's rules. * You can target users based on traits. */ declare type Traits = { [key: string]: any; }; /** * Generic Feature Flags * * Entries consist of the feature flag name as the key and the resolved variant's value as the value. */ declare type Flags = { [key: string]: boolean | number | string | null; }; /** * The inputs to a flag evaluation. * * Given a flag has not changed, the same inputs will always lead to the same variants when evaluating a flag. */ declare type Input = { endpoint: string; envKey: string; requestBody: EvaluationRequestBody; }; declare type SuccessOutcome<F extends Flags> = { data: GenericEvaluationResponseBody<F>; error?: never; }; declare type ErrorOutcome = { data?: never; error: ResolvingError; }; /** * The result of a flag evaluation */ declare type Outcome<F extends Flags> = SuccessOutcome<F> | ErrorOutcome; /** * The fetch() request failed due to a network error (fetch itself threw). */ declare type NetworkError = "network-error"; /** * The response body could not be parsed into the expected JSON structure. */ declare type InvalidResponseBodyError = "invalid-response-body"; /** * The HTTP Status Code was not 200-299, so the response was not ok. */ declare type ResponseNotOkError = "response-not-ok"; /** * The request was aborted because it reached any of the loadingTimeouts. */ declare type RequestTimeoutError = "request-timed-out"; declare type ResolvingError = NetworkError | InvalidResponseBodyError | ResponseNotOkError | RequestTimeoutError; declare type EvaluationRequestBody = { visitorKey: string | null; user: FlagUser | null; traits: Traits | null; }; /** * The HappyKit API response to a feature flag evaluation request. */ declare type GenericEvaluationResponseBody<F extends Flags> = { visitor: { key: string; } | null; flags: F; }; declare type SuccessInitialFlagState<F extends Flags> = { input: Input; outcome: SuccessOutcome<F>; error?: never; }; declare type ErrorInitialFlagState = { input: Input; outcome: ErrorOutcome; }; /** * The initial flag state. * * In case you preloaded your flags during server-side rendering using `getFlags()`, provide the returned state as `initialState`. The client will then skip the first request whenever possible and use the provided flags instead. This allows you to get rid of loading states and on the client. */ declare type InitialFlagState<F extends Flags> = SuccessInitialFlagState<F> | ErrorInitialFlagState; declare type Revalidate = () => void; declare type EmptyFlagBag = { flags: null; data: null; error: null; fetching: false; settled: false; revalidate: Revalidate; visitorKey: null; }; declare type EvaluatingFlagBag<F extends Flags> = { flags: null | F; data: null; error: null; fetching: true; settled: false; revalidate: Revalidate; visitorKey: string; }; declare type SucceededFlagBag<F extends Flags> = { flags: F; data: GenericEvaluationResponseBody<F>; error: null; fetching: false; settled: boolean; revalidate: Revalidate; visitorKey: string; }; declare type RevalidatingAfterSuccessFlagBag<F extends Flags> = { flags: F; data: GenericEvaluationResponseBody<F>; error: null; fetching: true; settled: boolean; revalidate: Revalidate; visitorKey: string; }; declare type FailedFlagBag<F extends Flags> = { flags: F | null; data: null; error: ResolvingError; fetching: false; settled: boolean; revalidate: Revalidate; visitorKey: string; }; declare type RevalidatingAfterErrorFlagBag<F extends Flags> = { flags: F | null; data: null; error: ResolvingError; fetching: true; settled: false; revalidate: Revalidate; visitorKey: string; }; /** * A bag of feature flag related data. */ declare type FlagBag<F extends Flags = Flags> = EmptyFlagBag | EvaluatingFlagBag<F> | SucceededFlagBag<F> | RevalidatingAfterSuccessFlagBag<F> | FailedFlagBag<F> | RevalidatingAfterErrorFlagBag<F>; declare type GetFlagsSuccessBag<F extends Flags> = { /** * The resolved flags * * In case the default flags contain flags not present in the loaded flags, * the missing flags will get added to the returned flags. */ flags: F; /** * The actually loaded data without any defaults applied, or null when * the flags could not be loaded. */ data: GenericEvaluationResponseBody<F> | null; error: null; initialFlagState: SuccessInitialFlagState<F>; /** * The cookie options you should forward using * * Only used for edge, not for server. * * ``` * response.cookie( * flagBag.cookie.name, * flagBag.cookie.value, * flagBag.cookie.options * ); * ``` * * or using * * ``` * response.cookie(...flagBag.cookie.args) * ``` */ cookie?: { name: string; value: string; options: CookieSerializeOptions; /** * Arguments for response.cookie() */ args: [string, string, CookieSerializeOptions]; } | null; }; declare type GetFlagsErrorBag<F extends Flags> = { /** * The resolved flags * * In case the flags could not be loaded, you will see the default * flags here (from config.defaultFlags) */ flags: F | null; /** * The actually loaded data without any defaults applied, or null when * the flags could not be loaded. */ data: null; error: ResolvingError; /** * The initial flag state that you can use to initialize useFlags() */ initialFlagState: ErrorInitialFlagState; /** * Only used for edge, not for server. */ cookie?: null; }; export { Flags as F, GetFlagsSuccessBag as G, Input as I, Outcome as O, Traits as T, FlagUser as a, GetFlagsErrorBag as b, GenericEvaluationResponseBody as c, InitialFlagState as d, FlagBag as e };