From 12123fc16b69a9db58188f552749d95606260c42 Mon Sep 17 00:00:00 2001 From: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Date: Fri, 7 Feb 2020 13:58:28 -0800 Subject: [PATCH 1/6] typescript type definitions (#34) * feat: Add typings for LDClient (#32) * typescript type definitions * typedoc * PR feedback * fix typos * setting default values to override platform inconsistencies --- .circleci/config.yml | 12 +- .gitignore | 5 + index.d.ts | 767 ++++++++++++++++++++++++++++++++ index.js | 20 +- package-lock.json | 1002 ++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- test-types.ts | 111 +++++ tsconfig.json | 13 + 8 files changed, 1931 insertions(+), 4 deletions(-) create mode 100644 index.d.ts create mode 100644 package-lock.json create mode 100644 test-types.ts create mode 100644 tsconfig.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 786bbaf..7a02255 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,9 +48,19 @@ jobs: - run: cp -r ../project/ ../hello-react-native/node_modules/launchdarkly-react-native-client-sdk/ - run: cd ../hello-react-native && react-native run-ios --configuration Release --simulator rn-ios + common: + docker: + - image: circleci/node:11.10.1 + steps: + - checkout + + - run: npm install + - run: npm run check-typescript + workflows: version: 2 android-ios: jobs: - android - - ios \ No newline at end of file + - ios + - common \ No newline at end of file diff --git a/.gitignore b/.gitignore index 67aea67..ef1d6ea 100644 --- a/.gitignore +++ b/.gitignore @@ -37,9 +37,14 @@ build/ .gradle local.properties *.iml +org.eclipse* +android/.project +android/.classpath # BUCK buck-out/ \.buckd/ *.keystore +# Auto-generated +test-types.js \ No newline at end of file diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..9095029 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,767 @@ +/** + * This is the API reference for the LaunchDarkly SDK for React Native. + * + * In typical usage, you will instantiate [[LDClient]] and then call [[configure]] once at startup time to + * set up your connection to LaunchDarkly. + * + * For more information, see the [SDK reference guide](http://docs.launchdarkly.com/docs/react-native-sdk-reference). + */ +declare module 'launchdarkly-react-native-client-sdk' { + + /** + * Configuration options for the LaunchDarkly React Native SDK. + */ + export type LDClientConfig = { + /** + * The mobile SDK key associated with your LaunchDarkly environment. + * + * This field is required as your the React Native SDK will use this value to unique + * identify your LaunchDarkly account. + */ + mobileKey: string; + + /** + * The base URI for the LaunchDarkly server. + * + * Most users should use the default value. + */ + baseUri?: string; + + /** + * The base URI for the LaunchDarkly streaming server. + * + * Most users should use the default value. + */ + streamUri?: string; + + /** + * The base URI for the LaunchDarkly events server. + * + * Most users should use the default value. + */ + eventsUri?: string; + + /** + * The capacity of the analytics events queue. + * + * The client buffers up to this many events in memory before flushing. If the capacity is exceeded + * before the queue is flushed, events will be discarded. Increasing the capacity means that events + * are less likely to be discarded, at the cost of consuming more memory. Note that in regular usage + * flag evaluations do not produce individual events, only summary counts, so you only need a large + * capacity if you are generating a large number of click, pageview, or identify events (or if you + * are using the event debugger). + * + * The default value is 100. + */ + eventsCapacity?: number; + + /** + * The interval in between flushes of the analytics events queue, in milliseconds. + * + * The default value is 30000ms (30 seconds). + */ + eventsFlushIntervalMillis?: number; + + /** + * The timeout interval for connecting to LaunchDarkly for flag requests and event reports. + * + * The default value is 10000ms (10 seconds). + */ + connectionTimeoutMillis?: number; + + /** + * The interval by which the SDK polls for flag updates when the application is in the foreground. This + * property is only used if is the streaming connection is disabled. + * + * The default value is 300000ms (5 min). + */ + pollingIntervalMillis?: number; + + /** + * The interval by which the SDK polls for flag updates when the application is in the background. + * + * The default value is 3600000ms (1 hour). + */ + backgroundPollingIntervalMillis?: number; + + /** + * Whether or not to use the REPORT verb to fetch flag settings. + * + * If this is true, flag settings will be fetched with a REPORT request + * including a JSON entity body with the user object. + * + * Otherwise (by default) a GET request will be issued with the user passed as + * a base64 URL-encoded path parameter. + * + * Do not use unless advised by LaunchDarkly. + */ + useReport?: boolean; + + /** + * Whether or not to open a streaming connection to LaunchDarkly for live flag updates. + * + * If this is true, the client will always attempt to maintain a streaming connection; if false, + * it never will. + * + * The default value is true. + */ + stream?: boolean; + + /** + * Whether or not the SDK should attempt to check for flag updates while the application + * runs in the background. + * + * If this is true, the client will periodically poll for updates while in the background; if + * false, the SDK will not attempt to receive updates while the app is backgrounded. + * + * The default value is false. + */ + disableBackgroundUpdating?: boolean; + + /** + * Disables all network calls from the LaunchDarkly SDK. + * + * This can also be specified after the client has been created, using LDClient.setOffline(). + * + * The default value is true (the client will make network calls). + */ + offline?: boolean; + + /** + * Controls information logged to the console, and modifying some setting ranges to facilitate debugging. + * + * This setting is only used when running in iOS. In Android this setting is ignored. + * + * The default value is false. + */ + debugMode?: boolean; + + /** + * Whether LaunchDarkly should provide additional information about how flag values were + * calculated. + * + * The additional information will then be available through the client's + * `LDClient.*VariationDetail` methods. Since this increases the size of network requests, + * such information is not sent unless you set this option to true. + */ + evaluationReasons?: boolean; + }; + + /** + * A LaunchDarkly user object. + */ + export type LDUserConfig = { + + /** + * A unique string identifying a user. + */ + key: string; + + /** + * The user's name. + * + * You can search for users on the User page by name. + */ + name?: string; + + /** + * The user's first name. + */ + firstName?: string; + + /** + * The user's last name. + */ + lastName?: string; + + /** + * The user's email address. + */ + email?: string; + + /** + * Whether to show the user on the Users page in LaunchDarkly. + * + * The default value is false. + */ + anonymous?: boolean; + + /** + * The country associated with the user. + */ + country?: string; + + /** + * Specifies a list of attribute names (either built-in or custom) which should be + * marked as private, and not sent to LaunchDarkly in analytics events. + */ + privateAttributeNames?: string[]; + + /** + * Any additional attributes associated with the user. + */ + custom?: { [key: string]: any }; + }; + + /** + * Describes the kind of error which occurred when a flag evaluation was calculated. + */ + export enum LDEvaluationReasonErrorKind { + /** + * The client is not able to establish a connection to LaunchDarkly yet. + * + * If there is a persistent feature store, the store does not yet contain flag data. + */ + CLIENT_NOT_READY = 'CLIENT_NOT_READY', + + /** + * The flag key did not match any known flag. + */ + FLAG_NOT_FOUND = 'FLAG_NOT_FOUND', + + /** + * The user object or user key was not provided. + */ + USER_NOT_SPECIFIED = 'USER_NOT_SPECIFIED', + + /** + * There was an internal inconsistency in the flag data. For example, a rule specified a nonexistent variation. + * + * This is an unusual condition that might require assistance from LaunchDarkly's Support team. + */ + MALFORMED_FLAG = 'MALFORMED_FLAG', + + /** + * The application code requested the flag value with a different data type than it actually is. + * + * For example, the code asked for a boolean when the flag type is actually a string. + */ + WRONG_TYPE = 'WRONG_TYPE', + + /** + * An unexpected error stopped flag evaluation. This could happen if you are using a persistent feature store and the database stops working. + * + * When this happens, the SDK always prints the specific error to the log. + */ + EXCEPTION = 'EXCEPTION', + } + + /** + * Describes the reason behind how a flag evaluation was calculated. + */ + export enum LDEvaluationReasonKind { + /** + * The flag is off and therefore returned its configured off value. + * + * This value appears on the dashboard next to "If targeting is off, serve:". + */ + OFF = 'OFF', + + /** + * The flag is on, but the user did not match any targets or rules, so it returned the value that appears on the dashboard under "Default rule." + */ + FALLTHROUGH = 'FALLTHROUGH', + + /** + * The user key was specifically targeted for this flag in the "Target individual users" section. + */ + TARGET_MATCH = 'TARGET_MATCH', + + /** + * The user who encountered the flag matched one of the flag's rules. + */ + RULE_MATCH = 'RULE_MATCH', + + /** + * The flag had at least one prerequisite flag that either was off or did not return the desired variation. + * + * Because of this, the flag returned its "off" value. + */ + PREREQUISITE_FAILED = 'PREREQUISITE_FAILED', + + /** + * The flag could not be evaluated, so the default value was returned + */ + ERROR = 'ERROR', + } + + /** + * The flag is off and therefore returned its configured off value. + */ + export type LDEvaluationReasonOff = { + kind: LDEvaluationReasonKind.OFF; + }; + + /** + * The flag is on, but the user did not match any targets or rules, so it returned the value that appears + * on the dashboard under "Default rule." + */ + export type LDEvaluationReasonFallthrough = { + kind: LDEvaluationReasonKind.FALLTHROUGH; + }; + + /** + * The user key was specifically targeted for this flag in the "Target individual users" section. + */ + export type LDEvaluationReasonTargetMatch = { + kind: LDEvaluationReasonKind.TARGET_MATCH; + }; + + /** + * The user who encountered the flag matched one of the flag's rules. + */ + export type LDEvaluationReasonRuleMatch = { + kind: LDEvaluationReasonKind.RULE_MATCH; + + /** + * The positional index of the matched rule (0 for the first rule). + */ + ruleIndex: number; + + /** + * The rule's unique identifier, which stays the same even if you rearrange the order of the rules. + */ + ruleId: string; + }; + + /** + * The flag had at least one prerequisite flag that either was off or did not return the desired variation. + * Because of this, the flag returned its "off" value. + */ + export type LDEvaluationReasonPrerequisiteFailed = { + kind: LDEvaluationReasonKind.PREREQUISITE_FAILED; + + /** + * The key of the prerequisite flag that failed. + */ + prerequisiteKey: string; + }; + + /** + * The flag could not be evaluated, so the default value was returned. + */ + export type LDEvaluationReasonError = { + kind: LDEvaluationReasonKind.ERROR; + + /** + * The kind of error which occurred. + */ + errorKind: LDEvaluationReasonErrorKind; + }; + + /** + * Describes the reason that a flag evaluation produced a particular value. This is + * part of the [[LDEvaluationDetail]] object returned by the variation detail methods. + */ + export type LDEvaluationReason = + | LDEvaluationReasonOff + | LDEvaluationReasonFallthrough + | LDEvaluationReasonTargetMatch + | LDEvaluationReasonRuleMatch + | LDEvaluationReasonPrerequisiteFailed + | LDEvaluationReasonError; + + /** + * An object that combines the result of a feature flag evaluation with information about + * how it was calculated. + * + * This is the result of calling one of the `LDClient.*VariationDetail` methods. + * + * For more information, see the [documentation](https://docs.launchdarkly.com/docs/evaluation-reasons). + */ + export type LDEvaluationDetail = { + /** + * The result of the flag evaluation. This will be either one of the flag's variations or + * the default value that was passed to the variation detail function. + */ + value: T; + + /** + * The index of the returned value within the flag's list of variations, e.g. 0 for the + * first variation-- or `null` if the default value was returned. + */ + variationIndex?: number; + + /** + * An object describing the main factor that influenced the flag evaluation value. + */ + reason: LDEvaluationReason; + }; + + /** + * A map of feature flags from their keys to their values. + */ + export interface LDFlagSet { + [key: string]: any; + } + + /** + * The LaunchDarkly SDK client object. + * + * Applications should configure the client at application startup time and reuse the same instance. + * + * For more information, see the [SDK Reference Guide](https://docs.launchdarkly.com/docs/react-native-sdk-reference). + */ + export class LDClient { + constructor(); + + /** + * Initialize the SDK to work with the specified client configuration options and on behalf of the specified user. + * + * This should only be called once at application start time. + * + * @param config + * the client configuration options + * @param userConfig + * the user + */ + configure(config: LDClientConfig, userConfig: LDUserConfig): Promise; + + /** + * Determines the variation of a boolean feature flag for the current user. + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing the flag's value. + */ + boolVariation(flagKey: string, fallback: boolean): Promise; + + /** + * Determines the variation of an integer feature flag for the current user. + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing the flag's value. + */ + intVariation(flagKey: string, fallback: number): Promise; + + /** + * Determines the variation of a floating-point feature flag for the current user. + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing the flag's value. + */ + floatVariation(flagKey: string, fallback: number): Promise; + + /** + * Determines the variation of a string feature flag for the current user. + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing the flag's value. + */ + stringVariation(flagKey: string, fallback: string): Promise; + + /** + * Determines the variation of a JSON feature flag for the current user. + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing the flag's value. + */ + jsonVariation( + flagKey: string, + fallback: Record, + ): Promise>; + + /** + * Determines the variation of a boolean feature flag for a user, along with information about how it was + * calculated. + * + * Note that this will only work if you have set `evaluationReasons` to true in [[LDClientConfig]]. + * Otherwise, the `reason` property of the result will be null. + * + * For more information, see the [SDK reference guide](https://docs.launchdarkly.com/docs/evaluation-reasons). + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing an [[LDEvaluationDetail]] object containing the value and explanation. + */ + boolVariationDetail( + flagKey: string, + fallback: boolean, + ): Promise | boolean>; + + /** + * Determines the variation of an integer feature flag for a user, along with information about how it was + * calculated. + * + * Note that this will only work if you have set `evaluationReasons` to true in [[LDClientConfig]]. + * Otherwise, the `reason` property of the result will be null. + * + * For more information, see the [SDK reference guide](https://docs.launchdarkly.com/docs/evaluation-reasons). + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing an [[LDEvaluationDetail]] object containing the value and explanation. + */ + intVariationDetail( + flagKey: string, + fallback: number, + ): Promise | number>; + + /** + * Determines the variation of a floating-point feature flag for a user, along with information about how it was + * calculated. + * + * Note that this will only work if you have set `evaluationReasons` to true in [[LDClientConfig]]. + * Otherwise, the `reason` property of the result will be null. + * + * For more information, see the [SDK reference guide](https://docs.launchdarkly.com/docs/evaluation-reasons). + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing an [[LDEvaluationDetail]] object containing the value and explanation. + */ + floatVariationDetail( + flagKey: string, + fallback: number, + ): Promise | number>; + + /** + * Determines the variation of a string feature flag for a user, along with information about how it was + * calculated. + * + * Note that this will only work if you have set `evaluationReasons` to true in [[LDClientConfig]]. + * Otherwise, the `reason` property of the result will be null. + * + * For more information, see the [SDK reference guide](https://docs.launchdarkly.com/docs/evaluation-reasons). + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing an [[LDEvaluationDetail]] object containing the value and explanation. + */ + stringVariationDetail( + flagKey: string, + fallback: string, + ): Promise | string>; + + /** + * Determines the variation of a JSON feature flag for a user, along with information about how it was + * calculated. + * + * Note that this will only work if you have set `evaluationReasons` to true in [[LDClientConfig]]. + * Otherwise, the `reason` property of the result will be null. + * + * For more information, see the [SDK reference guide](https://docs.launchdarkly.com/docs/evaluation-reasons). + * + * @param flagKey + * The unique key of the feature flag. + * @param fallback + * The default value of the flag, to be used if the value is not available from LaunchDarkly. + * @returns + * A promise containing an [[LDEvaluationDetail]] object containing the value and explanation. + */ + jsonVariationDetail( + flagKey: string, + fallback: Record, + ): Promise> | Record>; + + /** + * Returns a map of all available flags to the current user's values. + * + * @returns + * A promise containing an object in which each key is a feature flag key and each value is the flag value. + * Note that there is no way to specify a default value for each flag as there is with the + * `*Variation` methods, so any flag that cannot be evaluated will have a null value. + */ + allFlags(): Promise; + + /** + * Track events to use in goals or A/B tests. + * + * @param eventName + * The name of the event, which may correspond to a goal in A/B tests. + * @param data + * Optional additional information to associate with the event. + * @param metricValue + * Optional numeric value to attach to the tracked event + */ + track(eventName: string, data?: any, metricValue?: number): void; + + /** + * Checks whether the client has been put into offline mode. This is true only if [[setOffline]] + * was called, or if the configuration had [[LDClientConfig.offline]] set to true, + * not if the client is simply offline due to a loss of network connectivity. + * + * @returns + * A promise containing true if the client is in offline mode + */ + isOffline(): Promise; + + /** + * Shuts down any network connections maintained by the client and puts the client in offline + * mode, preventing the client from opening new network connections until [[setOnline]] is called. + * + * Note: The client automatically monitors the device's network connectivity and app foreground + * status, so calling [[setOffline]] or [[setOnline]] is normally unnecessary in most situations. + * + * @returns + * A promise containing true if the change was made successfully + */ + setOffline(): Promise; + + /** + * Restores network connectivity for the client, if the client was previously in offline mode. + * This operation may be throttled if it is called too frequently. + * + * Note: The client automatically monitors the device's network connectivity and app foreground + * status, so calling [[setOffline]] or [[setOnline]] is normally unnecessary in most situations. + * + * @returns + * A promise containing true if the change was made successfully + */ + setOnline(): Promise; + + /** + * Checks whether the client is ready to return feature flag values. This is true if either + * the client has successfully connected to LaunchDarkly and received feature flags, or the + * client has been put into offline mode (in which case it will return only default flag values). + * + * This function only works when running in Android. On iOS, this function will return a rejected promise. + * + * @returns + * A promise contianing true if the client is initialized or offline + */ + isInitialized(): Promise; + + /** + * Checks whether the `disableBackgroundUpdating` property of [[LDClientConfig]] was set to true. + * + * @returns + * A promise containing true if background polling is disabled + */ + isDisableBackgroundPolling(): Promise; + + /** + * Flushes all pending analytics events. + * + * Normally, batches of events are delivered in the background at intervals determined by the + * `eventsFlushIntervalMillis` property of [[LDClientConfig]]. Calling `flush` triggers an + * immediate delivery. + */ + flush(): void; + + /** + * Shuts down the client and releases its resources, after delivering any pending analytics + * events. After the client is closed, all calls to the `*Variation` methods will return default values, + * and it will not make any requests to LaunchDarkly. + */ + close(): Promise; + + /** + * Sets the current user, retrieves flags for that user, then sends an Identify Event to LaunchDarkly. + * + * @param userConfig + * The user for evaluation and event reporting + * @returns + * A promise indicating when this operation is complete (meaning that flags are ready for evaluation). + */ + identify(userConfig: LDUserConfig): Promise; + + /** + * Registers a callback to be called when the flag with key `flagKey` changes from its current value. + * + * @param flagKey + * The flag key to attach the callback to + * @param callback + * The callback to attach to the flag key + */ + registerFeatureFlagListener( + flagKey: string, + callback: (flagKey: string) => void, + ): void; + + /** + * Unregisters a callback for the flag with key `flagKey`. + * + * @param flagKey + * The flag key to remove the callback from + * @param callback + * The callback to remove from the flag key + */ + unregisterFeatureFlagListener( + flagKey: string, + callback: (flagKey: string) => void, + ): void; + + /** + * Gets an object from the client representing the current state of the client's connection. + * + * @returns + * A promise containing an object representing the status of the connection to LaunchDarkly. + */ + getConnectionInformation(): Promise; + + /** + * Registers a callback to be called on connection status updates. + * + * @param listenerId + * The listener to be called on a connection status update + * @param callback + * The callback to attach to the connection status update + */ + registerCurrentConnectionModeListener( + listenerId: string, + callback: (connectionMode: string) => void, + ): void; + + /** + * Unregisters a callback so that it will no longer be called on connection status updates. + * + * @param listenerId + * The listener to remoce the callback from + */ + unregisterCurrentConnectionModeListener(listenerId: string): void; + + /** + * Registers a callback to be called when a flag update is processed by the SDK. + * + * @param listenerId + * The listener to be called when a flag update is processed + * @param callback + * The callback to attach to the flag update + */ + registerAllFlagsListener( + listenerId: string, + callback: (updatedFlags: string[]) => void, + ): void; + + /** + * Unregisters a callback so it will no longer be called on flag updates. + * + * @param listenerId + * The listener to be removed + */ + unregisterAllFlagsListener(listenerId: string): void; + } + } + \ No newline at end of file diff --git a/index.js b/index.js index 5742671..1c8fd54 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,17 @@ export default class LDClient { } configure(config, userConfig) { - return LaunchdarklyReactNativeClient.configure(config, userConfig); + const configWithOverriddenDefaults = Object.assign({ + backgroundPollingIntervalMillis: 3600000, // the iOS SDK defaults this to 900000 + disableBackgroundUpdating: false // the iOS SDK defaults this to true + }, config); + + // The Android SDK expects the events URI to be in the form of "/mobile" whereas iOS only expects "". + if (configWithOverriddenDefaults.eventsUri && Platform.OS === 'android') { + configWithOverriddenDefaults.eventsUri = configWithOverriddenDefaults.eventsUri + '/mobile'; + } + + return LaunchdarklyReactNativeClient.configure(configWithOverriddenDefaults, _addUserOverrides(userConfig)); } boolVariation(flagKey, fallback) { @@ -182,7 +192,13 @@ export default class LDClient { } identify(userConfig) { - return LaunchdarklyReactNativeClient.identify(userConfig); + return LaunchdarklyReactNativeClient.identify(_addUserOverrides(userConfig)); + } + + _addUserOverrides(userConfig) { + return Object.assign({ + anonymous: false // the iOS SDK defaults this to true + }, userConfig); } isDisableBackgroundPolling() { diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cc247bd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1002 @@ +{ + "name": "launchdarkly-react-native-client-sdk", + "version": "2.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", + "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", + "dev": true, + "requires": { + "@babel/types": "^7.7.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz", + "integrity": "sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz", + "integrity": "sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.0.tgz", + "integrity": "sha512-LSln3cexwInTMYYoFeVLKnYPPMfWNJ8PubTBs3hkh7wCu9iBaqq1OOyW+xGmEdLxT1nhsl+9SJ+h2oUDYz0l2A==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz", + "integrity": "sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz", + "integrity": "sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-member-expression-to-functions": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz", + "integrity": "sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ==", + "dev": true, + "requires": { + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.6.0" + } + }, + "@babel/helper-define-map": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz", + "integrity": "sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.7.0", + "@babel/types": "^7.7.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz", + "integrity": "sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-function-name": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", + "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", + "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz", + "integrity": "sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz", + "integrity": "sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz", + "integrity": "sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz", + "integrity": "sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.7.0", + "@babel/helper-simple-access": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz", + "integrity": "sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz", + "integrity": "sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz", + "integrity": "sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g==", + "dev": true, + "requires": { + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", + "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", + "dev": true, + "requires": { + "@babel/types": "^7.7.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", + "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz", + "integrity": "sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz", + "integrity": "sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.2.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz", + "integrity": "sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", + "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz", + "integrity": "sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.2.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz", + "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.0.tgz", + "integrity": "sha512-vQMV07p+L+jZeUnvX3pEJ9EiXGCjB5CTTvsirFD9rpEuATnoAvLBLoYbw1v5tyn3d2XxSuvEKi8cV3KqYUa0vQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz", + "integrity": "sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz", + "integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", + "integrity": "sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", + "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz", + "integrity": "sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.0", + "@babel/helper-define-map": "^7.7.0", + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", + "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz", + "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz", + "integrity": "sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz", + "integrity": "sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.7.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-object-assign": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz", + "integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", + "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.0.tgz", + "integrity": "sha512-mXhBtyVB1Ujfy+0L6934jeJcSXj/VCg6whZzEcgiiZHNS0PGC7vUCsZDQCxxztkpIdF+dY1fUMcjAgEOC3ZOMQ==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", + "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz", + "integrity": "sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz", + "integrity": "sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", + "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.2.tgz", + "integrity": "sha512-UWhDaJRqdPUtdK1s0sKYdoRuqK0NepjZto2UZltvuCgMoMZmdjhgz5hcRokie/3aYEaSz3xvusyoayVaq4PjRg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-typescript": "^7.2.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz", + "integrity": "sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/template": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", + "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/types": "^7.7.0" + } + }, + "@babel/traverse": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", + "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.2", + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", + "@babel/parser": "^7.7.2", + "@babel/types": "^7.7.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", + "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "metro-react-native-babel-preset": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.0.tgz", + "integrity": "sha512-MAo1fm0dNn6MVZmylaz6k2HC1MINHLTLfE7O3a9Xz3fAtbGbApisp06rBUfK5uUqIJDmAaKgbiT34lHJSIiE6Q==", + "dev": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "react-refresh": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.2.tgz", + "integrity": "sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "typescript": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", + "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + } + } +} diff --git a/package.json b/package.json index ecceb62..03dc39b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "2.2.0", "description": "", "main": "index.js", + "types": "index.d.ts", "scripts": { + "check-typescript": "node_modules/typescript/bin/tsc", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -24,6 +26,7 @@ "react": "16.9.0" }, "devDependencies": { - "metro-react-native-babel-preset": "0.56.0" + "metro-react-native-babel-preset": "0.56.0", + "typescript": "3.0.1" } } diff --git a/test-types.ts b/test-types.ts new file mode 100644 index 0000000..1a91249 --- /dev/null +++ b/test-types.ts @@ -0,0 +1,111 @@ + +// This file exists only so that we can run the TypeScript compiler in the CI build +// to validate our index.d.ts file. The code will not actually be run. + +import { + LDClient, + LDClientConfig, + LDEvaluationDetail, + LDEvaluationReason, + LDFlagSet, + LDUserConfig, +} from 'launchdarkly-react-native-client-sdk'; + +async function tests() { + const jsonObj: Record = { + 'a': 's', + 'b': true, + 'c': 3, + 'd': [ 'x', 'y' ], + 'e': [ true, false ], + 'f': [ 1, 2 ] + }; + + const configWithKeyOnly: LDClientConfig = { + mobileKey: '' + }; + const configWithAllOptions: LDClientConfig = { + mobileKey: '', + baseUri: '', + streamUri: '', + eventsUri: '', + eventsCapacity: 1, + eventsFlushIntervalMillis: 1, + connectionTimeoutMillis: 1, + pollingIntervalMillis: 1, + backgroundPollingIntervalMillis: 1, + useReport: true, + stream: true, + disableBackgroundUpdating: true, + offline: true, + debugMode: true, + evaluationReasons: true, + }; + const userWithKeyOnly: LDUserConfig = { key: 'user' }; + const user: LDUserConfig = { + key: 'user', + name: 'name', + firstName: 'first', + lastName: 'last', + email: 'test@example.com', + anonymous: true, + country: 'us', + privateAttributeNames: [ 'name', 'email' ], + custom: jsonObj, + }; + const client: LDClient = new LDClient(); + + const configure: null = await client.configure(configWithAllOptions, user); + const identify: null = await client.identify(user); + + const boolFlagValue: boolean = await client.boolVariation('key', false); + const intFlagValue: number = await client.intVariation('key', 2); + const floatFlagValue: number = await client.floatVariation('key', 2.3); + const stringFlagValue: string = await client.stringVariation('key', 'default'); + const jsonFlagValue: Record = await client.jsonVariation('key', jsonObj); + + const boolDetail: LDEvaluationDetail | boolean = await client.boolVariationDetail('key', false); + const intDetail: LDEvaluationDetail | number = await client.intVariationDetail('key', 2); + const floatDetail: LDEvaluationDetail | number = await client.floatVariationDetail('key', 2.3); + const stringDetail: LDEvaluationDetail | string = await client.stringVariationDetail('key', 'default'); + const jsonDetail: LDEvaluationDetail> | Record = await client.jsonVariationDetail('key', jsonObj); + + const detailCasted = boolDetail as LDEvaluationDetail; + const detailValue: boolean = detailCasted.value; + const detailIndex: number | undefined = detailCasted.variationIndex; + const detailReason: LDEvaluationReason = detailCasted.reason; + + const flagSet: LDFlagSet = await client.allFlags(); + const flagSetValue: any = flagSet['key']; + + const track1: void = await client.track('eventname'); + const track2: void = await client.track('eventname', undefined); + const track3: void = await client.track('eventname', true); + const track4: void = await client.track('eventname', 2); + const track5: void = await client.track('eventname', 2.3); + const track6: void = await client.track('eventname', 'something'); + const track7: void = await client.track('eventname', [2, 3]); + const track8: void = await client.track('eventname', { foo: 2}); + const track9: void = await client.track('eventname', { foo: 2}, 4); + + const setOffline: boolean = await client.setOffline(); + const setOnline: boolean = await client.setOnline(); + const isOffline: boolean = await client.isOffline(); + const isInitialized: boolean = await client.isInitialized(); + const isDisableBackgroundPolling: boolean = await client.isDisableBackgroundPolling(); + + const callback = function(_: string): void { }; + const registerFeatureFlagListener: void = client.registerFeatureFlagListener('key', callback); + const unregisterFeatureFlagListener: void = client.unregisterFeatureFlagListener('key', callback); + const registerAllFlagsListener: void = client.registerAllFlagsListener('id', flags => flags); + const unregisterAllFlagsListener: void = client.unregisterAllFlagsListener('id'); + const registerCurrentConnectionModeListener: void = client.registerCurrentConnectionModeListener('id', callback); + const unregisterCurrentConnectionModeListener: void = client.unregisterCurrentConnectionModeListener('id'); + + const getConnectionInformation: any = await client.getConnectionInformation(); + + const flush: void = await client.flush(); + const close: void = await client.close(); +}; + +tests(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..acdd57b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "commonjs", + "strict": true, + "lib": [ + "es6" + ] + }, + "files": [ + "index.d.ts", + "test-types.ts" + ] + } \ No newline at end of file From 5a45e604928a4feec5d2cdddfa699b3798604071 Mon Sep 17 00:00:00 2001 From: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Date: Fri, 7 Feb 2020 14:08:45 -0800 Subject: [PATCH 2/6] fix evaluation reasons when exceptional behavior occurs (#35) --- .../LaunchdarklyReactNativeClientModule.java | 57 +++++++++++-------- index.d.ts | 12 ++-- test-types.ts | 21 ++++--- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java b/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java index 7a5dbc3..d23b5fb 100644 --- a/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java +++ b/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java @@ -34,6 +34,7 @@ import com.launchdarkly.android.LDStatusListener; import com.launchdarkly.android.LDAllFlagsListener; import com.launchdarkly.android.EvaluationDetail; +import com.launchdarkly.android.EvaluationReason; import com.launchdarkly.android.LDFailure; import java.lang.reflect.InvocationTargetException; @@ -565,14 +566,16 @@ public void boolVariationDetail(String flagKey, Promise promise) { @ReactMethod public void boolVariationDetailFallback(String flagKey, Boolean fallback, Promise promise) { + EvaluationDetail detailResult; try { - EvaluationDetail detailResult = ldClient.boolVariationDetail(flagKey, fallback); - JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); - WritableMap detailMap = fromJsonObject(jsonObject); - promise.resolve(detailMap); + detailResult = ldClient.boolVariationDetail(flagKey, fallback); } catch (Exception e) { - promise.resolve(fallback); + e.printStackTrace(); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); } + JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); + WritableMap detailMap = fromJsonObject(jsonObject); + promise.resolve(detailMap); } @ReactMethod @@ -582,14 +585,16 @@ public void intVariationDetail(String flagKey, Promise promise) { @ReactMethod public void intVariationDetailFallback(String flagKey, Integer fallback, Promise promise) { + EvaluationDetail detailResult; try { - EvaluationDetail detailResult = ldClient.intVariationDetail(flagKey, fallback); - JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); - WritableMap detailMap = fromJsonObject(jsonObject); - promise.resolve(detailMap); + detailResult = ldClient.intVariationDetail(flagKey, fallback); } catch (Exception e) { - promise.resolve(fallback); + e.printStackTrace(); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); } + JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); + WritableMap detailMap = fromJsonObject(jsonObject); + promise.resolve(detailMap); } @ReactMethod @@ -599,14 +604,16 @@ public void floatVariationDetail(String flagKey, Promise promise) { @ReactMethod public void floatVariationDetailFallback(String flagKey, Float fallback, Promise promise) { + EvaluationDetail detailResult; try { - EvaluationDetail detailResult = ldClient.floatVariationDetail(flagKey, fallback); - JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); - WritableMap detailMap = fromJsonObject(jsonObject); - promise.resolve(detailMap); + detailResult = ldClient.floatVariationDetail(flagKey, fallback); } catch (Exception e) { - promise.resolve(fallback); + e.printStackTrace(); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); } + JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); + WritableMap detailMap = fromJsonObject(jsonObject); + promise.resolve(detailMap); } @ReactMethod @@ -616,14 +623,16 @@ public void stringVariationDetail(String flagKey, Promise promise) { @ReactMethod public void stringVariationDetailFallback(String flagKey, String fallback, Promise promise) { + EvaluationDetail detailResult; try { - EvaluationDetail detailResult = ldClient.stringVariationDetail(flagKey, fallback); - JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); - WritableMap detailMap = fromJsonObject(jsonObject); - promise.resolve(detailMap); + detailResult = ldClient.stringVariationDetail(flagKey, fallback); } catch (Exception e) { - promise.resolve(fallback); + e.printStackTrace(); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); } + JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); + WritableMap detailMap = fromJsonObject(jsonObject); + promise.resolve(detailMap); } @ReactMethod @@ -673,12 +682,14 @@ private void jsonVariationBase(String flagKey, JsonElement fallback, Promise pro } private void jsonVariationDetailBase(String flagKey, JsonElement fallback, Promise promise) { + EvaluationDetail jsonElementDetail; try { - EvaluationDetail jsonElementDetail = ldClient.jsonVariationDetail(flagKey, fallback); - resolveJsonElementDetail(promise, jsonElementDetail); + jsonElementDetail = ldClient.jsonVariationDetail(flagKey, fallback); } catch (Exception e) { - resolveJsonElement(promise, fallback); + e.printStackTrace(); + jsonElementDetail = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); } + resolveJsonElementDetail(promise, jsonElementDetail); } diff --git a/index.d.ts b/index.d.ts index 9095029..da5be80 100644 --- a/index.d.ts +++ b/index.d.ts @@ -280,7 +280,7 @@ declare module 'launchdarkly-react-native-client-sdk' { PREREQUISITE_FAILED = 'PREREQUISITE_FAILED', /** - * The flag could not be evaluated, so the default value was returned + * The flag could not be evaluated, so the default value was returned. */ ERROR = 'ERROR', } @@ -499,7 +499,7 @@ declare module 'launchdarkly-react-native-client-sdk' { boolVariationDetail( flagKey: string, fallback: boolean, - ): Promise | boolean>; + ): Promise>; /** * Determines the variation of an integer feature flag for a user, along with information about how it was @@ -520,7 +520,7 @@ declare module 'launchdarkly-react-native-client-sdk' { intVariationDetail( flagKey: string, fallback: number, - ): Promise | number>; + ): Promise>; /** * Determines the variation of a floating-point feature flag for a user, along with information about how it was @@ -541,7 +541,7 @@ declare module 'launchdarkly-react-native-client-sdk' { floatVariationDetail( flagKey: string, fallback: number, - ): Promise | number>; + ): Promise>; /** * Determines the variation of a string feature flag for a user, along with information about how it was @@ -562,7 +562,7 @@ declare module 'launchdarkly-react-native-client-sdk' { stringVariationDetail( flagKey: string, fallback: string, - ): Promise | string>; + ): Promise>; /** * Determines the variation of a JSON feature flag for a user, along with information about how it was @@ -583,7 +583,7 @@ declare module 'launchdarkly-react-native-client-sdk' { jsonVariationDetail( flagKey: string, fallback: Record, - ): Promise> | Record>; + ): Promise>>; /** * Returns a map of all available flags to the current user's values. diff --git a/test-types.ts b/test-types.ts index 1a91249..d8f2633 100644 --- a/test-types.ts +++ b/test-types.ts @@ -64,16 +64,19 @@ async function tests() { const stringFlagValue: string = await client.stringVariation('key', 'default'); const jsonFlagValue: Record = await client.jsonVariation('key', jsonObj); - const boolDetail: LDEvaluationDetail | boolean = await client.boolVariationDetail('key', false); - const intDetail: LDEvaluationDetail | number = await client.intVariationDetail('key', 2); - const floatDetail: LDEvaluationDetail | number = await client.floatVariationDetail('key', 2.3); - const stringDetail: LDEvaluationDetail | string = await client.stringVariationDetail('key', 'default'); - const jsonDetail: LDEvaluationDetail> | Record = await client.jsonVariationDetail('key', jsonObj); + const boolDetail: LDEvaluationDetail = await client.boolVariationDetail('key', false); + const intDetail: LDEvaluationDetail = await client.intVariationDetail('key', 2); + const floatDetail: LDEvaluationDetail = await client.floatVariationDetail('key', 2.3); + const stringDetail: LDEvaluationDetail = await client.stringVariationDetail('key', 'default'); + const jsonDetail: LDEvaluationDetail> = await client.jsonVariationDetail('key', jsonObj); - const detailCasted = boolDetail as LDEvaluationDetail; - const detailValue: boolean = detailCasted.value; - const detailIndex: number | undefined = detailCasted.variationIndex; - const detailReason: LDEvaluationReason = detailCasted.reason; + const detailIndex: number | undefined = boolDetail.variationIndex; + const detailReason: LDEvaluationReason = boolDetail.reason; + const detailBoolValue: boolean = boolDetail.value; + const detailIntValue: number = intDetail.value; + const detailFloatValue: number = floatDetail.value; + const detailStringValue: string = stringDetail.value; + const detailJsonValue: Record = jsonDetail.value; const flagSet: LDFlagSet = await client.allFlags(); const flagSetValue: any = flagSet['key']; From e0155da940902a8ed0ad1716d5402d3db1535e5e Mon Sep 17 00:00:00 2001 From: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Date: Tue, 11 Feb 2020 16:55:54 -0800 Subject: [PATCH 3/6] bump android version (#36) --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 5c34599..3b7c1cb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -48,7 +48,7 @@ allprojects { dependencies { implementation 'com.facebook.react:react-native:+' - implementation 'com.launchdarkly:launchdarkly-android-client-sdk:2.9.0' + implementation 'com.launchdarkly:launchdarkly-android-client-sdk:2.10.0' implementation 'com.jakewharton.timber:timber:4.7.1' implementation "com.google.code.gson:gson:2.8.5" } From 7a4e00073fdd23a709c48dac21425eba4d6dc4f0 Mon Sep 17 00:00:00 2001 From: Joe Cieslik <5600929+torchhound@users.noreply.github.com> Date: Thu, 13 Feb 2020 12:51:50 -0800 Subject: [PATCH 4/6] Updated iOS SDK dependency to 4.4.1 (#37) --- ios/LaunchdarklyReactNativeClient.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/LaunchdarklyReactNativeClient.podspec b/ios/LaunchdarklyReactNativeClient.podspec index 55c3619..e793916 100644 --- a/ios/LaunchdarklyReactNativeClient.podspec +++ b/ios/LaunchdarklyReactNativeClient.podspec @@ -16,6 +16,6 @@ Pod::Spec.new do |s| s.swift_version = "5.0" s.dependency "React" - s.dependency "LaunchDarkly", "4.4.0" + s.dependency "LaunchDarkly", "4.4.1" end From b1bd3c51b9b3d39f4a3b69ff487ab6535caabeef Mon Sep 17 00:00:00 2001 From: Ben Woskow Date: Thu, 13 Feb 2020 22:56:59 -0800 Subject: [PATCH 5/6] fix compilation errors --- .../LaunchdarklyReactNativeClientModule.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java b/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java index d23b5fb..ccb0a15 100644 --- a/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java +++ b/android/src/main/java/com/launchdarkly/reactnative/LaunchdarklyReactNativeClientModule.java @@ -571,7 +571,7 @@ public void boolVariationDetailFallback(String flagKey, Boolean fallback, Promis detailResult = ldClient.boolVariationDetail(flagKey, fallback); } catch (Exception e) { e.printStackTrace(); - detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION), null, fallback); } JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); WritableMap detailMap = fromJsonObject(jsonObject); @@ -590,7 +590,7 @@ public void intVariationDetailFallback(String flagKey, Integer fallback, Promise detailResult = ldClient.intVariationDetail(flagKey, fallback); } catch (Exception e) { e.printStackTrace(); - detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION), null, fallback); } JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); WritableMap detailMap = fromJsonObject(jsonObject); @@ -609,7 +609,7 @@ public void floatVariationDetailFallback(String flagKey, Float fallback, Promise detailResult = ldClient.floatVariationDetail(flagKey, fallback); } catch (Exception e) { e.printStackTrace(); - detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION), null, fallback); } JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); WritableMap detailMap = fromJsonObject(jsonObject); @@ -628,7 +628,7 @@ public void stringVariationDetailFallback(String flagKey, String fallback, Promi detailResult = ldClient.stringVariationDetail(flagKey, fallback); } catch (Exception e) { e.printStackTrace(); - detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); + detailResult = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION), null, fallback); } JsonObject jsonObject = gson.toJsonTree(detailResult).getAsJsonObject(); WritableMap detailMap = fromJsonObject(jsonObject); @@ -687,7 +687,7 @@ private void jsonVariationDetailBase(String flagKey, JsonElement fallback, Promi jsonElementDetail = ldClient.jsonVariationDetail(flagKey, fallback); } catch (Exception e) { e.printStackTrace(); - jsonElementDetail = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION, null, fallback)); + jsonElementDetail = new EvaluationDetail(EvaluationReason.error(EvaluationReason.ErrorKind.EXCEPTION), null, fallback); } resolveJsonElementDetail(promise, jsonElementDetail); } From 2cfa0cd2bb9754710ec676615762f08ce34599f9 Mon Sep 17 00:00:00 2001 From: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Date: Thu, 20 Feb 2020 12:40:41 -0800 Subject: [PATCH 6/6] fix 3.0 release (#38) --- index.d.ts | 2 +- index.js | 9 ++------- test-types.ts | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/index.d.ts b/index.d.ts index da5be80..73d9645 100644 --- a/index.d.ts +++ b/index.d.ts @@ -402,7 +402,7 @@ declare module 'launchdarkly-react-native-client-sdk' { * * For more information, see the [SDK Reference Guide](https://docs.launchdarkly.com/docs/react-native-sdk-reference). */ - export class LDClient { + export default class LDClient { constructor(); /** diff --git a/index.js b/index.js index 1c8fd54..78caba4 100644 --- a/index.js +++ b/index.js @@ -18,13 +18,8 @@ export default class LDClient { backgroundPollingIntervalMillis: 3600000, // the iOS SDK defaults this to 900000 disableBackgroundUpdating: false // the iOS SDK defaults this to true }, config); - - // The Android SDK expects the events URI to be in the form of "/mobile" whereas iOS only expects "". - if (configWithOverriddenDefaults.eventsUri && Platform.OS === 'android') { - configWithOverriddenDefaults.eventsUri = configWithOverriddenDefaults.eventsUri + '/mobile'; - } - return LaunchdarklyReactNativeClient.configure(configWithOverriddenDefaults, _addUserOverrides(userConfig)); + return LaunchdarklyReactNativeClient.configure(configWithOverriddenDefaults, this._addUserOverrides(userConfig)); } boolVariation(flagKey, fallback) { @@ -192,7 +187,7 @@ export default class LDClient { } identify(userConfig) { - return LaunchdarklyReactNativeClient.identify(_addUserOverrides(userConfig)); + return LaunchdarklyReactNativeClient.identify(this._addUserOverrides(userConfig)); } _addUserOverrides(userConfig) { diff --git a/test-types.ts b/test-types.ts index d8f2633..31d99a4 100644 --- a/test-types.ts +++ b/test-types.ts @@ -2,8 +2,7 @@ // This file exists only so that we can run the TypeScript compiler in the CI build // to validate our index.d.ts file. The code will not actually be run. -import { - LDClient, +import LDClient, { LDClientConfig, LDEvaluationDetail, LDEvaluationReason,