flags
Version:
Flags SDK by Vercel - The feature flags toolkit for Next.js and SvelteKit
212 lines (205 loc) • 10.1 kB
TypeScript
import { J as JsonValue, f as FlagDeclaration, i as FlagOption, c as ApiData, e as FlagDefinitionType, P as ProviderData } from './types-CisDd6Kq.js';
import { IncomingMessage } from 'node:http';
import { NextRequest } from 'next/server';
import 'http';
import '@edge-runtime/cookies';
type NextApiRequestCookies = Partial<{
[key: string]: string;
}>;
/**
* Metadata on a feature flag function
*/
type FlagMeta<ValueType, EntitiesType> = {
/**
* The key of the feature flag
*/
key: FlagDeclaration<ValueType, EntitiesType>['key'];
/**
* An optional defaultValue which will be used when the flag's `decide` function returns undefined or throws an error. Catches async errors too.
*/
defaultValue?: FlagDeclaration<ValueType, EntitiesType>['defaultValue'];
/**
* A URL where this feature flag can be managed. Will show up in Vercel Toolbar.
*/
origin?: FlagDeclaration<ValueType, EntitiesType>['origin'];
/**
* A description of this feature flag. Will show up in Vercel Toolbar.
*/
description?: FlagDeclaration<ValueType, EntitiesType>['description'];
/**
* An array containing available options.
*
* * The returend value does not need to be declared in `options`, but it's recommended as all declared options show up in Vercel Toolbar.
*
* Value is required, but the label is optional.
* @example `[{ label: "Off", value: false }, { label: "On", value: true }]`
*
* Non-objects like strings can be passed using shorthands which will be used as values without labels.
* @example `["EUR", "USD"]`
*/
options?: FlagOption<ValueType>[];
/**
* This function is called when the feature flag is used (and no override is present) to return a value.
*/
decide: FlagDeclaration<ValueType, EntitiesType>['decide'];
/**
* This function can establish entities which the `decide` function will be called with.
*/
identify?: FlagDeclaration<ValueType, EntitiesType>['identify'];
/**
* Evaluates a feature flag with custom entities.
*
* Calling .run() bypasses the identify call and uses the provided entities directly.
*/
run: (options: {
identify: FlagDeclaration<ValueType, EntitiesType>['identify'] | EntitiesType;
request?: Parameters<PagesRouterFlag<ValueType, EntitiesType>>[0];
}) => Promise<ValueType>;
};
type AppRouterFlag<ValueType, EntitiesType> = {
(): Promise<ValueType>;
} & FlagMeta<ValueType, EntitiesType>;
type PagesRouterFlag<ValueType, EntitiesType> = {
(): never;
(request: IncomingMessage & {
cookies: NextApiRequestCookies;
}): Promise<ValueType>;
} & FlagMeta<ValueType, EntitiesType>;
type PrecomputedFlag<ValueType, EntitiesType> = {
(): never;
(groupCode: string, groupFlags: readonly Flag<any>[], secret?: string): Promise<ValueType>;
} & FlagMeta<ValueType, EntitiesType>;
type Flag<ValueType extends JsonValue, EntitiesType = any> = AppRouterFlag<ValueType, EntitiesType> | PagesRouterFlag<ValueType, EntitiesType> | PrecomputedFlag<ValueType, EntitiesType>;
type FlagsArray = readonly Flag<any, any>[];
type ValuesArray = readonly any[];
/**
* Resolves a list of flags
* @param flags - list of flags
* @returns - an array of evaluated flag values with one entry per flag
*/
declare function evaluate<T extends FlagsArray>(flags: T): Promise<{
[K in keyof T]: Awaited<ReturnType<T[K]>>;
}>;
/**
* Evaluate a list of feature flags and generate a signed string representing their values.
*
* This convenience function call combines `evaluate` and `serialize`.
*
* @param flags - list of flags
* @returns - a string representing evaluated flags
*/
declare function precompute<T extends FlagsArray>(flags: T): Promise<string>;
/**
* Combines flag declarations with values.
* @param flags - flag declarations
* @param values - flag values
* @returns - A record where the keys are flag keys and the values are flag values.
*/
declare function combine(flags: FlagsArray, values: ValuesArray): {
[k: string]: any;
};
/**
* Takes a list of feature flag declarations and their values and turns them into a short, signed string.
*
* The returned string is signed to avoid enumeration attacks.
*
* When a feature flag's `options` contains the value the flag resolved to, then the encoding will store it's index only, leading to better compression. Boolean values and null are compressed even when the options are not declared on the flag.
*
* @param flags - A list of feature flags
* @param values - A list of the values of the flags declared in ´flags`
* @param secret - The secret to use for signing the result
* @returns - A short string representing the values.
*/
declare function serialize(flags: FlagsArray, values: ValuesArray, secret?: string | undefined): Promise<string>;
/**
* Decodes all flags given the list of flags used to encode. Returns an object consisting of each flag's key and its resolved value.
* @param flags - Flags used when `code` was generated by `precompute` or `serialize`.
* @param code - The code returned from `serialize`
* @param secret - The secret to use for signing the result
* @returns - An object consisting of each flag's key and its resolved value.
*/
declare function deserialize(flags: FlagsArray, code: string, secret?: string | undefined): Promise<Record<string, any>>;
/**
* Decodes the value of one or multiple flags given the list of flags used to encode and the code.
*
* @param flag - Flag or list of flags to decode
* @param precomputeFlags - Flags used when `code` was generated by `serialize`
* @param code - The code returned from `serialize`
* @param secret - The secret to use for verifying the signature
*/
declare function getPrecomputed<T extends JsonValue>(flag: Flag<T, any>, precomputeFlags: FlagsArray, code: string, secret?: string): Promise<T>;
/**
* Decodes the value of one or multiple flags given the list of flags used to encode and the code.
*
* @param flag - Flag or list of flags to decode
* @param precomputeFlags - Flags used when `code` was generated by `serialize`
* @param code - The code returned from `serialize`
* @param secret - The secret to use for verifying the signature
*/
declare function getPrecomputed<T extends JsonValue, K extends readonly Flag<T, any>[]>(flags: readonly [...K], precomputeFlags: FlagsArray, code: string, secret?: string): Promise<{
[P in keyof K]: K[P] extends Flag<infer U, any> ? U : never;
}>;
/**
* Generates all permutations given a list of feature flags based on the options declared on each flag.
* @param flags - The list of feature flags
* @param filter - An optional filter function which gets called with each permutation.
* @param secret - The secret sign the generated permutation with
* @returns An array of strings representing each permutation
*/
declare function generatePermutations(flags: FlagsArray, filter?: ((permutation: Record<string, JsonValue>) => boolean) | null, secret?: string): Promise<string[]>;
/**
* A middleware-friendly version of React.cache.
*
* Given the same arguments, the function wrapped by this function will only ever run once for the duration of a request.
*
* React.cache should not be used in middleware as it would bring all of react
* into middleware, thus leading to an unnecessarily large middleware bundle.
*
* This function is a polyfill that will eventually land in Next.js itself,
* at which point it will be removed from `flags/next`.
*
* This function will turn any sync function async, since we rely on the
* headers() API to dedupe, which is async.
*/
declare function dedupe<A extends Array<unknown>, T>(fn: (...args: A) => T | Promise<T>): (...args: A) => Promise<T>;
/**
* Clears the cached value of a deduped function for the current request.
*
* This function is useful for resetting the cache after making changes to
* the underlying cached information.
*/
declare function clearDedupeCacheForCurrentRequest(dedupedFn: (...args: unknown[]) => unknown): Promise<boolean>;
/**
* Creates the Flags Discovery Endpoint for Next.js, which is a well-known endpoint used
* by Flags Explorer to discover the flags of your application.
*
* @param getApiData a function returning the API data
* @param options accepts a secret
* @returns a Next.js Route Handler
*/
declare function createFlagsDiscoveryEndpoint(getApiData: (request: NextRequest) => Promise<ApiData> | ApiData, options?: {
secret?: string | undefined;
}): (request: NextRequest) => Promise<Response>;
/**
* Declares a feature flag.
*
* This a feature flag function. When that function is called it will call the flag's `decide` function and return the result.
*
* If an override set by Vercel Toolbar, or more precisely if the `vercel-flag-overrides` cookie, is present then the `decide` function will not be called and the value of the override will be returned instead.
*
* In both cases this function also calls the `reportValue` function of `flags` so the evaluated flag shows up in Runtime Logs and is available for use with Web Analytics custom server-side events.
*
*
* @param definition - Information about the feature flag.
* @returns - A feature flag declaration
*/
declare function flag<ValueType extends JsonValue = boolean | string | number, EntitiesType = any>(definition: FlagDeclaration<ValueType, EntitiesType>): Flag<ValueType, EntitiesType>;
type KeyedFlagDefinitionType = {
key: string;
} & FlagDefinitionType;
/**
* Takes an object whose values are feature flag declarations and
* turns them into ProviderData to be returned through `/.well-known/vercel/flags`.
*/
declare function getProviderData(flags: Record<string, KeyedFlagDefinitionType | readonly unknown[]>): ProviderData;
export { type Flag, type KeyedFlagDefinitionType, clearDedupeCacheForCurrentRequest, combine, createFlagsDiscoveryEndpoint, dedupe, deserialize, evaluate, flag, generatePermutations, getPrecomputed, getProviderData, precompute, serialize };