diff --git a/types/rox-react-native/index.d.ts b/types/rox-react-native/index.d.ts index d44d7c5c00..d33761ea47 100644 --- a/types/rox-react-native/index.d.ts +++ b/types/rox-react-native/index.d.ts @@ -1,29 +1,25 @@ -// Type definitions for rox-react-native 4.5 +// Type definitions for rox-react-native 4.8 // Project: https://rollout.io // Definitions by: ahanriat +// g-guirado // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 3.0 /** - * DISCLAIMER: * - * Those type definition are based on the Javascript browser documentation - * as well as using and reversing the React-Native SDK + * Official documentation for rox-react-native is available here: + * https://support.rollout.io/docs/reactnative * - * Important note: Dedicated React-Native documentation as well as open source - * SDK are supposed to come. */ -export {}; - export interface RoxContainer { - [key: string]: Flag | Configuration | Variant; + [key: string]: Flag | Configuration | Variant; } /** * The register function should be called before the call to Rox.setup() * - * https://support.rollout.io/docs/javascript-browser-api#section-register + * https://support.rollout.io/docs/reactnative#section-register */ export function register(namespace: string, roxContainer: RoxContainer): void; @@ -31,7 +27,7 @@ export function register(namespace: string, roxContainer: RoxContainer): void; * Initiate connection with Rox servers for the application identified by the application key. * The registered containers will be synced and Rox entities will get the appropriate values. * - * https://support.rollout.io/docs/javascript-browser-api#section-setup + * https://support.rollout.io/docs/reactnative#section-setup */ export function setup( apiKey: string, @@ -40,25 +36,28 @@ export function setup( export interface RoxSetupOptions { version?: string; - // https://support.rollout.io/docs/javascript-browser-api#section-configurationfetchedhandler + // https://support.rollout.io/docs/reactnative#section-configurationfetchedhandler configurationFetchedHandler?(fetcherResult: RoxFetcherResult): void; debugLevel?: 'verbose'; - // https://support.rollout.io/docs/javascript-browser-api#section-using-the-impressionhandler-option - impressionHandler?( - reporting: RoxReporting, - experiment: RoxExperiment, - context: unknown - ): void; + // https://support.rollout.io/docs/reactnative#section-using-the-impressionhandler-option + impressionHandler?(reporting: RoxReporting, experiment: RoxExperiment, context: unknown): void; platform?: string; - freeze?: 'untilLaunch' | 'none'; + freeze?: FreezeOptions; + disableNetworkFetch?: boolean; + devModeSecret?: string; + // https://support.rollout.io/docs/reactnative#section--asyncstorage- + AsyncStorage?: any; // AsyncStorage from 'react-native' package +} + +export enum RoxFetcherStatus { + AppliedFromEmbedded = 'APPLIED_FROM_EMBEDDED', + AppliedFromCache = 'APPLIED_FROM_CACHE', + AppliedFromNetwork = 'APPLIED_FROM_NETWORK', + ErrorFetchFailed = 'ERROR_FETCH_FAILED', } export interface RoxFetcherResult { - fetcherStatus: - | 'APPLIED_FROM_EMBEDDED' - | 'APPLIED_FROM_CACHE' - | 'APPLIED_FROM_NETWORK' - | 'ERROR_FETCH_FAILED'; + fetcherStatus: RoxFetcherStatus; creationDate: Date; hasChanges: boolean; errorDetails?: string; @@ -92,48 +91,57 @@ export function setCustomBooleanProperty( name: string, value: boolean | (() => boolean) ): void; +export function setDynamicCustomPropertyRule( + handler: (propName: string, context: unknown) => number | string | boolean + ): void; /** * Unfreeze the state of all flags in code * Calling this function will unfreeze all flags, and using a flag will return it’s most updated value * * https://support.rollout.io/docs/flags-update-flow#section-flag-unfreeze - * https://support.rollout.io/docs/javascript-browser-api#section-unfreeze + * https://support.rollout.io/docs/reactnative#section--unfreeze- */ export function unfreeze(namespace?: string): void; /** * Pulls the latest configuration and flag values down from the Rollout servers * - * https://support.rollout.io/docs/javascript-browser-api#section-fetch + * https://support.rollout.io/docs/reactnative#section-fetch */ export function fetch(): Promise; /** * Default is untilForeground * - * https://support.rollout.io/docs/flags-update-flow#section-flag-freeze-level + * https://support.rollout.io/docs/reactnative#section--rox-freezeoptions- */ -export type RoxFlagFreezeLevel = 'none' | 'untilForeground' | 'untilLaunch'; +export enum FreezeOptions { + freezeOptionUntilLaunch = 1, + freezeOptionUntilForeground = 2, + freezeOptionNone = 3, +} + export interface RoxFlagOptions { - freeze?: RoxFlagFreezeLevel; + freeze?: FreezeOptions; } /** * Creates a new Flag - * https://support.rollout.io/docs/javascript-browser-api#section--rox-flag- + * https://support.rollout.io/docs/reactnative#section--rox-freezeoptions- */ export class Flag { - constructor(defaultValue: boolean, options?: RoxFlagOptions); + constructor(defaultValue?: boolean, options?: RoxFlagOptions); // The name of the Flag - name: string; + readonly name: string; + + // Default value of the Flag + readonly defaultValue: boolean; // Returns true when the flag is enabled isEnabled(): boolean; - getNameDetails(): RoxNameDetails; - // Unlock the Flag value from changes from the last time it was freezed unfreeze(): void; } @@ -141,47 +149,52 @@ export class Flag { /** * Used to create and manage Rollout feature flags that determine different predefined values * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-variant- + * https://support.rollout.io/docs/reactnative#section--rox-variant- */ export class Variant { constructor(defaultValue: T, options: T[], name?: string); // The name of the Flag - name: string; + readonly name: string; + + // Default value of the Variant + readonly defaultValue: BasicType; // Returns the current value of the Variant, accounting for value overrides - getValue(): T; - - getNameDetails(): RoxNameDetails; + getValue(): BasicType; // Unlock the Flag value from changes from the last time it was freezed unfreeze(): void; } -interface RoxNameDetails { - name: string; - namespace: string; -} - /** * manages a remote configuration setting with a value of type string, boolean, or number. * The constructor sets the default value for the remote configuration setting * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-configuration- + * https://support.rollout.io/docs/reactnative#section--rox-configuration- */ export class Configuration { constructor(defaultValue: T); // The name of the Configuration - name: string; + readonly name: string; + + // Default value of the Configuration + readonly defaultValue: BasicType; // Returns the current value of the Configuration, accounting for value overrides - getValue(): T; + getValue(): BasicType; // Unlock the Configuration value from changes from the last time it was freezed unfreeze(): void; } +/** + * Ensure that TypeScript properly types things with a basic type. + * For example, if T is true, returned type shall be boolean, not true + */ +export type BasicType = T extends boolean ? boolean : T extends number ? number : T extends string ? string : never; + /** * Override: Should only be used for development purposes (QA - Feature dev - e2e) * @@ -191,39 +204,53 @@ export class Configuration { * right after you call Rox.setup. To clear the override from the cache you need to * call the Rox.overrides.clearOverride method * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-overrides- + * https://support.rollout.io/docs/reactnative#section--rox-overrides- */ -export interface RoxOverrides { +export namespace overrides { /** * Sets an override value on a specific flag, this function accepts two parameters flag name ( * full flag name including namespace) and desired value (from type String). * This function also saves the override value on the local device disk, * so it is "remembered" for the next the SDK is loaded to production. * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-overrides-setoverride- + * https://support.rollout.io/docs/reactnative#section--rox-overrides-setoverride- * * Note that for boolean flag we still give the value as a string. */ - setOverride( - nameSpacedFlagName: string, - value: string | 'false' | 'true' - ): void; + function setOverride(nameSpacedFlagName: string, value: string | 'false' | 'true'): void; /** * Clears the override value from the flag (and the disk). * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-overrides-clearoverride- + * https://support.rollout.io/docs/reactnative#section--rox-overrides-clearoverride- */ - clearOverride(nameSpacedFlagName: string): void; + function clearOverride(nameSpacedFlagName: string): void; - getOriginalValue(nameSpacedFlagName: string): string; + function getOriginalValue(nameSpacedFlagName: string): string; /** * full flag name including namespace * - * https://support.rollout.io/docs/javascript-browser-api#section--rox-overrides-hasoverride- + * https://support.rollout.io/docs/reactnative#section--rox-overrides-hasoverride- */ - hasOverride(nameSpacedFlagName: string): boolean; + function hasOverride(nameSpacedFlagName: string): boolean; } -export const overrides: RoxOverrides; +/** + * Dynamic API is an alternative to Rollout static API for defining flags on the + * different container objects and accessing them from that container object. + * https://support.rollout.io/docs/dynamic-api + */ +export namespace dynamicApi { + /** + * Getting boolean value of a flag + */ + function isEnabled(nameSpacedFlagName: string, defaultValue: boolean, context?: unknown): boolean; + + /** + * Getting string value of a Variant flag + */ + function value(nameSpacedFlagName: string, defaultValue: string, context?: unknown): string; + } + +export const flags: ReadonlyArray; diff --git a/types/rox-react-native/rox-react-native-tests.ts b/types/rox-react-native/rox-react-native-tests.ts index 03dd29e362..a77993f110 100644 --- a/types/rox-react-native/rox-react-native-tests.ts +++ b/types/rox-react-native/rox-react-native-tests.ts @@ -1,7 +1,8 @@ import * as Rox from 'rox-react-native'; const flags = { - superFlag: new Rox.Flag(false) + superFlag: new Rox.Flag(false, { freeze: Rox.FreezeOptions.freezeOptionNone }), + superFlag2: new Rox.Flag(), }; const variants = { @@ -9,25 +10,57 @@ const variants = { }; const configurations = { - superConfiguration: new Rox.Configuration('☀️') + superConfiguration: new Rox.Configuration('☀️'), + superConfiguration2: new Rox.Configuration(true), }; // The register function should be called before the call to Rox.setup() Rox.register('default', { ...configurations, ...variants, ...flags }); Rox.setup('ROLLOUT_IO_KEY', { - impressionHandler + impressionHandler, + configurationFetchedHandler, }).then(linkTargetGroupAttributes); +Rox.dynamicApi.isEnabled('system.repotAnalytics', false); +Rox.dynamicApi.value('ui.textColor', 'red'); + +Rox.flags[0].defaultValue; +Rox.flags[0].name; + +flags.superFlag.isEnabled(); + +configurations.superConfiguration.defaultValue; +configurations.superConfiguration.name; +configurations.superConfiguration.getValue(); + +variants.superVariant.defaultValue; +variants.superVariant.name; +variants.superVariant.getValue(); + +Rox.unfreeze(); +flags.superFlag.unfreeze(); + function linkTargetGroupAttributes() { Rox.setCustomStringProperty('id', 'someId'); + Rox.setCustomStringProperty('id', () => 'someId'); + Rox.setCustomBooleanProperty('thisIsATest', true); + Rox.setCustomBooleanProperty('thisIsATest', () => true); + Rox.setCustomNumberProperty('aNumberProperty', 17); + Rox.setCustomNumberProperty('aNumberProperty', () => 17); + + Rox.setDynamicCustomPropertyRule((propName: string, _context: unknown) => { + return propName === 'myPropName'; + }); } -function impressionHandler( - reporting: Rox.RoxReporting, - experiment?: Rox.RoxExperiment -) { +function impressionHandler(_reporting: Rox.RoxReporting, _experiment?: Rox.RoxExperiment) { // If there is no experiment it means that the user has not been enrolled // or that the reporting is not used yet } + +function configurationFetchedHandler(fetcherResult: Rox.RoxFetcherResult) { + if (fetcherResult.hasChanges && fetcherResult.fetcherStatus === Rox.RoxFetcherStatus.AppliedFromCache) { + } +}