From ead3e84faf4a8fb4255c0d31d6b6418ade633a6b Mon Sep 17 00:00:00 2001 From: Christian Brevik Date: Tue, 28 Aug 2018 13:33:23 +0200 Subject: [PATCH] Rewrite api surface (#274) * Rewrite API surface using TypeScript * Streamline the README --- .gitignore | 3 + .npmignore | 38 +- .travis/run.sh | 2 + README.md | 1030 +++-- .../GoogleAnalyticsBridge.java | 337 +- .../GoogleAnalyticsBridgePackage.java | 3 +- .../GoogleAnalyticsPayload.java | 426 ++ .../GoogleAnalyticsSettings.java | 50 + example/index.ios.js | 163 + example/jsconfig.json | 9 + example/yarn.lock | 582 +-- index.js | 18 - .../project.pbxproj | 12 + .../GoogleAnalyticsPayload.h | 5 + .../GoogleAnalyticsPayload.m | 181 + .../RCTGoogleAnalyticsBridge.h | 2 +- .../RCTGoogleAnalyticsBridge.m | 367 +- .../RCTGoogleAnalyticsSettings.h | 5 + .../RCTGoogleAnalyticsSettings.m | 25 + package-lock.json | 456 -- package.json | 22 +- src/GoogleAnalyticsBackwardsCompability.js | 119 - src/GoogleAnalyticsSettings.js | 34 - src/GoogleAnalyticsSettings.ts | 37 + src/GoogleAnalyticsTracker.js | 304 -- src/GoogleAnalyticsTracker.ts | 390 ++ src/GoogleTagManager.js | 64 - src/GoogleTagManager.ts | 89 + ...id.js => FunctionCallTagHandlerAndroid.ts} | 22 +- .../FunctionCallTagHandlerIOS.ts | 58 + .../FunctionCallTagHandler/index.ios.js | 42 - src/Helpers/FunctionCallTagHandler/index.ts | 11 + src/Helpers/FunctionCallTagHandler/models.ts | 5 + src/NativeBridges.js | 2 - src/NativeBridges.ts | 90 + src/index.ts | 17 + src/models/Analytics.ts | 108 + src/models/Custom.ts | 62 + src/models/DataLayerEvent.ts | 19 + src/models/Product.ts | 127 + tsconfig.json | 14 + types/index.d.ts | 362 -- types/tsconfig.json | 13 - types/tslint.json | 11 - types/type-tests.ts | 49 - yarn.lock | 3811 +++++++++++++++++ 46 files changed, 6898 insertions(+), 2698 deletions(-) create mode 100644 android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsPayload.java create mode 100644 android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsSettings.java create mode 100644 example/index.ios.js create mode 100644 example/jsconfig.json delete mode 100644 index.js create mode 100644 ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.h create mode 100644 ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.m create mode 100644 ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.h create mode 100644 ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.m delete mode 100644 package-lock.json delete mode 100644 src/GoogleAnalyticsBackwardsCompability.js delete mode 100644 src/GoogleAnalyticsSettings.js create mode 100644 src/GoogleAnalyticsSettings.ts delete mode 100644 src/GoogleAnalyticsTracker.js create mode 100644 src/GoogleAnalyticsTracker.ts delete mode 100644 src/GoogleTagManager.js create mode 100644 src/GoogleTagManager.ts rename src/Helpers/FunctionCallTagHandler/{index.android.js => FunctionCallTagHandlerAndroid.ts} (59%) create mode 100644 src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerIOS.ts delete mode 100644 src/Helpers/FunctionCallTagHandler/index.ios.js create mode 100644 src/Helpers/FunctionCallTagHandler/index.ts create mode 100644 src/Helpers/FunctionCallTagHandler/models.ts delete mode 100644 src/NativeBridges.js create mode 100644 src/NativeBridges.ts create mode 100644 src/index.ts create mode 100644 src/models/Analytics.ts create mode 100644 src/models/Custom.ts create mode 100644 src/models/DataLayerEvent.ts create mode 100644 src/models/Product.ts create mode 100644 tsconfig.json delete mode 100644 types/index.d.ts delete mode 100644 types/tsconfig.json delete mode 100644 types/tslint.json delete mode 100644 types/type-tests.ts create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index c4b7a9b4..39e2442f 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ node_modules # OS X .DS_Store + +# Project +dist \ No newline at end of file diff --git a/.npmignore b/.npmignore index aaf61f51..ce883723 100644 --- a/.npmignore +++ b/.npmignore @@ -1,9 +1,39 @@ # example project -example - +example/ +src/ # build .travis .travis.yml - +yarn.lock +npm-debug.log +yarn-error.log +.DS_Store # Github stuff -ISSUE_TEMPLATE.md \ No newline at end of file +ISSUE_TEMPLATE.md +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +!android/src/ \ No newline at end of file diff --git a/.travis/run.sh b/.travis/run.sh index 8f80ef32..71ee9880 100755 --- a/.travis/run.sh +++ b/.travis/run.sh @@ -6,6 +6,8 @@ if [ "$LANE" = "node" ]; then else npm install -g react-native-cli react-native -v + yarn install + yarn run tsc cd example yarn install diff --git a/README.md b/README.md index 2d5703b0..0ee89945 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # GoogleAnalyticsBridge [![npm version](https://img.shields.io/npm/v/react-native-google-analytics-bridge.svg)](https://www.npmjs.com/package/react-native-google-analytics-bridge) [![Build Status](https://travis-ci.org/idehub/react-native-google-analytics-bridge.svg?branch=master)](https://travis-ci.org/idehub/react-native-google-analytics-bridge) **Google Analytics Bridge** is built to provide an easy interface to the native Google Analytics libraries on both **iOS** and **Android**. @@ -16,38 +18,27 @@ tracker.trackScreenView("Home"); tracker.trackEvent("testcategory", "testaction"); ``` -## Use environment's Google Service Version (due to crash on Google Service version 12 - -You can specify googlePlayServicesVersion in "android/gradle.properties". Otherwise, it will take default version - -e.g. -`googlePlayServicesVersion=11.8.0` - +## Version 6 breaking changes! +If you are upgrading to version 6 from an older version, read [this wiki post for important details](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Version-6-breaking-changes). -## Problems with tracking? Visitors not showing up? +The newest version of this library has a new API surface. The API changes are in most cases backwards-compatible. -This is **NOT** (_normally_) an error with this library. Please read [this guide on how to set up your Google Analytics account/property](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Creating-a-Google-Analytics-property-for-mobile-analytics) for mobile analytics. - -## Problems with android build failures? - -Here I have mentioned the required steps to resolve the issues regarding the build failures, when you got updated your android studio [please check the following doc to clear the issues](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Solution-for-Android-build-failure-issues -) +[**Important**: If you are using ecommerce or custom dimensions, you probably have to migrate to new API if you upgrade!](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Version-6-breaking-changes#migrating-to-new-api) ## Content -* [Installation](#installation-and-linking-libraries) -* [Manual installation](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Manual-installation) -* [Usage](#usage) -* [JavaScript API](#javascript-api) -* [Troubleshooting](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Troubleshooting) -* [A/B testing](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Simple-A-B-testing) -* [Roadmap](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Roadmap) +- [Installation](#installation-and-linking-libraries) +- [Manual installation](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Manual-installation) +- [Usage](#usage) +- [JavaScript API](#javascript-api) +- [Problems with the library?](https://github.com/idehub/react-native-google-analytics-bridge/wiki/Troubleshooting) +- [See wiki for more helpful topics](https://github.com/idehub/react-native-google-analytics-bridge/wiki) ## Installation and linking libraries -* For React Native >= `0.40` use version `5.0.0` (and up) of this module. -* For React Native < `0.40` use version `4.0.3`. +- For React Native >= `0.40` use version `5.0.0` (and up) of this module. +- For React Native < `0.40` use version `4.0.3`. Install with npm: `npm install --save react-native-google-analytics-bridge` @@ -108,394 +99,491 @@ GoogleTagManager.registerFunctionCallTagHandler( ) ``` -## Providing an existing GTM container - -In some scenarios it might be helpful to provide an opened GTM container to the bridge. Some possible scenarios where this could be helpful: +## JavaScript API -* You want to preload some config before loading the jsbundle. For instance checking an experiment variable to determine which jsbundle to load. -* You have a brownfield app that mixes native UI and react native UI that should share the same container. -* You want to try and make sure that the container is loaded before starting the app. + + +#### Table of Contents + +- [GoogleAnalyticsSettings](#googleanalyticssettings) + - [setOptOut](#setoptout) + - [Parameters](#parameters) + - [Examples](#examples) + - [setDispatchInterval](#setdispatchinterval) + - [Parameters](#parameters-1) + - [Examples](#examples-1) + - [setDryRun](#setdryrun) + - [Parameters](#parameters-2) + - [Examples](#examples-2) +- [GoogleAnalyticsTracker](#googleanalyticstracker) + - [Examples](#examples-3) + - [trackScreenView](#trackscreenview) + - [Parameters](#parameters-3) + - [Examples](#examples-4) + - [trackEvent](#trackevent) + - [Parameters](#parameters-4) + - [Examples](#examples-5) + - [trackTiming](#tracktiming) + - [Parameters](#parameters-5) + - [Examples](#examples-6) + - [trackException](#trackexception) + - [Parameters](#parameters-6) + - [Examples](#examples-7) + - [trackSocialInteraction](#tracksocialinteraction) + - [Parameters](#parameters-7) + - [Examples](#examples-8) + - [setUser](#setuser) + - [Parameters](#parameters-8) + - [Examples](#examples-9) + - [setClient](#setclient) + - [Parameters](#parameters-9) + - [Examples](#examples-10) + - [getClientId](#getclientid) + - [Examples](#examples-11) + - [allowIDFA](#allowidfa) + - [Parameters](#parameters-10) + - [Examples](#examples-12) + - [setAppName](#setappname) + - [Parameters](#parameters-11) + - [Examples](#examples-13) + - [setAppVersion](#setappversion) + - [Parameters](#parameters-12) + - [Examples](#examples-14) + - [setAnonymizeIp](#setanonymizeip) + - [Parameters](#parameters-13) + - [Examples](#examples-15) + - [setSamplingRate](#setsamplingrate) + - [Parameters](#parameters-14) + - [Examples](#examples-16) + - [setCurrency](#setcurrency) + - [Parameters](#parameters-15) + - [Examples](#examples-17) + - [setTrackUncaughtExceptions](#settrackuncaughtexceptions) + - [Parameters](#parameters-16) + - [dispatch](#dispatch) + - [Examples](#examples-18) + - [dispatchWithTimeout](#dispatchwithtimeout) + - [Parameters](#parameters-17) + - [Examples](#examples-19) +- [GoogleTagManager](#googletagmanager) + - [Examples](#examples-20) + - [openContainerWithId](#opencontainerwithid) + - [Parameters](#parameters-18) + - [Examples](#examples-21) + - [boolForKey](#boolforkey) + - [Parameters](#parameters-19) + - [Examples](#examples-22) + - [stringForKey](#stringforkey) + - [Parameters](#parameters-20) + - [Examples](#examples-23) + - [doubleForKey](#doubleforkey) + - [Parameters](#parameters-21) + - [Examples](#examples-24) + - [pushDataLayerEvent](#pushdatalayerevent) + - [Parameters](#parameters-22) + - [Examples](#examples-25) + - [registerFunctionCallTagHandler](#registerfunctioncalltaghandler) + - [Parameters](#parameters-23) + - [setVerboseLoggingEnabled](#setverboseloggingenabled) + - [Parameters](#parameters-24) +- [TimingMetadata](#timingmetadata) + - [Parameters](#parameters-25) + - [Examples](#examples-26) +- [EventMetadata](#eventmetadata) + - [Parameters](#parameters-26) + - [Examples](#examples-27) +- [HitPayload](#hitpayload) + - [Parameters](#parameters-27) + - [Examples](#examples-28) +- [CustomDimensionsByField](#customdimensionsbyfield) + - [Examples](#examples-29) +- [CustomDimensionsByIndex](#customdimensionsbyindex) + - [Examples](#examples-30) +- [CustomDimensionsFieldIndexMap](#customdimensionsfieldindexmap) + - [Examples](#examples-31) +- [CustomMetrics](#custommetrics) + - [Examples](#examples-32) +- [DataLayerEvent](#datalayerevent) + - [Parameters](#parameters-28) + - [Examples](#examples-33) +- [ProductActionEnum](#productactionenum) +- [Product](#product) + - [Parameters](#parameters-29) + - [Examples](#examples-34) +- [ProductAction](#productaction) + - [Parameters](#parameters-30) + - [Examples](#examples-35) +- [Transaction](#transaction) + - [Parameters](#parameters-31) + - [Examples](#examples-36) + +### GoogleAnalyticsSettings + +Settings which are applied across all trackers. + +#### setOptOut + +Sets if OptOut is active and disables Google Analytics. This is disabled by default. Note: This has to be set each time the App starts. + +##### Parameters + +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +##### Examples -This will require that you are familiar with the native api for GTM on whatever platforms you want to support. Generally the process is to load your container at startup, and hold the creation of the react native bridge until the container is loaded. On iOS you can then initialize an RCTGoogleTagManagerBridge and set the container property. On Android the process is similar, but you will need to supply the ContainerHolder to the GoogleAnalyticsBridgePackage instead. +```javascript +GoogleAnalyticsSettings.setOptOut(true); +``` -## JavaScript API +#### setDispatchInterval -* [GoogleAnalyticsTracker](#googleanalyticstracker-api) -* [GoogleAnalyticsSettings](#googleanalyticssettings-api) -* [GoogleTagManager](#googletagmanager-api) +Sets the trackers dispatch interval. +Events, screen views, etc, are sent in batches to your tracker. This function allows you to configure how often (in seconds) the batches are sent to your tracker. Recommended to keep this around 20-120 seconds to preserve battery and network traffic. This is set to 20 seconds by default. -## GoogleAnalyticsTracker API +##### Parameters -### new GoogleAnalyticsTracker(trackerId, customDimensionsFieldsIndexMap = {}) +- `intervalInSeconds` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -* **trackerId (required):** String, your tracker id, something like: UA-12345-1 -* **customDimensionsFieldsIndexMap (optional):** {{fieldName: fieldIndex}} Custom dimensions field/index pairs +##### Examples ```javascript -import { GoogleAnalyticsTracker } from "react-native-google-analytics-bridge"; -let tracker = new GoogleAnalyticsTracker("UA-12345-1"); +GoogleAnalyticsSettings.setDispatchInterval(30); ``` -Google Analytics expects dimensions to be tracked by indices, and not field names. -To simplify this, you can construct a tracker with a customDimensionsFieldsIndexMap. With this, you can map field names to indices, e.g: +#### setDryRun -```javascript -let tracker2 = new GoogleAnalyticsTracker("UA-12345-3", { test: 1 }); -tracker2.trackScreenViewWithCustomDimensionValues("Home", { test: "Beta" }); -``` +When enabled the native library prevents any data from being sent to Google Analytics. This allows you to test or debug the implementation, without your test data appearing in your Google Analytics reports. -Here the underlying logic will transform the custom dimension, so what ends up being sent to GA is `{ 1: 'Beta' }`. -This should make it easier to use custom dimensions. If you do not provide a customDimensionsFieldsIndexMap, the custom dimensions are passed through untouched. +##### Parameters -### trackScreenView(screenName) +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -* **screenName (required):** String, name of current screen +##### Examples -**Important**: Calling this will also set the "current view" for other calls. So events tracked will be tagged as having occured on the current view, `Home` in this example. This means it is important to track navigation, especially if events can fire on different views. +```javascript +GoogleAnalyticsSettings.setDryRun(true); +``` + +### GoogleAnalyticsTracker -See the [Google Analytics docs](https://developers.google.com/analytics/devguides/collection/ios/v3/screens) for more info +#### Examples ```javascript +// Constructing a tracker is simple: +import { GoogleAnalyticsTracker } from "react-native-google-analytics-bridge"; +const tracker = new GoogleAnalyticsTracker("UA-12345-1"); tracker.trackScreenView("Home"); + +// You can have multiple trackers if you have several tracking ids +const tracker2 = new GoogleAnalyticsTracker("UA-12345-2"); ``` -### trackEvent(category, action, optionalValues) +```javascript +// One optional feature as well is constructing a tracker with a CustomDimensionsFieldIndexMap, to map custom dimension field names to index keys: +const fieldIndexMap = { customerType: 1 }; +const tracker3 = new GoogleAnalyticsTracker("UA-12345-3", fieldIndexMap); -* **category (required):** String, category of event -* **action (required):** String, name of action -* **optionalValues:** Object - * **label:** String - * **value:** Number +// This is because the Google Analytics API expects custom dimensions to be tracked by index keys, and not field names. +// Here the underlying logic will transform the custom dimension, so what ends up being sent to GA is { 1: 'Premium' }: +tracker3.trackScreenView("Home", { customDimensions: { customerType: "Premium" } }); -See the [Google Analytics docs](https://developers.google.com/analytics/devguides/collection/ios/v3/events) for more info. +// If you do not use a CustomDimensionsFieldIndexMap, you will have to use index as keys instead for custom dimensions: +tracker.trackScreenView("Home", { customDimensions: { 1: "Premium" } }); +``` + +#### trackScreenView + +Track the current screen/view. Calling this will also set the "current view" for other calls. + So events tracked will be tagged as having occured on the current view, `Home` in this example. +This means it is important to track navigation, especially if events can fire on different views. + +##### Parameters + +- `screenName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The name of the current screen +- `payload` **[HitPayload](#hitpayload)** (Optional) An object containing the hit payload (optional, default `null`) + +##### Examples ```javascript -tracker.trackEvent("testcategory", "testaction"); -// or -tracker.trackEvent("testcategory", "testaction", { - label: "v1.0.3", - value: 22 -}); -``` - -### trackTiming(category, value, optionalValues) - -* **category (required):** String, category of the timed event -* **value (required):** Number, the timing measurement in milliseconds -* **optionalValues:** Object - * **name (required):** String, the name of the timed event - * **label:** String, the label of the timed event - -See the [Google Analytics docs](https://developers.google.com/analytics/devguides/collection/ios/v3/usertimings) for more info. - -```javascript -tracker.trackTiming("testcategory", 13000, { name: "LoadList" }); // name option is required -// or -tracker.trackTiming("testcategory", 13000, { - name: "loadList", - label: "v1.0.3" -}); -``` - -### trackPurchaseEvent(product, transaction, eventCategory, eventAction) - -* **product (required):** Object - * **id (required):** String - * **name (required):** String - * **category (optional):** String - * **brand (optional):** String - * **variant (optional):** String - * **price (optional):** Number - * **quantity (optional):** Number - * **couponCode (optional):** String -* **transaction (required):** Object - * **id (required):** String - * **affiliation (optional):** String, an entity with which the transaction should be affiliated (e.g. a particular store) - * **revenue (optional):** Number - * **tax (optional):** Number - * **shipping (optional):** Number - * **couponCode (optional):** String -* **eventCategory (required):** String, defaults to "Ecommerce" -* **eventAction (required):** String, defaults to "Purchase" - -See the [Google Analytics docs](https://developers.google.com/analytics/devguides/collection/ios/v3/enhanced-ecommerce#measuring-transactions) for more info. - -```javascript -tracker.trackPurchaseEvent( - { - id: "P12345", - name: "Android Warhol T-Shirt", - category: "Apparel/T-Shirts", - brand: "Google", - variant: "Black", - price: 29.2, - quantity: 1, - couponCode: "APPARELSALE" - }, - { - id: "T12345", - affiliation: "Google Store - Online", - revenue: 37.39, - tax: 2.85, - shipping: 5.34, - couponCode: "SUMMER2013" - }, - "Ecommerce", - "Purchase" -); -``` - -### trackMultiProductsPurchaseEvent(products, transaction, eventCategory, eventAction) - -same as trackPurchaseEvent but instead of one product you can provide an Array of products - -### trackMultiProductsPurchaseEventWithCustomDimensionValues(products, transaction, eventCategory, eventAction, dimensionIndexValueDict) - -* **products (required):** Array, array of products -* **transaction (required):** Object, transaction object -* **eventCategory (required):** String, defaults to "Ecommerce" -* **eventAction (required):** String, defaults to "Purchase" -* **dimensionIndexValueDict (required):** Dict of dimension index / values. - -```javascript -tracker.trackMultiProductsPurchaseEventWithCustomDimensionValues( - [ - { - id: "P12345", - name: "Android Warhol T-Shirt", - category: "Apparel/T-Shirts", - brand: "Google", - variant: "Black", - price: 29.2, - quantity: 1, - couponCode: "APPARELSALE" - }, - { - id: "P54321", - name: "IOS T-Shirt", - category: "Apparel/T-Shirts", - brand: "Apple", - variant: "Black", - price: 10.1, - quantity: 1, - couponCode: "APPARELSALE" - } - ], - { - id: "T12345", - affiliation: "Store - Online", - revenue: 52.5, - tax: 7.86, - shipping: 5.34, - couponCode: "SUMMER2013" - }, - "Ecommerce", - "Purchase", - { "1": "premium", "5": "foo" } -); -``` - -### trackException(error, fatal) - -* **error:** String, a description of the exception (up to 100 characters), accepts nil -* **fatal (required):** Boolean, indicates whether the exception was fatal, defaults to false - -See the [Google Analytics docs](https://developers.google.com/analytics/devguides/collection/ios/v3/exceptions) for more info. +tracker.trackScreenView('Home'); +``` ```javascript -try { - ... -} catch(error) { - tracker.trackException(error.message, false); -} +// With payload: +const payload = { impressionList: "Sale", impressionProducts: [ { id: "PW928", name: "Premium bundle" } ] }; +tracker.trackScreenView("SplashModal", payload); ``` -### trackSocialInteraction(network, action, targetUrl) +#### trackEvent -* **network (required):** String, name of social network (e.g. 'Facebook', 'Twitter', 'Google+') -* **action (required):** String, social action (e.g. 'Like', 'Share', '+1') -* **targetUrl:** String, url of content being shared +Track an event that has occured -See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/social) docs for more info. +##### Parameters -```javascript -tracker.trackSocialInteraction("Twitter", "Post"); -``` +- `category` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The event category +- `action` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The event action +- `eventMetadata` **[EventMetadata](#eventmetadata)** (Optional) An object containing event metadata +- `payload` **[HitPayload](#hitpayload)** (Optional) An object containing the hit payload (optional, default `null`) -### trackScreenViewWithCustomDimensionValues(screenName, dimensionIndexValueDict) +##### Examples -* **screenName (required):** String, name of current screen -* **dimensionIndexValueDict (required):** Dict of dimension index / values. +```javascript +tracker.trackEvent("DetailsButton", "Click"); +``` -Tracks a screen view with one or more customDimensionValues. See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/customdimsmets) docs for more info. +```javascript +// Track event with label and value +tracker.trackEvent("AppVersionButton", "Click", { label: "v1.0.3", value: 22 }); +``` ```javascript -tracker.trackScreenViewWithCustomDimensionValues("Home", { - "1": "premium", - "5": "foo" -}); +// Track with a payload (ecommerce in this case): +const product = { + id: "P12345", + name: "Android Warhol T-Shirt", + category: "Apparel/T-Shirts", + brand: "Google", + variant: "Black", + price: 29.2, + quantity: 1, + couponCode: "APPARELSALE" +}; +const transaction = { + id: "T12345", + affiliation: "Google Store - Online", + revenue: 37.39, + tax: 2.85, + shipping: 5.34, + couponCode: "SUMMER2013" +}; +const productAction = { + transaction, + action: 7 // Purchase action, see ProductActionEnum +} +const payload = { products: [ product ], productAction: productAction } +tracker.trackEvent("FinalizeOrderButton", "Click", null, payload); ``` -### trackEventWithCustomDimensionValues(category, action, optionalValues, dimensionIndexValueDict) +#### trackTiming + +Track a timing measurement -* **category (required):** String, category of event -* **action (required):** String, name of action -* **optionalValues:** Object - * **label:** String - * **value:** Number -* **dimensionIndexValueDict (required):** Dict of dimension index / values. +##### Parameters -Tracks an event with one or more customDimensionValues. See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/customdimsmets) docs for more info. +- `category` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The event category +- `interval` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Required) The timing measurement in milliseconds +- `timingMetadata` **[TimingMetadata](#timingmetadata)** (Required) An object containing timing metadata +- `payload` **[HitPayload](#hitpayload)** (Optional) An object containing the hit payload (optional, default `null`) + +##### Examples ```javascript -tracker.trackEventWithCustomDimensionValues( - "testcategory", - "testaction", - { label: "v1.0.3", value: 22 }, - { "1": "premium", "5": "foo" } -); +tracker.trackTiming("testcategory", 2000, { name: "LoadList" }); // name metadata is required ``` -### trackEventWithCustomDimensionAndMetricValues(category, action, optionalValues, dimensionIndexValueDict) +```javascript +// With optional label: +tracker.trackTiming("testcategory", 2000, { name: "LoadList", label: "v1.0.3" }); +``` -* **category (required):** String, category of event -* **action (required):** String, name of action -* **optionalValues:** Object - * **label:** String - * **value:** Number -* **dimensionIndexValueDict (required):** Dict of dimension index / values. -* **metricIndexValueDict (required):** Dict of metric index / values. +#### trackException -Tracks an event with one or more customDimensionValues and one or more customMetricValues. See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/customdimsmets) docs for more info. +Track an exception + +##### Parameters + +- `error` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The description of the error +- `fatal` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (Optional) A value indiciating if the error was fatal, defaults to false (optional, default `false`) +- `payload` **[HitPayload](#hitpayload)** (Optional) An object containing the hit payload (optional, default `null`) + +##### Examples ```javascript -tracker.trackEventWithCustomDimensionAndMetricValues('testcategory', 'testaction', {label: 'v1.0.3', value: 22}, {'1':'premium', '5':'foo'}, , {'1': 3, '5': 4}); +try { + ... +} catch(error) { + tracker.trackException(error.message, false); +} ``` -### setUser(userId) +#### trackSocialInteraction + +Track a social interaction, Facebook, Twitter, etc. + +##### Parameters -* **userId (required):** String, an **anonymous** identifier that complies with Google Analytic's user ID policy +- `network` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `action` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `targetUrl` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `payload` **[HitPayload](#hitpayload)** (Optional) An object containing the hit payload -See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/user-id) for more info. +##### Examples ```javascript -tracker.setUser("12345678"); +tracker.trackSocialInteraction("Twitter", "Post"); ``` -### setClient(clientId) +#### setUser + +Sets the current userId for tracking. -* **clientId (required):** String, an **anonymous** identifier that complies with Google Analytic's client ID policy +##### Parameters -See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#clientId) for more info. +- `userId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** An anonymous identifier that complies with Google Analytic's user ID policy + +##### Examples ```javascript -tracker.setClient("35009a79-1a05-49d7-b876-2b884d0f825b"); +tracker.setUser("12345678"); ``` -### getClientId() +#### setClient -This function lets you get the client id to be used for different purpose for logging etc. +Sets the current clientId for tracking. -* returns Promise +##### Parameters + +- `clientId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** A anonymous identifier that complies with Google Analytic's client ID policy + +##### Examples ```javascript -tracker.clientId().then(clientId => console.log("Client id is: ", clientId)); +tracker.setClient("35009a79-1a05-49d7-b876-2b884d0f825b"); ``` -### createNewSession(screenName) +#### getClientId -* **screenName (required):** String, the current screen which the session started on +Get the client id to be used for purpose of logging etc. -See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/sessions#manual) for more info. +##### Examples ```javascript -tracker.createNewSession("HomeScreen"); +tracker.getClientId().then(clientId => console.log("Client id is: ", clientId)); ``` -### allowIDFA(enabled) +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** -* **enabled (required):** Boolean, true to allow IDFA collection, defaults to `true`. +#### allowIDFA Also called advertising identifier collection, and is used for advertising features. **Important**: For iOS you can only use this method if you have done the optional step 6 from the installation guide. Only enable this (and link the appropriate libraries) if you plan to use advertising features in your app, or else your app may get rejected from the AppStore. -See the [Google Analytics](https://developers.google.com/analytics/devguides/collection/ios/v3/campaigns#ios-install) for more info. +##### Parameters + +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (Optional) Defaults to true (optional, default `true`) + +##### Examples ```javascript tracker.allowIDFA(true); ``` -### setTrackUncaughtExceptions(enabled) +#### setAppName + +Overrides the app name logged in Google Analytics. The Bundle name is used by default. Note: This has to be set each time the App starts. -* **enabled (required):** Boolean +##### Parameters -Sets if uncaught exceptions should be tracked. This is enabled by default. +- `appName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) + +##### Examples ```javascript -tracker.setTrackUncaughtExceptions(true); +tracker.setAppName("YourAwesomeApp"); ``` -### setAnonymizeIp(enabled) +#### setAppVersion + +Sets the trackers appVersion + +##### Parameters -* **enabled (required):** Boolean +- `appVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) -Sets if AnonymizeIp is enabled. This is disabled by default. -If enabled the last octet of the IP address will be removed. +##### Examples ```javascript -tracker.setAnonymizeIp(true); +tracker.setAppVersion("1.3.2"); ``` -### setAppName(appName) +#### setAnonymizeIp + +Sets if AnonymizeIp is enabled +If enabled the last octet of the IP address will be removed -* **appName (required):** String +##### Parameters -Overrides the app name logged in Google Analytics. The Bundle name is used by default. -Note: This has to be set each time the App starts. +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (Required) + +##### Examples ```javascript -tracker.setAppName("someAppName"); +tracker.setAnonymizeIp(true); ``` -### setSamplingRate(ratio) - -* **ratio (required):** Number Percentage 0 - 100 +#### setSamplingRate Sets tracker sampling rate. +##### Parameters + +- `sampleRatio` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Required) Percentage 0 - 100 + +##### Examples + ```javascript tracker.setSamplingRate(50); ``` -### setCurrency(currencyCode) +#### setCurrency + +Sets the currency for tracking. + +##### Parameters -* **currencyCode (required):** String, ISO 4217 currency code +- `currencyCode` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) The currency ISO 4217 code -Sets tracker currency property, see [Currency Codes](https://developers.google.com/analytics/devguides/platform/features/currencies). +##### Examples ```javascript tracker.setCurrency("EUR"); ``` -### dispatch() +#### setTrackUncaughtExceptions + +Sets if uncaught exceptions should be tracked +Important to note: On iOS this option is set on all trackers. On Android it is set per tracker. +If you are using multiple trackers on iOS, this will enable & disable on all trackers. + +##### Parameters + +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +#### dispatch This function lets you manually dispatch all hits which are queued. -Use this function sparingly, as it will normally happen automatically as a batch. +Use this function sparingly, as it will normally happen automatically +as a batch. This function will also dispatch for all trackers. -* returns Promise +##### Examples ```javascript tracker.dispatch().then(done => console.log("Dispatch is done: ", done)); ``` -### dispatchWithTimeout() +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** Returns when done + +#### dispatchWithTimeout + +The same as `dispatch`, but also gives you the ability to time out +the Promise in case dispatch takes too long. -* **timeout (optional):** Number, in ms +##### Parameters -The same as `dispatch()`, but also gives you the ability to time out the Promise in case dispatch takes too long. +- `timeout` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The timeout. Default value is 15 sec. (optional, default `-1`) -* returns Promise +##### Examples ```javascript tracker @@ -503,160 +591,394 @@ tracker .then(done => console.log("Dispatch is done: ", done)); ``` -## GoogleAnalyticsSettings API +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** Returns when done or timed out -Settings are applied across all trackers. +### GoogleTagManager -### setDryRun(enabled) +Can only be used with one container. All functions returns a Promise. -* **enabled (required):** Boolean, indicating if the `dryRun` flag should be enabled or not. +#### Examples -When enabled the native library prevents any data from being sent to Google Analytics. This allows you to test or debug the implementation, without your test data appearing in your Google Analytics reports. +```javascript +import { GoogleTagManager } from "react-native-google-analytics-bridge"; +GoogleTagManager.openContainerWithId("GT-NZT48") + .then(() => GoogleTagManager.stringForKey("pack")) + .then(str => console.log("Pack: ", str)); +``` + +#### openContainerWithId + +Call once to open the container for all subsequent static calls. + +##### Parameters + +- `containerId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +##### Examples ```javascript -GoogleAnalyticsSettings.setDryRun(true); +GoogleTagManager.openContainerWithId('GT-NZT48').then((..) => ..) ``` -### setDispatchInterval(intervalInSeconds) +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** + +#### boolForKey + +Retrieves a boolean value with the given key from the opened container. -* **intervalInSeconds (required):** Number, indicating how often dispatches should be sent +##### Parameters -Events, screen views, etc, are sent in batches to your tracker. This function allows you to configure how often (in seconds) the batches are sent to your tracker. Recommended to keep this around 20-120 seconds to preserve battery and network traffic. -This is set to 20 seconds by default. +- `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +##### Examples ```javascript -GoogleAnalyticsSettings.setDispatchInterval(30); +GoogleTagManager.boolForKey("key").then(val => console.log(val)); ``` -### setOptOut(enabled) +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** + +#### stringForKey + +Retrieves a string with the given key from the opened container. + +##### Parameters -* **enabled (required):** Boolean +- `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** -Sets if OptOut is active and disables Google Analytics. This is disabled by default. -Note: This has to be set each time the App starts. +##### Examples ```javascript -GoogleAnalyticsSettings.setOptOut(true); +GoogleTagManager.stringForKey("key").then(val => console.log(val)); ``` -## GoogleTagManager API +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** + +#### doubleForKey + +Retrieves a number with the given key from the opened container. + +##### Parameters + +- `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +##### Examples ```javascript -import { GoogleTagManager } from "react-native-google-analytics-bridge"; -GoogleTagManager.openContainerWithId("GT-NZT48") - .then(() => GoogleTagManager.stringForKey("pack")) - .then(str => console.log("Pack: ", str)); +GoogleTagManager.doubleForKey("key").then(val => console.log(val)); ``` -Can only be used with one container. All methods returns a `Promise`. +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** + +#### pushDataLayerEvent -### openContainerWithId(containerId) +Push a datalayer event for Google Analytics through Google Tag Manager. The event must have at least one key "event" with event name. -* **containerId (required):** String, your container id. +##### Parameters -**Important**: Call **once** to open the container for all subsequent static calls. +- `event` **[DataLayerEvent](#datalayerevent)** An Map<String, Object> containing key and value pairs. It must have at least one key "event" with event name + +##### Examples ```javascript -GoogleTagManager.openContainerWithId('GT-NZT48') -.then((..) => ..) +GoogleTagManager.pushDataLayerEvent({ + event: "eventName", + pageId: "/home" +}).then(success => console.log(success)); ``` -### stringForKey(key) +Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** -##### Parameter(s) +#### registerFunctionCallTagHandler -* **key (required):** String +Register Function Call tag handler -##### Returns: +##### Parameters -* **value:** String +- `functionName` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** -Retrieves a string with the given key from the opened container. +#### setVerboseLoggingEnabled + +Sets logger to verbose, default is warning + +##### Parameters + +- `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +### TimingMetadata + +Used when tracking time measurements + +#### Parameters + +- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Required) +- `label` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) + +#### Examples ```javascript -GoogleTagManager.stringForKey("key").then(val => console.log(val)); +const timingMetadata = { name: "LoadList" } // name is a required value when tracking timing +tracker.trackTiming("testcategory", 13000, timingMetadata); ``` -### boolForKey(key) +### EventMetadata -##### Parameter(s) +Used when tracking event -* **key (required):** String +#### Parameters -##### Returns: +- `label` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `value` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) -* **value:** Boolean +#### Examples -Retrieves a boolean value with the given key from the opened container. +```javascript +const eventMetadata = { label: "v1.0.3", value: 22 } +tracker.trackEvent("FinalizeOrderButton", "Click", eventMetadata); +``` + +### HitPayload + +The HitPayload object and possible values + +Used by the different tracking methods for adding metadata to the hit. + +#### Parameters + +- `products` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Product](#product)>** (Optional) Used for ecommerce +- `impressionProducts` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Product](#product)>** (Optional) Used for ecommerce +- `impressionList` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) Used for ecommerce +- `impressionSource` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) Used for ecommerce +- `productAction` **[ProductAction](#productaction)** (Optional) Used for ecommerce +- `customDimensions` **([CustomDimensionsByIndex](#customdimensionsbyindex) \| [CustomDimensionsByField](#customdimensionsbyfield))** (Optional) +- `customMetrics` **[CustomMetrics](#custommetrics)** (Optional) +- `utmCampaignUrl` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) Used for campaigns +- `session` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) Only two possible values, "start" or "end". This will either start or end a session. + +#### Examples ```javascript -GoogleTagManager.boolForKey("key").then(val => console.log(val)); +// If you want to do send a purchase payload with an event: +const product = { + id: "P12345", + name: "Android Warhol T-Shirt", + category: "Apparel/T-Shirts", + brand: "Google", + variant: "Black", + price: 29.2, + quantity: 1, + couponCode: "APPARELSALE" +}; +const transaction = { + id: "T12345", + affiliation: "Google Store - Online", + revenue: 37.39, + tax: 2.85, + shipping: 5.34, + couponCode: "SUMMER2013" +}; +const productAction = { + transaction, + action: 7 // Purchase action, see ProductActionEnum +} +const payload = { products: [ product ], productAction: productAction } +tracker.trackEvent("FinalizeOrderButton", "Click", null, payload); ``` -### doubleForKey(key) +```javascript +// If you want to send custom dimensions with a screen view: +const customDimensions = { + 1: "Beta", + 3: "Premium" +}; +const payload = { customDimensions }; +tracker.trackScreenView("SaleScreen", payload); +``` -##### Parameter(s) +### CustomDimensionsByField -* **key (required):** String +- **See: CustomDimensionsFieldIndexMap** +- **See: CustomDimensionsByIndex** -##### Returns: +A dictionary with custom dimensions values and their (mapped) field name keys. +In order to use this and send in custom dimensions by field name, you must have +provided a `CustomDimensionsFieldIndexMap` when constructing the tracker. -* **value:** Number +#### Examples -Retrieves a number with the given key from the opened container. +```javascript +const customDimensions = { customerType: "Premium", appType: "Beta", credit: 1200 } +tracker.trackScreenView("Home", { customDimensions }); +``` + +### CustomDimensionsByIndex + +- **See: CustomDimensionsFieldIndexMap** +- **See: CustomDimensionsByField** + +A dictionary with custom dimensions values and their index keys. + +#### Examples ```javascript -GoogleTagManager.doubleForKey("key").then(val => console.log(val)); +const customDimensions = { 1: "Premium", 3: "Beta", 5: 1200 } +tracker.trackScreenView("Home", { customDimensions }); ``` -### pushDataLayerEvent(dictionary = {}) +### CustomDimensionsFieldIndexMap + +- **See: CustomDimensionsFieldIndexMap** +- **See: CustomDimensionsByField** + +A dictionary describing mapping of field names to indices for custom dimensions. +This is an optional object used by the tracker. -##### Parameter(s) +#### Examples -* **dictionary (required):** dictionary An Map containing key and value pairs. +```javascript +// Create something like: +const fieldIndexMap = { customerType: 1 }; +// Construct tracker with it: +const tracker = new GoogleAnalyticsTracker("UA-12345-3", fieldIndexMap); +// This allows you to send in customDimensions in the`HitPayload by field name instead of index: +tracker.trackScreenView("Home", { customDimensions: { customerType: "Premium" } }); +// If you do not provide a map, you instead have to send in by index: +tracker.trackScreenView("Home", { customDimensions: { 1: "Premium" } }); +``` -##### Returns: +### CustomMetrics -* **value:** Boolean +A dictionary with custom metric values and their index keys. -Push a DataLayer event for Google Analytics through Google Tag Manager. +#### Examples ```javascript -GoogleTagManager.pushDataLayerEvent({ +const customMetrics = { 1: 2389, 4: 15000 } +tracker.trackScreenView("Home", { customMetrics }); +``` + +### DataLayerEvent + +The Google Tag Manager DataLayerEvent dictionary. + +Populate this event-object with values to push to the DataLayer. The only required property is `event`. + +#### Parameters + +- `event` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +#### Examples + +```javascript +const dataLayerEvent = { event: "eventName", pageId: "/home" -}).then(success => console.log(success)); +}; +GoogleTagManager.pushDataLayerEvent(dataLayerEvent); ``` -### registerFunctionCallTagHandler(functionName, handler) +### ProductActionEnum + +Enhanced Ecommerce ProductActionEnum + +Used by `ProductAction` when describing the type of product action. The possible values (numbers) are: + +- Detail = 1, +- Click = 2, +- Add = 3, +- Remove = 4, +- Checkout = 5, +- CheckoutOption = 6, +- Purchase = 7, +- Refund = 8 -##### Parameter(s) +### Product -* **functionName (required):** String -* **handler (required):** function +Enhanced Ecommerce Product -Resgisters a Function Call tag handler based on name of the function that has been configured in the Tag Manager interface. +Used by `HitPayload` when populating product actions or impressions + +#### Parameters + +- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `category` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `brand` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `variant` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `price` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) +- `couponCode` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `quantity` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) + +#### Examples ```javascript -GoogleTagManager.registerFunctionCallTagHandler("name_of_the_function", (functionName, tagArguments) => { - // Handle the Function Tag when it is fired -}).then(() => { - console.log("Function call tag handler has been registered"); -}); +const product = { + id: "P12345", + name: "Android Warhol T-Shirt", + category: "Apparel/T-Shirts", + brand: "Google", + variant: "Black", + price: 29.2, + quantity: 1, + couponCode: "APPARELSALE" +}; ``` -### setVerboseLoggingEnabled(enabled) +### ProductAction -##### Parameter(s) +Enhanced Ecommerce Product Action -* **enabled (required):** Boolean +Used by `HitPayload` when describing a product action -##### Returns: +#### Parameters -* **value:** Boolean +- `action` **[ProductActionEnum](#productactionenum)** +- `transaction` **[Transaction](#transaction)** (Optional) +- `checkoutStep` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) +- `checkoutOption` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `productActionList` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `productListSource` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) -Sets logger to verbose, default is warning +#### Examples + +```javascript +const productAction = { + transaction, + action: 7 // Purchase action, see ProductActionEnum +} +``` + +```javascript +const productAction = { + action: 3 // Add action, see ProductActionEnum +} +``` + +### Transaction + +Enhanced Ecommerce Transaction + +Used by `ProductAction` when populating describing a purchase/transaction + +#### Parameters + +- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `affiliation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) +- `revenue` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional - but not really) +- `tax` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) +- `shipping` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (Optional) +- `couponCode` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** (Optional) + +#### Examples ```javascript -GoogleTagManager.setVerboseLoggingEnabled(true); +const transaction = { + id: "T12345", + affiliation: "Google Store - Online", + revenue: 37.39, + tax: 2.85, + shipping: 5.34, + couponCode: "SUMMER2013" +}; ``` diff --git a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java index 82bc3c0d..91d07d7b 100644 --- a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java +++ b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridge.java @@ -1,5 +1,7 @@ package com.idehub.GoogleAnalyticsBridge; +import android.support.annotation.Nullable; + import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; @@ -31,6 +33,10 @@ public String getName() { return "GoogleAnalyticsBridge"; } + synchronized GoogleAnalytics getAnalyticsInstance() { + return GoogleAnalytics.getInstance(getReactApplicationContext()); + } + HashMap mTrackers = new HashMap(); synchronized Tracker getTracker(String trackerId) { @@ -44,10 +50,6 @@ synchronized Tracker getTracker(String trackerId) { return mTrackers.get(trackerId); } - synchronized GoogleAnalytics getAnalyticsInstance() { - return GoogleAnalytics.getInstance(getReactApplicationContext()); - } - @Override public Map getConstants() { final Map constants = new HashMap<>(); @@ -56,207 +58,110 @@ public Map getConstants() { } @ReactMethod - public void trackScreenView(String trackerId, String screenName){ + public void trackScreenView(String trackerId, String screenName, @Nullable ReadableMap payload){ Tracker tracker = getTracker(trackerId); if (tracker != null) { tracker.setScreenName(screenName); - tracker.send(new HitBuilders.ScreenViewBuilder().build()); + HitBuilders.ScreenViewBuilder builder = new HitBuilders.ScreenViewBuilder(); + + if (payload != null) { + GoogleAnalyticsPayload.addScreenViewBuilderPayload(builder, payload); + } + + tracker.send(builder.build()); } } @ReactMethod - public void trackEvent(String trackerId, String category, String action, ReadableMap optionalValues){ + public void trackEvent(String trackerId, String category, String action, @Nullable String label, @Nullable String value, @Nullable ReadableMap payload){ Tracker tracker = getTracker(trackerId); if (tracker != null) { - HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() + HitBuilders.EventBuilder builder = new HitBuilders.EventBuilder() .setCategory(category) .setAction(action); - if (optionalValues != null) + if (label != null) { - if (optionalValues.hasKey("label")) - { - hit.setLabel(optionalValues.getString("label")); - } - if (optionalValues.hasKey("value")) - { - hit.setValue((long) optionalValues.getDouble("value")); - } + builder.setLabel(label); + } + if (value != null) + { + builder.setValue(Long.valueOf(value)); } - tracker.send(hit.build()); + if (payload != null) { + GoogleAnalyticsPayload.addEventBuilderPayload(builder, payload); + } + + tracker.send(builder.build()); } } @ReactMethod - public void trackTiming(String trackerId, String category, Double value, ReadableMap optionalValues){ + public void trackTiming(String trackerId, String category, Double interval, String name, @Nullable String label, @Nullable ReadableMap payload){ Tracker tracker = getTracker(trackerId); if (tracker != null) { - HitBuilders.TimingBuilder hit = new HitBuilders.TimingBuilder() + HitBuilders.TimingBuilder builder = new HitBuilders.TimingBuilder() .setCategory(category) - .setValue(value.longValue()); + .setValue(interval.longValue()) + .setVariable(name); - if (optionalValues != null) + if (label != null) { - if (optionalValues.hasKey("name")) - { - hit.setVariable(optionalValues.getString("name")); - } - if (optionalValues.hasKey("label")) - { - hit.setLabel(optionalValues.getString("label")); - } + builder.setLabel(label); } - tracker.send(hit.build()); - } - } - - @ReactMethod - public void trackPurchaseEvent(String trackerId, ReadableMap product, ReadableMap transaction, String eventCategory, String eventAction){ - Tracker tracker = getTracker(trackerId); - - if (tracker != null) { - - HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() - .addProduct(this.getPurchaseProduct(product)) - .setProductAction(this.getPurchaseTransaction(transaction)) - .setCategory(eventCategory) - .setAction(eventAction); + if (payload != null) + { + GoogleAnalyticsPayload.addTimingBuilderPayload(builder, payload); + } - tracker.send(hit.build()); + tracker.send(builder.build()); } } @ReactMethod - public void trackMultiProductsPurchaseEvent(String trackerId, ReadableArray products, ReadableMap transaction, String eventCategory, String eventAction) { + public void trackException(String trackerId, String error, Boolean fatal, @Nullable ReadableMap payload) + { Tracker tracker = getTracker(trackerId); if (tracker != null) { - HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() - .setProductAction(this.getPurchaseTransaction(transaction)) - .setCategory(eventCategory) - .setAction(eventAction); + HitBuilders.ExceptionBuilder builder = new HitBuilders.ExceptionBuilder() + .setDescription(error) + .setFatal(fatal); - for (int i = 0; i < products.size(); i++) { - ReadableMap product = products.getMap(i); - hit.addProduct(this.getPurchaseProduct(product)); + if (payload != null) { + GoogleAnalyticsPayload.addExceptionBuilderPayload(builder, payload); } - tracker.send(hit.build()); + tracker.send(builder.build()); } } @ReactMethod - public void trackMultiProductsPurchaseEventWithCustomDimensionValues(String trackerId, ReadableArray products, ReadableMap transaction, String eventCategory, String eventAction, ReadableMap dimensionIndexValues) { + public void trackSocialInteraction(String trackerId, String network, String action, String targetUrl, @Nullable ReadableMap payload) + { Tracker tracker = getTracker(trackerId); if (tracker != null) { + HitBuilders.SocialBuilder builder = new HitBuilders.SocialBuilder() + .setNetwork(network) + .setAction(action) + .setTarget(targetUrl); - HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() - .setProductAction(this.getPurchaseTransaction(transaction)) - .setCategory(eventCategory) - .setAction(eventAction); - - for (int i = 0; i < products.size(); i++) { - ReadableMap product = products.getMap(i); - hit.addProduct(this.getPurchaseProduct(product)); - } - - ReadableMapKeySetIterator iterator = dimensionIndexValues.keySetIterator(); - while (iterator.hasNextKey()) { - String dimensionIndex = iterator.nextKey(); - String dimensionValue = dimensionIndexValues.getString(dimensionIndex); - hit.setCustomDimension(Integer.parseInt(dimensionIndex), dimensionValue); + if (payload != null) { + GoogleAnalyticsPayload.addSocialBuilderPayload(builder, payload); } - tracker.send(hit.build()); - } - } - - private ProductAction getPurchaseTransaction(ReadableMap transaction) { - ProductAction productAction = new ProductAction(ProductAction.ACTION_PURCHASE) - .setTransactionId(transaction.getString("id")); - - // Id is the only required value - // https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data - - if(transaction.hasKey("tax")) { - productAction.setTransactionTax(transaction.getDouble("tax")); - } - - if(transaction.hasKey("revenue")) { - productAction.setTransactionRevenue(transaction.getDouble("revenue")); - } - - if(transaction.hasKey("shipping")) { - productAction.setTransactionShipping(transaction.getDouble("shipping")); - } - - if(transaction.hasKey("couponCode")) { - productAction.setTransactionCouponCode(transaction.getString("couponCode")); - } - - if(transaction.hasKey("affiliation")) { - productAction.setTransactionAffiliation(transaction.getString("affiliation")); - } - - return productAction; - } - - private Product getPurchaseProduct(ReadableMap product) { - Product ecommerceProduct = new Product() - .setId(product.getString("id")) - .setName(product.getString("name")); - - // A Product must have a name or id value. All other values are optional and don't need to be set. - // https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce#measuring-impressions - - if(product.hasKey("brand")) { - ecommerceProduct.setBrand(product.getString("brand")); - } - - if(product.hasKey("price")) { - ecommerceProduct.setPrice(product.getDouble("price")); - } - - if(product.hasKey("quantity")) { - ecommerceProduct.setQuantity(product.getInt("quantity")); - } - - if(product.hasKey("variant")) { - ecommerceProduct.setVariant(product.getString("variant")); - } - - if(product.hasKey("category")) { - ecommerceProduct.setCategory(product.getString("category")); - } - - if(product.hasKey("couponCode")) { - ecommerceProduct.setCouponCode(product.getString("couponCode")); - } - - return ecommerceProduct; - } - - @ReactMethod - public void trackException(String trackerId, String error, Boolean fatal) - { - Tracker tracker = getTracker(trackerId); - - if (tracker != null) { - tracker.send(new HitBuilders.ExceptionBuilder() - .setDescription(error) - .setFatal(fatal) - .build()); + tracker.send(builder.build()); } } @@ -305,89 +210,6 @@ public void allowIDFA(String trackerId, Boolean enabled) } } - @ReactMethod - public void trackSocialInteraction(String trackerId, String network, String action, String targetUrl) - { - Tracker tracker = getTracker(trackerId); - - if (tracker != null) { - tracker.send(new HitBuilders.SocialBuilder() - .setNetwork(network) - .setAction(action) - .setTarget(targetUrl) - .build()); - } - } - - @ReactMethod - public void trackScreenViewWithCustomDimensionValues(String trackerId, String screenName, ReadableMap dimensionIndexValues) - { - Tracker tracker = getTracker(trackerId); - - if (tracker != null) - { - tracker.setScreenName(screenName); - HitBuilders.ScreenViewBuilder screenBuilder = new HitBuilders.ScreenViewBuilder(); - ReadableMapKeySetIterator iterator = dimensionIndexValues.keySetIterator(); - while (iterator.hasNextKey()) { - String dimensionIndex = iterator.nextKey(); - String dimensionValue = dimensionIndexValues.getString(dimensionIndex); - screenBuilder.setCustomDimension(Integer.parseInt(dimensionIndex), dimensionValue); - } - tracker.send(screenBuilder.build()); - } - } - - @ReactMethod - public void trackEventWithCustomDimensionValues(String trackerId, String category, String action, ReadableMap optionalValues, ReadableMap dimensionIndexValues) - { - this.trackEventWithCustomDimensionAndMetricValues(trackerId, category, action, optionalValues, dimensionIndexValues, null); - } - - @ReactMethod - public void trackEventWithCustomDimensionAndMetricValues(String trackerId, String category, String action, ReadableMap optionalValues, ReadableMap dimensionIndexValues, ReadableMap metricIndexValues) - { - Tracker tracker = getTracker(trackerId); - - if (tracker != null) - { - HitBuilders.EventBuilder hit = new HitBuilders.EventBuilder() - .setCategory(category) - .setAction(action); - - - if (optionalValues != null) - { - if (optionalValues.hasKey("label")) - { - hit.setLabel(optionalValues.getString("label")); - } - if (optionalValues.hasKey("value")) - { - hit.setValue((long) optionalValues.getDouble("value")); - } - } - - ReadableMapKeySetIterator iterator = dimensionIndexValues.keySetIterator(); - while (iterator.hasNextKey()) { - String dimensionIndex = iterator.nextKey(); - String dimensionValue = dimensionIndexValues.getString(dimensionIndex); - hit.setCustomDimension(Integer.parseInt(dimensionIndex), dimensionValue); - } - - if(metricIndexValues != null){ - ReadableMapKeySetIterator metricIterator = metricIndexValues.keySetIterator(); - while (metricIterator.hasNextKey()) { - String metricIndex = metricIterator.nextKey(); - int metricValue = metricIndexValues.getInt(metricIndex); - hit.setCustomMetric(Integer.parseInt(metricIndex), metricValue); - } - } - - tracker.send(hit.build()); - } - } - @ReactMethod public void setSamplingRate(String trackerId, Double sampleRate){ Tracker tracker = getTracker(trackerId); @@ -398,37 +220,6 @@ public void setSamplingRate(String trackerId, Double sampleRate){ } } - @ReactMethod - public void setDryRun(Boolean enabled){ - GoogleAnalytics analytics = getAnalyticsInstance(); - - if (analytics != null) - { - analytics.setDryRun(enabled); - } - } - - @ReactMethod - public void setDispatchInterval(Integer intervalInSeconds){ - GoogleAnalytics analytics = getAnalyticsInstance(); - - if (analytics != null) - { - analytics.setLocalDispatchPeriod(intervalInSeconds); - } - } - - @ReactMethod - public void setTrackUncaughtExceptions(String trackerId, Boolean enabled){ - Tracker tracker = getTracker(trackerId); - - if (tracker != null) - { - tracker.enableExceptionReporting(enabled); - } - } - - @ReactMethod public void setAnonymizeIp(String trackerId, Boolean enabled){ Tracker tracker = getTracker(trackerId); @@ -439,16 +230,6 @@ public void setAnonymizeIp(String trackerId, Boolean enabled){ } } - @ReactMethod - public void setOptOut(Boolean enabled){ - GoogleAnalytics analytics = getAnalyticsInstance(); - - if (analytics != null) - { - analytics.setAppOptOut(enabled); - } - } - @ReactMethod public void setAppName(String trackerId, String appName){ Tracker tracker = getTracker(trackerId); @@ -478,16 +259,14 @@ public void setCurrency(String trackerId, String currencyCode) } } + // A special case. For iOS this is set on all trackers. On Android it is on each tracker. @ReactMethod - public void trackCampaignFromUrl(String trackerId, String urlString){ + public void setTrackUncaughtExceptions(String trackerId, Boolean enabled){ Tracker tracker = getTracker(trackerId); if (tracker != null) { - tracker.setScreenName("Init With Campaign"); - tracker.send(new HitBuilders.ScreenViewBuilder() - .setCampaignParamsFromUrl(urlString) - .build()); + tracker.enableExceptionReporting(enabled); } } diff --git a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridgePackage.java b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridgePackage.java index e00eda62..708bd625 100644 --- a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridgePackage.java +++ b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsBridgePackage.java @@ -35,8 +35,9 @@ public List createNativeModules( List modules = new ArrayList<>(); modules.add(new GoogleAnalyticsBridge(reactContext, _trackingId)); + modules.add(new GoogleAnalyticsSettings(reactContext)); modules.add(new GoogleTagManagerBridge(reactContext, _containerHolder)); - + return modules; } diff --git a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsPayload.java b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsPayload.java new file mode 100644 index 00000000..3441dd35 --- /dev/null +++ b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsPayload.java @@ -0,0 +1,426 @@ +package com.idehub.GoogleAnalyticsBridge; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableMapKeySetIterator; +import com.facebook.react.bridge.ReadableType; +import com.google.android.gms.analytics.HitBuilders; +import com.google.android.gms.analytics.ecommerce.Product; +import com.google.android.gms.analytics.ecommerce.ProductAction; + +public class GoogleAnalyticsPayload { + private static abstract class InternalBuilder { + public abstract void setProduct(final Product product); + public abstract void setImpressionProduct(final Product product, final String impressionList); + public abstract void setProductAction(final ProductAction productAction); + public abstract void setCustomDimension(final Integer index, final String value); + public abstract void setCustomMetric(final Integer index, final Integer value); + public abstract void setUtmCampaignUrl(final String utmCampaignUrl); + public abstract void setSessionState(final String sessionState); + + public void build(ReadableMap payload) { + buildProducts(payload); + buildImpressionProducts(payload); + buildProductAction(payload); + buildCustomDimensions(payload); + buildCustomMetrics(payload); + buildUtmCampaignUrl(payload); + buildSessionState(payload); + } + + private void buildProducts(ReadableMap payload) { + if (payload.hasKey("products")) { + ReadableArray products = payload.getArray("products"); + for (int i = 0; i < products.size(); i++) { + ReadableMap product = products.getMap(i); + Product ecommerceProduct = getEcommerceProduct(product); + this.setProduct(ecommerceProduct); + } + } + } + + private void buildImpressionProducts(ReadableMap payload) { + if (payload.hasKey("impressionProducts")) { + String impressionList = payload.getString("impressionList"); + ReadableArray impressionProducts = payload.getArray("impressionProducts"); + for (int i = 0; i < impressionProducts.size(); i++) { + ReadableMap product = impressionProducts.getMap(i); + Product ecommerceProduct = getEcommerceProduct(product); + this.setImpressionProduct(ecommerceProduct, impressionList); + } + } + } + + private void buildProductAction(ReadableMap payload) { + if (payload.hasKey("productAction")) { + ReadableMap productAction = payload.getMap("productAction"); + this.setProductAction(getEcommerceProductAction(productAction)); + } + } + + private void buildCustomDimensions(ReadableMap payload) { + if (payload.hasKey("customDimensions")) { + ReadableMap customDimensions = payload.getMap("customDimensions"); + ReadableMapKeySetIterator iterator = customDimensions.keySetIterator(); + while (iterator.hasNextKey()) { + String dimensionIndex = iterator.nextKey(); + ReadableType type = customDimensions.getType(dimensionIndex); + String value = null; + switch (type) { + case String: + value = customDimensions.getString(dimensionIndex); + break; + case Number: + value = Double.toString(customDimensions.getDouble(dimensionIndex)); + break; + case Boolean: + value = Boolean.toString(customDimensions.getBoolean(dimensionIndex)); + break; + } + if (value != null) { + this.setCustomDimension(Integer.parseInt(dimensionIndex), value); + } + } + + } + } + + private void buildCustomMetrics(ReadableMap payload) { + if (payload.hasKey("customMetrics")) { + ReadableMap customMetrics = payload.getMap("customMetrics"); + ReadableMapKeySetIterator iterator = customMetrics.keySetIterator(); + while (iterator.hasNextKey()) { + String index = iterator.nextKey(); + this.setCustomMetric(Integer.parseInt(index), customMetrics.getInt(index)); + } + + } + } + + private void buildUtmCampaignUrl(ReadableMap payload) { + if (payload.hasKey("utmCampaignUrl")) { + String utmCampaignUrl = payload.getString("utmCampaignUrl"); + this.setUtmCampaignUrl(utmCampaignUrl); + } + } + + private void buildSessionState(ReadableMap payload) { + if (payload.hasKey("session")) { + String sessionState = payload.getString("session"); + this.setSessionState(sessionState); + } + } + } + + public static void addScreenViewBuilderPayload(final HitBuilders.ScreenViewBuilder builder, ReadableMap payload) { + InternalBuilder internalBuilder = new InternalBuilder() { + @Override + public void setProduct(final Product product) { + builder.addProduct(product); + } + + @Override + public void setImpressionProduct(final Product product, final String impressionList) { + builder.addImpression(product, impressionList); + } + + @Override + public void setProductAction(ProductAction productAction) { + builder.setProductAction(productAction); + } + + @Override + public void setCustomDimension(Integer index, String value) { + builder.setCustomDimension(index, value); + } + + @Override + public void setCustomMetric(Integer index, Integer value) { + builder.setCustomMetric(index, value); + } + + @Override + public void setUtmCampaignUrl(String utmCampaignUrl) { + builder.setCampaignParamsFromUrl(utmCampaignUrl); + } + + @Override + public void setSessionState(String sessionState) { + builder.set("&sc", sessionState); + } + }; + + internalBuilder.build(payload); + } + + public static void addEventBuilderPayload(final HitBuilders.EventBuilder builder, ReadableMap payload) { + InternalBuilder internalBuilder = new InternalBuilder() { + @Override + public void setProduct(final Product product) { + builder.addProduct(product); + } + + @Override + public void setImpressionProduct(final Product product, final String impressionList) { + builder.addImpression(product, impressionList); + } + + @Override + public void setProductAction(ProductAction productAction) { + builder.setProductAction(productAction); + } + + @Override + public void setCustomDimension(Integer index, String value) { + builder.setCustomDimension(index, value); + } + + @Override + public void setCustomMetric(Integer index, Integer value) { + builder.setCustomMetric(index, value); + } + + @Override + public void setUtmCampaignUrl(String utmCampaignUrl) { + builder.setCampaignParamsFromUrl(utmCampaignUrl); + } + + @Override + public void setSessionState(String sessionState) { + builder.set("&sc", sessionState); + } + }; + + internalBuilder.build(payload); + } + + public static void addTimingBuilderPayload(final HitBuilders.TimingBuilder builder, ReadableMap payload) { + InternalBuilder internalBuilder = new InternalBuilder() { + @Override + public void setProduct(final Product product) { + builder.addProduct(product); + } + + @Override + public void setImpressionProduct(final Product product, final String impressionList) { + builder.addImpression(product, impressionList); + } + + @Override + public void setProductAction(ProductAction productAction) { + builder.setProductAction(productAction); + } + + @Override + public void setCustomDimension(Integer index, String value) { + builder.setCustomDimension(index, value); + } + + @Override + public void setCustomMetric(Integer index, Integer value) { + builder.setCustomMetric(index, value); + } + + @Override + public void setUtmCampaignUrl(String utmCampaignUrl) { + builder.setCampaignParamsFromUrl(utmCampaignUrl); + } + + @Override + public void setSessionState(String sessionState) { + builder.set("&sc", sessionState); + } + }; + + internalBuilder.build(payload); + } + + public static void addExceptionBuilderPayload(final HitBuilders.ExceptionBuilder builder, ReadableMap payload) { + InternalBuilder internalBuilder = new InternalBuilder() { + @Override + public void setProduct(final Product product) { + builder.addProduct(product); + } + + @Override + public void setImpressionProduct(final Product product, final String impressionList) { + builder.addImpression(product, impressionList); + } + + @Override + public void setProductAction(ProductAction productAction) { + builder.setProductAction(productAction); + } + + @Override + public void setCustomDimension(Integer index, String value) { + builder.setCustomDimension(index, value); + } + + @Override + public void setCustomMetric(Integer index, Integer value) { + builder.setCustomMetric(index, value); + } + + @Override + public void setUtmCampaignUrl(String utmCampaignUrl) { + builder.setCampaignParamsFromUrl(utmCampaignUrl); + } + + @Override + public void setSessionState(String sessionState) { + builder.set("&sc", sessionState); + } + }; + + internalBuilder.build(payload); + } + + public static void addSocialBuilderPayload(final HitBuilders.SocialBuilder builder, ReadableMap payload) { + InternalBuilder internalBuilder = new InternalBuilder() { + @Override + public void setProduct(final Product product) { + builder.addProduct(product); + } + + @Override + public void setImpressionProduct(final Product product, final String impressionList) { + builder.addImpression(product, impressionList); + } + + @Override + public void setProductAction(ProductAction productAction) { + builder.setProductAction(productAction); + } + + @Override + public void setCustomDimension(Integer index, String value) { + builder.setCustomDimension(index, value); + } + + @Override + public void setCustomMetric(Integer index, Integer value) { + builder.setCustomMetric(index, value); + } + + @Override + public void setUtmCampaignUrl(String utmCampaignUrl) { + builder.setCampaignParamsFromUrl(utmCampaignUrl); + } + + @Override + public void setSessionState(String sessionState) { + builder.set("&sc", sessionState); + } + }; + + internalBuilder.build(payload); + } + + private static Product getEcommerceProduct(ReadableMap product) { + Product ecommerceProduct = new Product() + .setId(product.getString("id")) + .setName(product.getString("name")); + + // A Product must have a name or id value. All other values are optional and don't need to be set. + // https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce#measuring-impressions + + if (product.hasKey("brand")) { + ecommerceProduct.setBrand(product.getString("brand")); + } + + if (product.hasKey("price")) { + ecommerceProduct.setPrice(product.getDouble("price")); + } + + if (product.hasKey("quantity")) { + ecommerceProduct.setQuantity(product.getInt("quantity")); + } + + if (product.hasKey("variant")) { + ecommerceProduct.setVariant(product.getString("variant")); + } + + if (product.hasKey("category")) { + ecommerceProduct.setCategory(product.getString("category")); + } + + if (product.hasKey("couponCode")) { + ecommerceProduct.setCouponCode(product.getString("couponCode")); + } + + return ecommerceProduct; + } + + private static ProductAction getEcommerceProductAction(ReadableMap productActionMap) { + ProductAction productAction = new ProductAction(mapProductAction(productActionMap.getInt("action"))); + + if (productActionMap.hasKey("transaction")) { + ReadableMap transaction = productActionMap.getMap("transaction"); + productAction.setTransactionId(transaction.getString("id")); + + // Id is the only required value + // https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#action-data + + if (transaction.hasKey("tax")) { + productAction.setTransactionTax(transaction.getDouble("tax")); + } + + if (transaction.hasKey("revenue")) { + productAction.setTransactionRevenue(transaction.getDouble("revenue")); + } + + if (transaction.hasKey("shipping")) { + productAction.setTransactionShipping(transaction.getDouble("shipping")); + } + + if (transaction.hasKey("couponCode")) { + productAction.setTransactionCouponCode(transaction.getString("couponCode")); + } + + if (transaction.hasKey("affiliation")) { + productAction.setTransactionAffiliation(transaction.getString("affiliation")); + } + } + + if (productActionMap.hasKey("checkoutStep")) { + productAction.setCheckoutStep(productActionMap.getInt("checkoutStep")); + } + + if (productActionMap.hasKey("checkoutOption")) { + productAction.setCheckoutOptions(productActionMap.getString("checkoutOption")); + } + + if (productActionMap.hasKey("productActionList")) { + productAction.setProductActionList(productActionMap.getString("productActionList")); + } + + if (productActionMap.hasKey("productListSource")) { + productAction.setProductListSource(productActionMap.getString("productListSource")); + } + + return productAction; + } + + private static String mapProductAction(Integer action) { + switch (action) { + case 1: + return ProductAction.ACTION_CLICK; + case 2: + return ProductAction.ACTION_DETAIL; + case 3: + return ProductAction.ACTION_ADD; + case 4: + return ProductAction.ACTION_REMOVE; + case 5: + return ProductAction.ACTION_CHECKOUT; + case 6: + return ProductAction.ACTION_CHECKOUT_OPTION; + case 7: + default: + return ProductAction.ACTION_PURCHASE; + case 8: + return ProductAction.ACTION_REFUND; + } + } +} \ No newline at end of file diff --git a/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsSettings.java b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsSettings.java new file mode 100644 index 00000000..fc6e8c72 --- /dev/null +++ b/android/src/main/java/com/idehub/GoogleAnalyticsBridge/GoogleAnalyticsSettings.java @@ -0,0 +1,50 @@ +package com.idehub.GoogleAnalyticsBridge; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.google.android.gms.analytics.GoogleAnalytics; + +public class GoogleAnalyticsSettings extends ReactContextBaseJavaModule { + + public GoogleAnalyticsSettings(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { return "GoogleAnalyticsSettings"; } + + synchronized GoogleAnalytics getAnalyticsInstance() { + return GoogleAnalytics.getInstance(getReactApplicationContext()); + } + + @ReactMethod + public void setDryRun(Boolean enabled){ + GoogleAnalytics analytics = getAnalyticsInstance(); + + if (analytics != null) + { + analytics.setDryRun(enabled); + } + } + + @ReactMethod + public void setDispatchInterval(Integer intervalInSeconds){ + GoogleAnalytics analytics = getAnalyticsInstance(); + + if (analytics != null) + { + analytics.setLocalDispatchPeriod(intervalInSeconds); + } + } + + @ReactMethod + public void setOptOut(Boolean enabled){ + GoogleAnalytics analytics = getAnalyticsInstance(); + + if (analytics != null) + { + analytics.setAppOptOut(enabled); + } + } +} diff --git a/example/index.ios.js b/example/index.ios.js new file mode 100644 index 00000000..80e051dd --- /dev/null +++ b/example/index.ios.js @@ -0,0 +1,163 @@ +/** + * Sample React Native App + * https://github.com/facebook/react-native + * @flow + */ + +import React, { Component } from "react"; +import { AppRegistry, StyleSheet, Text, View } from "react-native"; + +import { + GoogleAnalyticsTracker, + GoogleAnalyticsSettings, + GoogleTagManager +} from "react-native-google-analytics-bridge"; +export default class example extends Component { + render() { + // Recommend you set this much higher in real app! 30 seconds+ + // GoogleAnalyticsSettings has static methods and is applied + // for all trackers + GoogleAnalyticsSettings.setDispatchInterval(2); + GoogleAnalyticsSettings.setDryRun(true); + //GoogleAnalyticsSettings.setOptOut(true); + + // The tracker is constructed + let tracker = new GoogleAnalyticsTracker("UA-12345-2"); + // You can have multiple trackers + let tracker2 = new GoogleAnalyticsTracker("UA-12345-3", { demo: 1 }); + + tracker2.trackScreenViewWithCustomDimensionValues("Home", { demo: "Yes" }); + + tracker.trackEvent("testcategory", "Hello iOS"); + + tracker.trackScreenView("Home"); + + tracker.trackEvent("testcategory", "Hello iOS", { + label: "notdry", + value: 1 + }); + + tracker.newTrackEvent("testcategory", "Hello iOS"); + + tracker.trackTiming("testcategory", 13000, { + label: "notdry", + name: "testduration" + }); + + tracker.setTrackUncaughtExceptions(true); + tracker.trackPurchaseEvent( + { + id: "P12345", + name: "Android Warhol T-Shirt", + category: "Apparel/T-Shirts", + brand: "Apple", + variant: "Black", + price: 29.2, + quantity: 1, + couponCode: "APPARELSALE" + }, + { + id: "T12345", + affiliation: "Apple Store - Online", + revenue: 37.39, + tax: 2.85, + shipping: 5.34, + couponCode: "SUMMER2013" + } + ); + + tracker.trackMultiProductsPurchaseEvent( + [ + { + id: "2224711", + name: "Top Ilem", + category: "Women/Kleidung/Tops/Spitzentops", + brand: "THE label", + variant: "rot", + price: 39.9, + quantity: 1 + }, + { + id: "2224706", + name: "Shorts Isto", + category: "Women/Kleidung/Hosen/Shirts", + brand: "THE label", + variant: "grau", + price: 59.9, + quantity: 1 + } + ], + { + id: "T12345", + affiliation: "THE label Shop", + revenue: 83.87, + tax: 15.93, + shipping: 0.0, + couponCode: "SUMMER2016" + } + ); + + tracker.trackException("This is an error message", false); + + tracker.trackSocialInteraction("Twitter", "Post"); + + tracker.setUser("12345678"); + + tracker.allowIDFA(true); + + tracker.setAnonymizeIp(true); + + GoogleTagManager.openContainerWithId("GT-NZT48") + .then(() => { + return GoogleTagManager.stringForKey("pack"); + }) + .then(str => { + console.log("Str: ", str); + return GoogleTagManager.boolForKey("wat"); + }) + .then(wat => { + console.log("Wat: ", wat); + return GoogleTagManager.doubleForKey("orly"); + }) + .then(orly => { + console.log("Orly: ", orly); + }) + .catch(err => { + console.log(err); + }); + + return ( + + Welcome to React Native! + + To get started, edit index.ios.js + + + Press Cmd+R to reload,{"\n"} + Cmd+D or shake for dev menu + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "center", + alignItems: "center", + backgroundColor: "#F5FCFF" + }, + welcome: { + fontSize: 20, + textAlign: "center", + margin: 10 + }, + instructions: { + textAlign: "center", + color: "#333333", + marginBottom: 5 + } +}); + +AppRegistry.registerComponent("example", () => example); diff --git a/example/jsconfig.json b/example/jsconfig.json new file mode 100644 index 00000000..c98b6e08 --- /dev/null +++ b/example/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/example/yarn.lock b/example/yarn.lock index 027d8a19..9d1e2122 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2,399 +2,399 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0-beta.49", "@babel/code-frame@^7.0.0-beta.35": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz#becd805482734440c9d137e46d77340e64d7f51b" +"@babel/code-frame@7.0.0-beta.51", "@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz#bd71d9b192af978df915829d39d4094456439a0c" dependencies: - "@babel/highlight" "7.0.0-beta.49" + "@babel/highlight" "7.0.0-beta.51" "@babel/core@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.49.tgz#73de2081dd652489489f0cb4aa97829a1133314e" - dependencies: - "@babel/code-frame" "7.0.0-beta.49" - "@babel/generator" "7.0.0-beta.49" - "@babel/helpers" "7.0.0-beta.49" - "@babel/parser" "7.0.0-beta.49" - "@babel/template" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.51.tgz#0e54bd6b638736b2ae593c31a47f0969e2b2b96d" + dependencies: + "@babel/code-frame" "7.0.0-beta.51" + "@babel/generator" "7.0.0-beta.51" + "@babel/helpers" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" convert-source-map "^1.1.0" debug "^3.1.0" json5 "^0.5.0" lodash "^4.17.5" - micromatch "^2.3.11" + micromatch "^3.1.10" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@7.0.0-beta.49", "@babel/generator@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.49.tgz#e9cffda913996accec793bbc25ab91bc19d0bf7a" +"@babel/generator@7.0.0-beta.51", "@babel/generator@^7.0.0-beta": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.51.tgz#6c7575ffde761d07485e04baedc0392c6d9e30f6" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" jsesc "^2.5.1" lodash "^4.17.5" source-map "^0.5.0" trim-right "^1.0.1" -"@babel/helper-annotate-as-pure@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.49.tgz#7d9005d54fe7ad6cb876790251e75575419186e9" +"@babel/helper-annotate-as-pure@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.51.tgz#38cf7920bf5f338a227f754e286b6fbadee04b58" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.49.tgz#c62dd5042b54a590d5e71e6020c46b91d6c6c875" +"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.51.tgz#2133fffe3e2f71591e42147b947291ca2ad39237" dependencies: - "@babel/helper-explode-assignable-expression" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-explode-assignable-expression" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-builder-react-jsx@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.49.tgz#e6c35f8c88e90093139fa7b3027d05cceb47f43d" +"@babel/helper-builder-react-jsx@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.51.tgz#86c72d6683bd2597c938a12153a6e480bf140128" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" esutils "^2.0.0" -"@babel/helper-call-delegate@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.49.tgz#4b5d41782a683d5dc6497834a32310a8d02a3af9" +"@babel/helper-call-delegate@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.51.tgz#04ed727c97cf05bcb2fd644837331ab15d63c819" dependencies: - "@babel/helper-hoist-variables" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-hoist-variables" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-define-map@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.49.tgz#4ea067aa720937240df395cd073c24fcad9c2b3b" +"@babel/helper-define-map@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.51.tgz#d88c64737e948c713f9f1153338e8415fee40b11" dependencies: - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" lodash "^4.17.5" -"@babel/helper-explode-assignable-expression@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.49.tgz#2bfb95df7ec130735bf655e44a217a70d3b13e93" +"@babel/helper-explode-assignable-expression@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.51.tgz#9875332ad8b5d5c982fa481cb82b731703f2cd2d" dependencies: - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-function-name@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.49.tgz#a25c1119b9f035278670126e0225c03041c8de32" +"@babel/helper-function-name@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz#21b4874a227cf99ecafcc30a90302da5a2640561" dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.49" - "@babel/template" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-get-function-arity" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-get-function-arity@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.49.tgz#cf5023f32d2ad92d087374939cec0951bcb51441" +"@babel/helper-get-function-arity@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz#3281b2d045af95c172ce91b20825d85ea4676411" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-hoist-variables@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.49.tgz#d9740651c93bb4fa79c1b6bac634051fc4d03ff5" +"@babel/helper-hoist-variables@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.51.tgz#5d7ebc8596567b644fc989912c3a3ef98be058fc" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-member-expression-to-functions@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.49.tgz#2f642b003d45155e0a9e7a4ad0e688d91bbc1583" +"@babel/helper-member-expression-to-functions@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-beta.51.tgz#2a42536574176588806e602eb17a52d323f82870" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-module-imports@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.49.tgz#41d7d59891016c493432a46f7464446552890c75" +"@babel/helper-module-imports@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.51.tgz#ce00428045fbb7d5ebc0ea7bf835789f15366ab2" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" lodash "^4.17.5" -"@babel/helper-module-transforms@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.49.tgz#fc660bda9d6497412e18776a71aed9a9e2e5f7ad" +"@babel/helper-module-transforms@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.51.tgz#13af0c8ee41f277743c8fc43d444315db2326f73" dependencies: - "@babel/helper-module-imports" "7.0.0-beta.49" - "@babel/helper-simple-access" "7.0.0-beta.49" - "@babel/helper-split-export-declaration" "7.0.0-beta.49" - "@babel/template" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-module-imports" "7.0.0-beta.51" + "@babel/helper-simple-access" "7.0.0-beta.51" + "@babel/helper-split-export-declaration" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" lodash "^4.17.5" -"@babel/helper-optimise-call-expression@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.49.tgz#a98b43c3a6c54bef48f87b10dc4568dec0b41bf7" +"@babel/helper-optimise-call-expression@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.51.tgz#21f2158ef083a123ce1e04665b5bb84f370080d7" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-plugin-utils@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.49.tgz#0e9fcbb834f878bb365d2a8ea90eee21ba3ccd23" +"@babel/helper-plugin-utils@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.51.tgz#0f6a5f2b6d1c6444413f8fab60940d79b63c2031" "@babel/helper-remap-async-to-generator@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.49.tgz#b3fdaab412784d7e8657bacab286923efc9498b8" - dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-beta.49" - "@babel/helper-wrap-function" "7.0.0-beta.49" - "@babel/template" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" - -"@babel/helper-replace-supers@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.49.tgz#e7444c718057f6a0a3645caf8e78fb546ffb0d9f" - dependencies: - "@babel/helper-member-expression-to-functions" "7.0.0-beta.49" - "@babel/helper-optimise-call-expression" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" - -"@babel/helper-simple-access@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.49.tgz#97a41e2789a9bf8a6c30536a258b79e7444c5d82" - dependencies: - "@babel/template" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.51.tgz#0edc57e05dcb5dde2a0b6ee6f8d0261982def25f" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.51" + "@babel/helper-wrap-function" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + +"@babel/helper-replace-supers@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.51.tgz#279a61afb849476c6cc70d5519f83df4a74ffa6f" + dependencies: + "@babel/helper-member-expression-to-functions" "7.0.0-beta.51" + "@babel/helper-optimise-call-expression" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + +"@babel/helper-simple-access@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.51.tgz#c9d7fecd84a181d50a3afcc422fc94a968be3050" + dependencies: + "@babel/template" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" lodash "^4.17.5" -"@babel/helper-split-export-declaration@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.49.tgz#40d78eda0968d011b1c52866e5746cfb23e57548" +"@babel/helper-split-export-declaration@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz#8a6c3f66c4d265352fc077484f9f6e80a51ab978" dependencies: - "@babel/types" "7.0.0-beta.49" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-wrap-function@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.49.tgz#385591460b4d93ef96ee3819539c0cdc9bbd4758" +"@babel/helper-wrap-function@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.51.tgz#6c516fb044109964ee031c22500a830313862fb1" dependencies: - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/template" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helpers@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.49.tgz#054d84032d4e94286a80586500068e41005a51d0" +"@babel/helpers@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.51.tgz#95272be2ab4634d6820425f8925031a928918397" dependencies: - "@babel/template" "7.0.0-beta.49" - "@babel/traverse" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/highlight@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.49.tgz#96bdc6b43e13482012ba6691b1018492d39622cc" +"@babel/highlight@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.51.tgz#e8844ae25a1595ccfd42b89623b4376ca06d225d" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/parser@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.49.tgz#944d0c5ba2812bb159edbd226743afd265179bdc" +"@babel/parser@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.51.tgz#27cec2df409df60af58270ed8f6aa55409ea86f6" "@babel/plugin-external-helpers@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0-beta.49.tgz#c67ffa9e23d7063810b0d4304857bf5c16f8a35b" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0-beta.51.tgz#b4783bcf9152d15942cbe0f0bca261b849d35c98" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-proposal-class-properties@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.49.tgz#527e90af75d23fd5e3bae1a218dc0a6d9236b5f1" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.51.tgz#b5c662f862a30ace94fc48477837b1d255fa38df" dependencies: - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/helper-member-expression-to-functions" "7.0.0-beta.49" - "@babel/helper-optimise-call-expression" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/helper-replace-supers" "7.0.0-beta.49" - "@babel/plugin-syntax-class-properties" "7.0.0-beta.49" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-member-expression-to-functions" "7.0.0-beta.51" + "@babel/helper-optimise-call-expression" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/helper-replace-supers" "7.0.0-beta.51" + "@babel/plugin-syntax-class-properties" "7.0.0-beta.51" "@babel/plugin-proposal-object-rest-spread@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.49.tgz#6d0cd60f7a7bd7c444a371c4e9470bff02f5777c" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.51.tgz#5bc469e5e6d1b84a5d6046b59e90ca016c2086d6" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.51" -"@babel/plugin-syntax-class-properties@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.49.tgz#6a14fa47ceaa32b53e14e6648326e52dab306904" +"@babel/plugin-syntax-class-properties@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.51.tgz#f0cbf6f22a879c593a07e8e141c908e087701e91" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-syntax-dynamic-import@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.49.tgz#f0af7ac6b53676a496093d4a6e2a2ec655c07b78" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.51.tgz#9c0aeef57d0678e3726db171aa73e474a25de7f2" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" -"@babel/plugin-syntax-flow@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.49.tgz#5b3f0b65ca9660534535643b82530fb1d58e63ee" +"@babel/plugin-syntax-flow@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.51.tgz#de0883134406f90f958b64073e9749880229de56" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" -"@babel/plugin-syntax-jsx@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.49.tgz#15b832504b49f116f9c484e8e40a5e17c542ed13" +"@babel/plugin-syntax-jsx@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.51.tgz#f672a3371c6ba3fe53bffd2e8ab5dc40495382cf" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" -"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.49": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.49.tgz#4784b3880823ff12e742c26b41e9857f701d639e" +"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.51.tgz#6d57a119c1f064c458e45bad45bef0a83ed10c00" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-arrow-functions@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.49.tgz#dd3845b63c683d187d5186ee0e882c4046c4f0e3" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.51.tgz#29b9db6e38688a06ec5c25639996d89a5ebfdbe3" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-block-scoping@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.49.tgz#dd5a9ddd986775c8b20cf5b61065afb3dd9eaac9" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.51.tgz#be555c79f0da4eb168a7fe16d787a9a7173701e0" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" lodash "^4.17.5" "@babel/plugin-transform-classes@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.49.tgz#5342471d2e6a3337332ea246b46c0bddf5fc544d" - dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-beta.49" - "@babel/helper-define-map" "7.0.0-beta.49" - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/helper-optimise-call-expression" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/helper-replace-supers" "7.0.0-beta.49" - "@babel/helper-split-export-declaration" "7.0.0-beta.49" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.51.tgz#043f31fb6327664a32d8ba65de15799efdc65da0" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.51" + "@babel/helper-define-map" "7.0.0-beta.51" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-optimise-call-expression" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/helper-replace-supers" "7.0.0-beta.51" + "@babel/helper-split-export-declaration" "7.0.0-beta.51" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.49.tgz#b8259d174bf07ab4b56566562b46ee6520c3dfd2" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.51.tgz#8c72a1ab3e0767034ff9e6732d2581c23c032efe" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-destructuring@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.49.tgz#4366392c9c82d1231056c1d0029438a60d362b82" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.51.tgz#d5d454e574c7ef33ee49e918b048afb29be935f6" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-exponentiation-operator@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.49.tgz#457b2d09004794684aa6e1b04015080b80a08a14" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.51.tgz#04b4e3e40b3701112dd6eda39625132757881fd4" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-flow-strip-types@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.49.tgz#f02a26528e94b2c1d11d9573b63ee5782d4f2af9" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.51.tgz#67d434459f7a7b26a9f2a6855bc12e67894e47a6" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/plugin-syntax-flow" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/plugin-syntax-flow" "7.0.0-beta.51" "@babel/plugin-transform-for-of@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.49.tgz#3ec72726bf1d89a0d4d511be7a9549066f57aade" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.51.tgz#44f476b06c4035517a8403a2624fb164c4371455" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-function-name@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.49.tgz#af39f60e7aefce9b25eb4adcedd04d50866ce218" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.51.tgz#70653c360b53254246f4659ec450b0c0a56d86aa" dependencies: - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-literals@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.49.tgz#07c838254d65e6867e86513eb0f22d5f26b0a56a" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.51.tgz#45b07a94223cfa226701a79460b42b32df1dec05" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-modules-commonjs@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.49.tgz#09fb345d5927c2ba3bd89e7cdb13a55067ed39a0" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.51.tgz#4038f9e15244e10900cb89f5b796d050f1eb195b" dependencies: - "@babel/helper-module-transforms" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/helper-simple-access" "7.0.0-beta.49" + "@babel/helper-module-transforms" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/helper-simple-access" "7.0.0-beta.51" "@babel/plugin-transform-object-assign@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0-beta.49.tgz#031bf5cfeb976e62e8a91fc16ffb3a6448c410cd" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0-beta.51.tgz#0d56a3e2d8b06d9de6c6519835a3e028448e13b8" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-parameters@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.49.tgz#1cad71a2a33281e5efbb1a4623a964c073ce9a2d" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.51.tgz#990195b1dfdb1bcc94906f3034951089ed1edd4e" dependencies: - "@babel/helper-call-delegate" "7.0.0-beta.49" - "@babel/helper-get-function-arity" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-call-delegate" "7.0.0-beta.51" + "@babel/helper-get-function-arity" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-react-display-name@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.49.tgz#242a006bf4122a93b273f69dfe6c394a0fcec638" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.51.tgz#1b48bd34dfa9087252c8707d29bd1df2e8821cbe" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-react-jsx-source@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.49.tgz#05bb7429b6dd44cbdca69585481347a809caa8ca" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.51.tgz#6999dc491c8b4602efb4d0bd1bafc936ad696ecf" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/plugin-syntax-jsx" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/plugin-syntax-jsx" "7.0.0-beta.51" "@babel/plugin-transform-react-jsx@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.49.tgz#0f2789fde305c3c14151848f8514a2af1441af58" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.51.tgz#7af8498518b83906405438370198808ca6e63b10" dependencies: - "@babel/helper-builder-react-jsx" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" - "@babel/plugin-syntax-jsx" "7.0.0-beta.49" + "@babel/helper-builder-react-jsx" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" + "@babel/plugin-syntax-jsx" "7.0.0-beta.51" "@babel/plugin-transform-regenerator@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.49.tgz#d4ed7967033f4f5b49363c203503899b8357cae2" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.51.tgz#536f0d599d2753dca0a2be8a65e2c244a7b5612b" dependencies: - regenerator-transform "^0.12.3" + regenerator-transform "^0.12.4" "@babel/plugin-transform-shorthand-properties@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.49.tgz#49f134dbde4f655834c21524e9e61a58d4e17900" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.51.tgz#ddbc0b1ae1ddb3bcfe6969f2c968103f11e32bd9" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-spread@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.49.tgz#6abab05fc0cca829aaf9e2a85044b79763e681ca" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.51.tgz#100129bc8d7dcf4bc79adcd6129a4214259d8a50" dependencies: - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/plugin-transform-template-literals@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.49.tgz#e609aed6b8fcc7e1ebccacf22138a647202940a2" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.51.tgz#2d0595f56461d4345ba35c38d73033f87ecbbbc8" dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-beta.49" - "@babel/helper-plugin-utils" "7.0.0-beta.49" + "@babel/helper-annotate-as-pure" "7.0.0-beta.51" + "@babel/helper-plugin-utils" "7.0.0-beta.51" "@babel/register@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0-beta.49.tgz#57e823a5062e3ddd25548398e9f5077c17991f08" + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0-beta.51.tgz#31a6d27f124cc7a2a0a603b65d23d5644b979aa0" dependencies: - core-js "^2.5.6" + core-js "^2.5.7" find-cache-dir "^1.0.0" home-or-tmp "^3.0.0" lodash "^4.17.5" @@ -402,33 +402,33 @@ pirates "^3.0.1" source-map-support "^0.4.2" -"@babel/template@7.0.0-beta.49", "@babel/template@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.49.tgz#e38abe8217cb9793f461a5306d7ad745d83e1d27" +"@babel/template@7.0.0-beta.51", "@babel/template@^7.0.0-beta": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.51.tgz#9602a40aebcf357ae9677e2532ef5fc810f5fbff" dependencies: - "@babel/code-frame" "7.0.0-beta.49" - "@babel/parser" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/code-frame" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" lodash "^4.17.5" -"@babel/traverse@7.0.0-beta.49", "@babel/traverse@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.49.tgz#4f2a73682a18334ed6625d100a8d27319f7c2d68" +"@babel/traverse@7.0.0-beta.51", "@babel/traverse@^7.0.0-beta": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.51.tgz#981daf2cec347a6231d3aa1d9e1803b03aaaa4a8" dependencies: - "@babel/code-frame" "7.0.0-beta.49" - "@babel/generator" "7.0.0-beta.49" - "@babel/helper-function-name" "7.0.0-beta.49" - "@babel/helper-split-export-declaration" "7.0.0-beta.49" - "@babel/parser" "7.0.0-beta.49" - "@babel/types" "7.0.0-beta.49" + "@babel/code-frame" "7.0.0-beta.51" + "@babel/generator" "7.0.0-beta.51" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-split-export-declaration" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" debug "^3.1.0" globals "^11.1.0" invariant "^2.2.0" lodash "^4.17.5" -"@babel/types@7.0.0-beta.49", "@babel/types@^7.0.0-beta": - version "7.0.0-beta.49" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.49.tgz#b7e3b1c3f4d4cfe11bdf8c89f1efd5e1617b87a6" +"@babel/types@7.0.0-beta.51", "@babel/types@^7.0.0-beta": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9" dependencies: esutils "^2.0.2" lodash "^4.17.5" @@ -460,8 +460,8 @@ acorn-globals@^4.1.0: acorn "^5.0.0" acorn@^5.0.0, acorn@^5.3.0: - version "5.6.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.6.2.tgz#b1da1d7be2ac1b4a327fb9eab851702c5045b4e7" + version "5.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.0.tgz#03d135486e648e870799b4d26c82b21f2ad21531" ajv@^5.1.0: version "5.5.2" @@ -1542,14 +1542,14 @@ collection-visit@^1.0.0: object-visit "^1.0.0" color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" dependencies: - color-name "^1.1.1" + color-name "1.1.1" -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" color-support@^1.1.3: version "1.1.3" @@ -1574,8 +1574,8 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" compare-versions@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.2.1.tgz#a49eb7689d4caaf0b6db5220173fd279614000f7" + version "3.3.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" component-emitter@^1.2.1: version "1.2.1" @@ -1637,7 +1637,7 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.6: +core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -1863,8 +1863,8 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" escodegen@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + version "1.10.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.10.0.tgz#f647395de22519fbd0d928ffcf1d17e0dec2603e" dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -2080,8 +2080,8 @@ fbjs-scripts@^0.8.1: through2 "^2.0.0" fbjs@^0.8.14, fbjs@^0.8.16, fbjs@^0.8.9: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" @@ -2089,7 +2089,7 @@ fbjs@^0.8.14, fbjs@^0.8.16, fbjs@^0.8.9: object-assign "^4.1.0" promise "^7.1.1" setimmediate "^1.0.5" - ua-parser-js "^0.7.9" + ua-parser-js "^0.7.18" figures@^2.0.0: version "2.0.0" @@ -2440,8 +2440,8 @@ ignore-walk@^3.0.1: minimatch "^3.0.4" image-size@^0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4" + version "0.6.3" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" import-local@^1.0.0: version "1.0.0" @@ -3516,7 +3516,7 @@ micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -4110,8 +4110,8 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" psl@^1.1.24: - version "1.1.27" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.27.tgz#2b2c77019db86855170d903532400bf71ee085b6" + version "1.1.28" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.28.tgz#4fb6ceb08a1e2214d4fd4de0ca22dae13740bc7b" punycode@^1.4.1: version "1.4.1" @@ -4162,11 +4162,11 @@ react-devtools-core@3.1.0: ws "^2.0.3" react-is@^16.3.1: - version "16.4.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.0.tgz#cc9fdc855ac34d2e7d9d2eb7059bbc240d35ffcf" + version "16.4.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.1.tgz#d624c4650d2c65dbd52c72622bbf389435d9776e" "react-native-google-analytics-bridge@file:..": - version "5.7.1" + version "6.0.0-rc11" react-native@0.55.4: version "0.55.4" @@ -4332,7 +4332,7 @@ regenerator-transform@^0.10.0: babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.12.3: +regenerator-transform@^0.12.4: version "0.12.4" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.4.tgz#aa9b6c59f4b97be080e972506c560b3bccbfcff0" dependencies: @@ -5017,7 +5017,7 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -ua-parser-js@^0.7.9: +ua-parser-js@^0.7.18: version "0.7.18" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed" diff --git a/index.js b/index.js deleted file mode 100644 index 578d3203..00000000 --- a/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { GoogleAnalyticsBackwardsCompability } from './src/GoogleAnalyticsBackwardsCompability'; -import { GoogleAnalyticsTracker } from './src/GoogleAnalyticsTracker'; -import { GoogleAnalyticsSettings } from './src/GoogleAnalyticsSettings'; -import { GoogleTagManager } from './src/GoogleTagManager'; -import { GoogleAnalyticsBridge } from './src/NativeBridges'; - -export { - GoogleAnalyticsTracker, - GoogleAnalyticsSettings, - GoogleTagManager, -}; - -/** - * Backwards compatibility default export. - * Versions bellow 3.1.0 used static GoogleAnalytics class. - * This exported instance makes sure older implementations work. - */ -export default new GoogleAnalyticsBackwardsCompability(GoogleAnalyticsBridge ? GoogleAnalyticsBridge.nativeTrackerId : null); diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.xcodeproj/project.pbxproj b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.xcodeproj/project.pbxproj index 09aca7ca..be1a1dd4 100644 --- a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.xcodeproj/project.pbxproj +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + A708FC1A1F6BA89900211FC3 /* GoogleAnalyticsPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = A708FC191F6BA89900211FC3 /* GoogleAnalyticsPayload.m */; }; + A708FC201F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = A708FC1F1F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.m */; }; A710AAE31CC640E40085DAC1 /* RCTGoogleTagManagerBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = A710AAE21CC640E40085DAC1 /* RCTGoogleTagManagerBridge.m */; }; A79185CA1C30694E001236A6 /* RCTGoogleAnalyticsBridge.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = A79185C91C30694E001236A6 /* RCTGoogleAnalyticsBridge.h */; }; A79185CC1C30694E001236A6 /* RCTGoogleAnalyticsBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = A79185CB1C30694E001236A6 /* RCTGoogleAnalyticsBridge.m */; }; @@ -27,6 +29,10 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + A708FC181F6BA86C00211FC3 /* GoogleAnalyticsPayload.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoogleAnalyticsPayload.h; sourceTree = ""; }; + A708FC191F6BA89900211FC3 /* GoogleAnalyticsPayload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoogleAnalyticsPayload.m; sourceTree = ""; }; + A708FC1E1F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGoogleAnalyticsSettings.h; sourceTree = ""; }; + A708FC1F1F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGoogleAnalyticsSettings.m; sourceTree = ""; }; A710AAE11CC640E40085DAC1 /* RCTGoogleTagManagerBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGoogleTagManagerBridge.h; sourceTree = ""; }; A710AAE21CC640E40085DAC1 /* RCTGoogleTagManagerBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGoogleTagManagerBridge.m; sourceTree = ""; }; A79185C61C30694E001236A6 /* libRCTGoogleAnalyticsBridge.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTGoogleAnalyticsBridge.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -82,10 +88,14 @@ A79185C81C30694E001236A6 /* RCTGoogleAnalyticsBridge */ = { isa = PBXGroup; children = ( + A708FC1E1F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.h */, + A708FC1F1F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.m */, A710AAE11CC640E40085DAC1 /* RCTGoogleTagManagerBridge.h */, A710AAE21CC640E40085DAC1 /* RCTGoogleTagManagerBridge.m */, A79185C91C30694E001236A6 /* RCTGoogleAnalyticsBridge.h */, A79185CB1C30694E001236A6 /* RCTGoogleAnalyticsBridge.m */, + A708FC181F6BA86C00211FC3 /* GoogleAnalyticsPayload.h */, + A708FC191F6BA89900211FC3 /* GoogleAnalyticsPayload.m */, ); path = RCTGoogleAnalyticsBridge; sourceTree = ""; @@ -170,6 +180,8 @@ buildActionMask = 2147483647; files = ( A710AAE31CC640E40085DAC1 /* RCTGoogleTagManagerBridge.m in Sources */, + A708FC1A1F6BA89900211FC3 /* GoogleAnalyticsPayload.m in Sources */, + A708FC201F6BB4D200211FC3 /* RCTGoogleAnalyticsSettings.m in Sources */, A79185CC1C30694E001236A6 /* RCTGoogleAnalyticsBridge.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.h b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.h new file mode 100644 index 00000000..d116aea2 --- /dev/null +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.h @@ -0,0 +1,5 @@ +#import "GAIDictionaryBuilder.h" + +@interface GoogleAnalyticsPayload : NSObject ++ (void)addBuilderPayload:(GAIDictionaryBuilder*)builder payload:(NSDictionary *)payload; +@end diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.m b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.m new file mode 100644 index 00000000..d4e02c33 --- /dev/null +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/GoogleAnalyticsPayload.m @@ -0,0 +1,181 @@ +#import "GoogleAnalyticsPayload.h" +#import +#import +#import "GAI.h" +#import "GAIFields.h" +#import "GAIDictionaryBuilder.h" +#import "GAIEcommerceProduct.h" +#import "GAIEcommerceProductAction.h" +#import "GAIEcommerceFields.h" + +@implementation GoogleAnalyticsPayload { + +} + +typedef enum { + Detail = 1, + Click = 2, + Add = 3, + Remove = 4, + Checkout = 5, + CheckoutOption = 6, + Purchase = 7, + Refund = 8 +} ProductActionEnum; + ++ (void)addBuilderPayload:(GAIDictionaryBuilder*)builder payload:(NSDictionary*)payload +{ + NSArray* products = payload[@"products"]; + if (products) { + NSArray* ecommerceProducts = getEcommerceProducts(products); + for (GAIEcommerceProduct* product in ecommerceProducts) { + [builder addProduct:product]; + } + } + + NSArray* impressionProducts = payload[@"impressionProducts"]; + if (impressionProducts) { + NSArray* ecommerceProducts = getEcommerceProducts(impressionProducts); + for (GAIEcommerceProduct* product in ecommerceProducts) { + [builder addProductImpression:product + impressionList:payload[@"impressionList"] + impressionSource:payload[@"impressionSource"]]; + } + } + + NSDictionary* productActionDict = payload[@"productAction"]; + if (productActionDict) { + [builder setProductAction:getEcommerceProductAction(productActionDict)]; + } + + NSDictionary* customDimensions = payload[@"customDimensions"]; + if (customDimensions) { + for (NSString *dimensionIndex in customDimensions){ + [builder set:[customDimensions objectForKey:dimensionIndex] forKey:[GAIFields customDimensionForIndex:[dimensionIndex intValue]]]; + } + } + + NSDictionary* customMetrics = payload[@"customMetrics"]; + if (customMetrics) { + for (NSString *metricIndex in customMetrics) { + [builder set:[customMetrics objectForKey:metricIndex] forKey:[GAIFields customMetricForIndex:[metricIndex intValue]]]; + } + } + + NSString* utmCampaignUrl = payload[@"utmCampaignUrl"]; + if (utmCampaignUrl) { + [builder setAll:getUtmCampaignUrlHitParams(utmCampaignUrl)]; + } + + NSString* sessionState = payload[@"session"]; + if (sessionState != nil) { + [builder set:sessionState forKey:kGAISessionControl]; + } +} + +static NSArray* getEcommerceProducts(NSArray* products) +{ + NSMutableArray* ecommerceProducts = [NSMutableArray new]; + + for (NSDictionary* product in products) + { + GAIEcommerceProduct *ecommerceProduct = [[GAIEcommerceProduct alloc] init]; + + [ecommerceProduct setId:[RCTConvert NSString:product[@"id"]]]; + [ecommerceProduct setName:[RCTConvert NSString:product[@"name"]]]; + [ecommerceProduct setCategory:[RCTConvert NSString:product[@"category"]]]; + [ecommerceProduct setBrand:[RCTConvert NSString:product[@"brand"]]]; + [ecommerceProduct setVariant:[RCTConvert NSString:product[@"variant"]]]; + [ecommerceProduct setPrice:[RCTConvert NSNumber:product[@"price"]]]; + [ecommerceProduct setCouponCode:[RCTConvert NSString:product[@"couponCode"]]]; + [ecommerceProduct setQuantity:[RCTConvert NSNumber:product[@"quantity"]]]; + + [ecommerceProducts addObject:ecommerceProduct]; + } + + return ecommerceProducts; +} + +static GAIEcommerceProductAction* getEcommerceProductAction(NSDictionary* productActionDict) +{ + if (!productActionDict) return NULL; + + NSString* action = getProductAction([RCTConvert NSNumber:productActionDict[@"action"]]); + + GAIEcommerceProductAction* productAction = [[GAIEcommerceProductAction alloc] init]; + + [productAction setAction:action]; + + NSDictionary* transaction = productActionDict[@"transaction"]; + if (transaction) { + [productAction setTransactionId:[RCTConvert NSString:transaction[@"id"]]]; + [productAction setAffiliation: [RCTConvert NSString:transaction[@"affiliation"]]]; + [productAction setRevenue:[RCTConvert NSNumber:transaction[@"revenue"]]]; + [productAction setTax:[RCTConvert NSNumber:transaction[@"tax"]]]; + [productAction setShipping:[RCTConvert NSNumber:transaction[@"shipping"]]]; + [productAction setCouponCode:[RCTConvert NSString:transaction[@"couponCode"]]]; + } + + // Sets the option associated with the checkout. This value is used for kGAICheckout and kGAICheckoutOptions product actions. + NSNumber* checkoutStep = [RCTConvert NSNumber:productActionDict[@"checkoutStep"]]; + if (checkoutStep) + [productAction setCheckoutStep:checkoutStep]; + + // Sets the option associated with the checkout. This value is used for kGAICheckout and kGAICheckoutOptions product actions. + NSString* checkoutOption = [RCTConvert NSString:productActionDict[@"checkoutOption"]]; + if (checkoutOption) + [productAction setCheckoutOption:checkoutOption]; + + // Sets the list name associated with the products in Google Analytics beacons. This value is used in kGAIPADetail and kGAIPAClick product actions. + NSString* productActionList = [RCTConvert NSString:productActionDict[@"productActionList"]]; + if (productActionList) + [productAction setProductActionList:productActionList]; + + // Sets the list source name associated with the products in Google Analytics beacons. This value is used in kGAIPADetail and kGAIPAClick product actions. + NSString* productListSource = [RCTConvert NSString:productActionDict[@"productListSource"]]; + if (productListSource) + [productAction setProductListSource:productListSource]; + + return productAction; +} + +static NSString* getProductAction(NSNumber* action) +{ + switch ([action intValue]) { + case Click: + return kGAIPAClick; + case Detail: + return kGAIPADetail; + case Add: + return kGAIPAAdd; + case Remove: + return kGAIPARemove; + case Checkout: + return kGAIPACheckout; + case Refund: + return kGAIPARefund; + default: + case Purchase: + return kGAIPAPurchase; + } +} + +static NSDictionary* getUtmCampaignUrlHitParams(NSString* urlString) +{ + GAIDictionaryBuilder *hitParams = [[GAIDictionaryBuilder alloc] init]; + + // setCampaignParametersFromUrl: parses Google Analytics campaign ("UTM") + // parameters from a string url into a Map that can be set on a Tracker. + [hitParams setCampaignParametersFromUrl:urlString]; + + // kGAICampaignSource is required. Use host if not set by previous call. + NSURL *url = [NSURL URLWithString:urlString]; + if(![hitParams get:kGAICampaignSource] && [url host].length !=0) { + [hitParams set:@"referrer" forKey:kGAICampaignMedium]; + [hitParams set:[url host] forKey:kGAICampaignSource]; + } + + return [hitParams build]; +} + +@end diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.h b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.h index 2f224e82..dd3fb5e1 100644 --- a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.h +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.h @@ -1,5 +1,5 @@ #import @interface RCTGoogleAnalyticsBridge : NSObject -- (void) trackEventWithCustomDimensionAndMetricValues:(NSString *)trackerId category:(NSString *)category action:(NSString *)action optionalValues:(NSDictionary *)optionalValues dimensionIndexValues:(NSDictionary *)dimensionIndexValues metricIndexValues:(NSDictionary *)metricIndexValues; + @end diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m index 783cd506..3f1ad780 100644 --- a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge.m @@ -1,4 +1,5 @@ #import "RCTGoogleAnalyticsBridge.h" +#import "GoogleAnalyticsPayload.h" #import #import #import @@ -10,19 +11,15 @@ #import "GAIEcommerceFields.h" @implementation RCTGoogleAnalyticsBridge { - + } -NSString *staticTrackerId; - - (instancetype)init { if ((self = [super init])) { [GAI sharedInstance].trackUncaughtExceptions = YES; [GAI sharedInstance].dispatchInterval = 20; - - staticTrackerId = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GAITrackingId"]; - + NSString *logLevel = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GAILogLevel"]; if (logLevel != nil) { [[GAI sharedInstance].logger setLogLevel:[logLevel intValue]]; @@ -31,238 +28,121 @@ - (instancetype)init return self; } -- (NSDictionary *)constantsToExport -{ - return @{ @"nativeTrackerId": staticTrackerId != nil ? staticTrackerId : [NSNull null] }; -} - RCT_EXPORT_MODULE(); -RCT_EXPORT_METHOD(trackScreenView:(NSString *)trackerId screenName:(NSString *)screenName) -{ - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - [tracker set:kGAIScreenName - value:screenName]; - [tracker send:[[GAIDictionaryBuilder createScreenView] build]]; -} - -RCT_EXPORT_METHOD(trackEvent:(NSString *)trackerId category:(NSString *)category action:(NSString *)action optionalValues:(NSDictionary *)optionalValues) -{ - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *label = [RCTConvert NSString:optionalValues[@"label"]]; - NSNumber *value = [RCTConvert NSNumber:optionalValues[@"value"]]; - [tracker send:[[GAIDictionaryBuilder createEventWithCategory:category - action:action - label:label - value:value] build]]; -} - -RCT_EXPORT_METHOD(trackScreenViewWithCustomDimensionValues:(NSString *)trackerId screenName:(NSString *)screenName dimensionIndexValues:(NSDictionary *)dimensionIndexValues) +RCT_EXPORT_METHOD(trackScreenView:(nonnull NSString *)trackerId + screenName:(nonnull NSString *)screenName + payload:(NSDictionary *)payload) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIScreenName - value:screenName]; - + value:screenName]; GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; - - for (NSString *dimensionIndex in dimensionIndexValues) - [builder set:[dimensionIndexValues objectForKey:dimensionIndex] forKey:[GAIFields customDimensionForIndex:[dimensionIndex intValue]]]; - + + if (payload) { + [GoogleAnalyticsPayload addBuilderPayload:builder payload:payload]; + } + [tracker send:[builder build]]; } -RCT_EXPORT_METHOD(trackEventWithCustomDimensionValues:(NSString *)trackerId category:(NSString *)category action:(NSString *)action optionalValues:(NSDictionary *)optionalValues dimensionIndexValues:(NSDictionary *)dimensionIndexValues) -{ - [self trackEventWithCustomDimensionAndMetricValues:trackerId category:category action:action optionalValues:optionalValues dimensionIndexValues:dimensionIndexValues metricIndexValues:nil]; -} - -RCT_EXPORT_METHOD(trackEventWithCustomDimensionAndMetricValues:(NSString *)trackerId category:(NSString *)category action:(NSString *)action optionalValues:(NSDictionary *)optionalValues dimensionIndexValues:(NSDictionary *)dimensionIndexValues metricIndexValues:(NSDictionary *)metricIndexValues) +RCT_EXPORT_METHOD(trackEvent:(nonnull NSString *)trackerId + category:(nonnull NSString *)category + action:(nonnull NSString *)action + label:(NSString *)label + value:(NSString *)value + payload:(NSDictionary *)payload) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *label = [RCTConvert NSString:optionalValues[@"label"]]; - NSNumber *value = [RCTConvert NSNumber:optionalValues[@"value"]]; - + + NSNumber* valueNumber = nil; + if (value) { + valueNumber = @([value intValue]); + } + GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createEventWithCategory:category action:action label:label - value:value]; - for (NSString *dimensionIndex in dimensionIndexValues) - [builder set:[dimensionIndexValues objectForKey:dimensionIndex] forKey:[GAIFields customDimensionForIndex:[dimensionIndex intValue]]]; + value:valueNumber]; - if (metricIndexValues != nil){ - for (NSString *metricIndex in metricIndexValues) - [builder set:[metricIndexValues objectForKey:metricIndex] forKey:[GAIFields customMetricForIndex:[metricIndex intValue]]]; + if (payload) { + [GoogleAnalyticsPayload addBuilderPayload:builder payload:payload]; + } + + // Non-interaction event. Enable sending events without affecting bounce + NSString* nonInteraction = payload[@"nonInteraction"]; + if (nonInteraction) { + [builder set:nonInteraction ? @"1" : @"0" forKey:kGAINonInteraction]; } [tracker send:[builder build]]; } -RCT_EXPORT_METHOD(trackTiming:(NSString *)trackerId category:(nonnull NSString *)category value:(nonnull NSNumber *)value optionalValues:(nonnull NSDictionary *)optionalValues) -{ - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *name = [RCTConvert NSString:optionalValues[@"name"]]; - NSString *label = [RCTConvert NSString:optionalValues[@"label"]]; - [tracker send:[[GAIDictionaryBuilder createTimingWithCategory:category - interval:value - name:name - label:label] build]]; -} - -RCT_EXPORT_METHOD(trackPurchaseEvent:(NSString *)trackerId product:(NSDictionary *)product transaction:(NSDictionary *)transaction eventCategory:(NSString *)eventCategory eventAction:(NSString *)eventAction) +RCT_EXPORT_METHOD(trackTiming:(nonnull NSString *)trackerId + category:(nonnull NSString *)category + interval:(nonnull NSNumber *)interval + name:(nonnull NSString *)name + label:(NSString *)label + payload:(NSDictionary *)payload) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *productId = [RCTConvert NSString:product[@"id"]]; - NSString *productName = [RCTConvert NSString:product[@"name"]]; - NSString *productCategory = [RCTConvert NSString:product[@"category"]]; - NSString *productBrand = [RCTConvert NSString:product[@"brand"]]; - NSString *productVariant = [RCTConvert NSString:product[@"variant"]]; - NSNumber *productPrice = [RCTConvert NSNumber:product[@"price"]]; - NSString *productCouponCode = [RCTConvert NSString:product[@"couponCode"]]; - NSNumber *productQuantity = [RCTConvert NSNumber:product[@"quantity"]]; - NSString *transactionId = [RCTConvert NSString:transaction[@"id"]]; - NSString *transactionAffiliation = [RCTConvert NSString:transaction[@"affiliation"]]; - NSNumber *transactionRevenue = [RCTConvert NSNumber:transaction[@"revenue"]]; - NSNumber *transactionTax = [RCTConvert NSNumber:transaction[@"tax"]]; - NSNumber *transactionShipping = [RCTConvert NSNumber:transaction[@"shipping"]]; - NSString *transactionCouponCode = [RCTConvert NSString:transaction[@"couponCode"]]; - GAIEcommerceProduct *ecommerceProduct = [[GAIEcommerceProduct alloc] init]; - [ecommerceProduct setId:productId]; - [ecommerceProduct setName:productName]; - [ecommerceProduct setCategory:productCategory]; - [ecommerceProduct setBrand:productBrand]; - [ecommerceProduct setVariant:productVariant]; - [ecommerceProduct setPrice:productPrice]; - [ecommerceProduct setCouponCode:productCouponCode]; - [ecommerceProduct setQuantity:productQuantity]; - GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createEventWithCategory:eventCategory - action:eventAction - label:nil - value:nil]; - GAIEcommerceProductAction *action = [[GAIEcommerceProductAction alloc] init]; - [action setAction:kGAIPAPurchase]; - [action setTransactionId:transactionId]; - [action setAffiliation:transactionAffiliation]; - [action setRevenue:transactionRevenue]; - [action setTax:transactionTax]; - [action setShipping:transactionShipping]; - [action setCouponCode:transactionCouponCode]; - [builder setProductAction:action]; - [builder addProduct:ecommerceProduct]; - [tracker send:[builder build]]; -} - -RCT_EXPORT_METHOD(trackMultiProductsPurchaseEvent:(NSString *)trackerId products:(NSArray *)products transaction:(NSDictionary *)transaction eventCategory:(NSString *)eventCategory eventAction:(NSString *)eventAction) { - - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *transactionId = [RCTConvert NSString:transaction[@"id"]]; - NSString *transactionAffiliation = [RCTConvert NSString:transaction[@"affiliation"]]; - NSNumber *transactionRevenue = [RCTConvert NSNumber:transaction[@"revenue"]]; - NSNumber *transactionTax = [RCTConvert NSNumber:transaction[@"tax"]]; - NSNumber *transactionShipping = [RCTConvert NSNumber:transaction[@"shipping"]]; - NSString *transactionCouponCode = [RCTConvert NSString:transaction[@"couponCode"]]; - GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createEventWithCategory:eventCategory - action:eventAction - label:nil - value:nil]; - GAIEcommerceProductAction *action = [[GAIEcommerceProductAction alloc] init]; - [action setAction:kGAIPAPurchase]; - [action setTransactionId:transactionId]; - [action setAffiliation:transactionAffiliation]; - [action setRevenue:transactionRevenue]; - [action setTax:transactionTax]; - [action setShipping:transactionShipping]; - [action setCouponCode:transactionCouponCode]; - [builder setProductAction:action]; - for (id product in products) { - NSString *productId = [RCTConvert NSString:product[@"id"]]; - NSString *productName = [RCTConvert NSString:product[@"name"]]; - NSString *productBrand = [RCTConvert NSString:product[@"brand"]]; - NSNumber *productPrice = [RCTConvert NSNumber:product[@"price"]]; - NSString *productVariant = [RCTConvert NSString:product[@"variant"]]; - NSString *productCategory = [RCTConvert NSString:product[@"category"]]; - NSNumber *productQuantity = [RCTConvert NSNumber:product[@"quantity"]]; - GAIEcommerceProduct *ecommerceProduct = [[GAIEcommerceProduct alloc] init]; - [ecommerceProduct setId:productId]; - [ecommerceProduct setName:productName]; - [ecommerceProduct setCategory:productCategory]; - [ecommerceProduct setBrand:productBrand]; - [ecommerceProduct setVariant:productVariant]; - [ecommerceProduct setPrice:productPrice]; - [ecommerceProduct setQuantity:productQuantity]; - if ([product objectForKey:@"couponCode"]) { - NSString *productCouponCode = [RCTConvert NSString:product[@"couponCode"]]; - [ecommerceProduct setCouponCode:productCouponCode]; - } - [builder addProduct:ecommerceProduct]; + + GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createTimingWithCategory:category + interval:interval + name:name + label:label]; + + if (payload) { + [GoogleAnalyticsPayload addBuilderPayload:builder payload:payload]; } + [tracker send:[builder build]]; } -RCT_EXPORT_METHOD(trackMultiProductsPurchaseEventWithCustomDimensionValues:(NSString *)trackerId products:(NSArray *)products transaction:(NSDictionary *)transaction eventCategory:(NSString *)eventCategory eventAction:(NSString *)eventAction dimensionIndexValues:(NSDictionary *)dimensionIndexValues) { - +RCT_EXPORT_METHOD(trackException:(nonnull NSString *)trackerId + error:(nonnull NSString *)error + fatal:(BOOL)fatal + payload:(NSDictionary *)payload) +{ id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - NSString *transactionId = [RCTConvert NSString:transaction[@"id"]]; - NSString *transactionAffiliation = [RCTConvert NSString:transaction[@"affiliation"]]; - NSNumber *transactionRevenue = [RCTConvert NSNumber:transaction[@"revenue"]]; - NSNumber *transactionTax = [RCTConvert NSNumber:transaction[@"tax"]]; - NSNumber *transactionShipping = [RCTConvert NSNumber:transaction[@"shipping"]]; - NSString *transactionCouponCode = [RCTConvert NSString:transaction[@"couponCode"]]; - GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createEventWithCategory:eventCategory - action:eventAction - label:nil - value:nil]; - for (NSString *dimensionIndex in dimensionIndexValues) - [builder set:[dimensionIndexValues objectForKey:dimensionIndex] forKey:[GAIFields customDimensionForIndex:[dimensionIndex intValue]]]; - - GAIEcommerceProductAction *action = [[GAIEcommerceProductAction alloc] init]; - [action setAction:kGAIPAPurchase]; - [action setTransactionId:transactionId]; - [action setAffiliation:transactionAffiliation]; - [action setRevenue:transactionRevenue]; - [action setTax:transactionTax]; - [action setShipping:transactionShipping]; - [action setCouponCode:transactionCouponCode]; - [builder setProductAction:action]; - for (id product in products) { - NSString *productId = [RCTConvert NSString:product[@"id"]]; - NSString *productName = [RCTConvert NSString:product[@"name"]]; - NSString *productBrand = [RCTConvert NSString:product[@"brand"]]; - NSNumber *productPrice = [RCTConvert NSNumber:product[@"price"]]; - NSString *productVariant = [RCTConvert NSString:product[@"variant"]]; - NSString *productCategory = [RCTConvert NSString:product[@"category"]]; - NSNumber *productQuantity = [RCTConvert NSNumber:product[@"quantity"]]; - GAIEcommerceProduct *ecommerceProduct = [[GAIEcommerceProduct alloc] init]; - [ecommerceProduct setId:productId]; - [ecommerceProduct setName:productName]; - [ecommerceProduct setCategory:productCategory]; - [ecommerceProduct setBrand:productBrand]; - [ecommerceProduct setVariant:productVariant]; - [ecommerceProduct setPrice:productPrice]; - [ecommerceProduct setQuantity:productQuantity]; - if ([product objectForKey:@"couponCode"]) { - NSString *productCouponCode = [RCTConvert NSString:product[@"couponCode"]]; - [ecommerceProduct setCouponCode:productCouponCode]; - } - [builder addProduct:ecommerceProduct]; + + GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createExceptionWithDescription:error + withFatal:[NSNumber numberWithBool:fatal]]; + + if (payload) { + [GoogleAnalyticsPayload addBuilderPayload:builder payload:payload]; } + [tracker send:[builder build]]; } -RCT_EXPORT_METHOD(trackException:(NSString *)trackerId error:(NSString *)error fatal:(BOOL)fatal) +RCT_EXPORT_METHOD(trackSocialInteraction:(nonnull NSString *)trackerId + network:(nonnull NSString *)network + action:(nonnull NSString *)action + targetUrl:(nonnull NSString *)targetUrl + payload:(NSDictionary *)payload) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - [tracker send:[[GAIDictionaryBuilder createExceptionWithDescription:error - withFatal:[NSNumber numberWithBool:fatal]] build]]; + + GAIDictionaryBuilder *builder =[GAIDictionaryBuilder createSocialWithNetwork:network + action:action + target:targetUrl]; + + if (payload) { + [GoogleAnalyticsPayload addBuilderPayload:builder payload:payload]; + } + + [tracker send:[builder build]]; } -RCT_EXPORT_METHOD(setUser:(NSString *)trackerId userId:(NSString *)userId) +RCT_EXPORT_METHOD(setUser:(nonnull NSString *)trackerId userId:(nonnull NSString *)userId) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIUserId - value:userId]; + value:userId]; } -RCT_EXPORT_METHOD(setClient:(NSString *)trackerId clientId:(NSString *)clientId) +RCT_EXPORT_METHOD(setClient:(nonnull NSString *)trackerId clientId:(nonnull NSString *)clientId) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIClientId @@ -279,113 +159,47 @@ - (NSDictionary *)constantsToExport reject(@"CLIENTID_FAILED", nil, RCTErrorWithMessage(@"Unable to fetch client id")); } -RCT_EXPORT_METHOD(allowIDFA:(NSString *)trackerId enabled:(BOOL)enabled) +RCT_EXPORT_METHOD(allowIDFA:(nonnull NSString *)trackerId enabled:(BOOL)enabled) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; tracker.allowIDFACollection = enabled; } -RCT_EXPORT_METHOD(trackSocialInteraction:(NSString *)trackerId network:(NSString *)network action:(NSString *)action targetUrl:(NSString *)targetUrl) -{ - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - [tracker send:[[GAIDictionaryBuilder createSocialWithNetwork:network - action:action - target:targetUrl] build]]; -} - - -RCT_EXPORT_METHOD(setSamplingRate:(NSString *)trackerId sampleRate:(nonnull NSNumber *)sampleRate) +RCT_EXPORT_METHOD(setSamplingRate:(nonnull NSString *)trackerId sampleRate:(nonnull NSNumber *)sampleRate) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAISampleRate value:[sampleRate stringValue]]; } -RCT_EXPORT_METHOD(setDryRun:(BOOL)enabled) -{ - [GAI sharedInstance].dryRun = enabled; -} - -RCT_EXPORT_METHOD(setDispatchInterval:(NSInteger)intervalInSeconds) -{ - [GAI sharedInstance].dispatchInterval = intervalInSeconds; -} - -RCT_EXPORT_METHOD(setTrackUncaughtExceptions:(NSString *)trackerId enabled:(BOOL)enabled) -{ - [GAI sharedInstance].trackUncaughtExceptions = enabled; -} - -RCT_EXPORT_METHOD(setAnonymizeIp:(NSString *)trackerId enabled:(BOOL)enabled) +RCT_EXPORT_METHOD(setAnonymizeIp:(nonnull NSString *)trackerId enabled:(BOOL)enabled) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIAnonymizeIp value:enabled ? @"1" : @"0"]; } -RCT_EXPORT_METHOD(setOptOut:(BOOL)enabled) -{ - [GAI sharedInstance].optOut = enabled; -} - -RCT_EXPORT_METHOD(setAppName:(NSString *)trackerId appName:(NSString *)appName) +RCT_EXPORT_METHOD(setAppName:(nonnull NSString *)trackerId appName:(nonnull NSString *)appName) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIAppName value:appName]; } -RCT_EXPORT_METHOD(setAppVersion:(NSString *)trackerId appVersion:(NSString *)appVersion) +RCT_EXPORT_METHOD(setAppVersion:(nonnull NSString *)trackerId appVersion:(nonnull NSString *)appVersion) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAIAppVersion value:appVersion]; } -RCT_EXPORT_METHOD(setCurrency:(NSString *)trackerId currencyCode:(NSString *)currencyCode) +RCT_EXPORT_METHOD(setCurrency:(nonnull NSString *)trackerId currencyCode:(nonnull NSString *)currencyCode) { id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; [tracker set:kGAICurrencyCode - value:currencyCode]; + value:currencyCode]; } -RCT_EXPORT_METHOD(trackCampaignFromUrl:(NSString *)trackerId urlString:(NSString *)urlString) +// A special case. For iOS this is set on all trackers. On Android it is on each tracker. +RCT_EXPORT_METHOD(setTrackUncaughtExceptions:(nonnull NSString *)trackerId enabled:(BOOL)enabled) { - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - - // setCampaignParametersFromUrl: parses Google Analytics campaign ("UTM") - // parameters from a string url into a Map that can be set on a Tracker. - GAIDictionaryBuilder *hitParams = [[GAIDictionaryBuilder alloc] init]; - - // Set campaign data on the map, not the tracker directly because it only - // needs to be sent once. - [hitParams setCampaignParametersFromUrl:urlString]; - - // Campaign source is the only required campaign field. If previous call - // did not set a campaign source, use the hostname as a referrer instead. - NSURL *url = [NSURL URLWithString:urlString]; - if(![hitParams get:kGAICampaignSource] && [url host].length !=0) { - // Set campaign data on the map, not the tracker. - [hitParams set:@"referrer" forKey:kGAICampaignMedium]; - [hitParams set:[url host] forKey:kGAICampaignSource]; - } - - NSDictionary *hitParamsDict = [hitParams build]; - - // A screen name is required for a screen view. - [tracker set:kGAIScreenName value:@"Init With Campaign"]; - - // Previous V3 SDK versions. - // [tracker send:[[[GAIDictionaryBuilder createAppView] setAll:hitParamsDict] build]]; - - // SDK Version 3.08 and up. - [tracker send:[[[GAIDictionaryBuilder createScreenView] setAll:hitParamsDict] build]]; -} - -RCT_EXPORT_METHOD(createNewSession:(NSString *)trackerId screenName:(NSString *)screenName) -{ - id tracker = [[GAI sharedInstance] trackerWithTrackingId:trackerId]; - - GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; - [builder set:@"start" forKey:kGAISessionControl]; - [tracker set:kGAIScreenName value:screenName]; - [tracker send:[builder build]]; + [GAI sharedInstance].trackUncaughtExceptions = enabled; } RCT_EXPORT_METHOD(dispatch:(RCTPromiseResolveBlock)resolve @@ -399,9 +213,6 @@ - (NSDictionary *)constantsToExport }]; } -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} + @end diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.h b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.h new file mode 100644 index 00000000..a69fbfe5 --- /dev/null +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.h @@ -0,0 +1,5 @@ +#import + +@interface RCTGoogleAnalyticsSettings : NSObject + +@end diff --git a/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.m b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.m new file mode 100644 index 00000000..bcd031b5 --- /dev/null +++ b/ios/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsBridge/RCTGoogleAnalyticsSettings.m @@ -0,0 +1,25 @@ +#import "RCTGoogleAnalyticsSettings.h" +#import "GAI.h" + +@implementation RCTGoogleAnalyticsSettings { + +} + +RCT_EXPORT_MODULE(); + +RCT_EXPORT_METHOD(setDryRun:(BOOL)enabled) +{ + [GAI sharedInstance].dryRun = enabled; +} + +RCT_EXPORT_METHOD(setDispatchInterval:(NSInteger)intervalInSeconds) +{ + [GAI sharedInstance].dispatchInterval = intervalInSeconds; +} + +RCT_EXPORT_METHOD(setOptOut:(BOOL)enabled) +{ + [GAI sharedInstance].optOut = enabled; +} + +@end diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c0e8841d..00000000 --- a/package-lock.json +++ /dev/null @@ -1,456 +0,0 @@ -{ - "name": "react-native-google-analytics-bridge", - "version": "5.9.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/parsimmon": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.6.2.tgz", - "integrity": "sha512-QdjZG37I1uhpqfLuBbAm7KVW4egx+qQAkeCsIXEqbdEiCDlWjYhWbPqLpg7RCg8DuUgLSKaPFE6jNe6wi5YUlw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" - }, - "dependencies": { - "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.2" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, - "requires": { - "color-name": "1.1.1" - } - }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "definitelytyped-header-parser": { - "version": "github:Microsoft/definitelytyped-header-parser#f152526f82f51d2baf91a99a397b449342b52db1", - "dev": true, - "requires": { - "@types/parsimmon": "1.6.2", - "parsimmon": "1.8.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dtslint": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-0.2.0.tgz", - "integrity": "sha512-o87elwuM2r0OeIn99jcFPzpELFj8l1pdtaqCdfepjbTHMVHy+rRCFEtwOhs4s3FcX4KP0n7V5gfsaYMTSBoNVQ==", - "dev": true, - "requires": { - "definitelytyped-header-parser": "github:Microsoft/definitelytyped-header-parser#f152526f82f51d2baf91a99a397b449342b52db1", - "fs-promise": "2.0.3", - "strip-json-comments": "2.0.1", - "tslint": "5.10.0", - "typescript": "3.0.0-dev.20180609" - } - }, - "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 - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" - } - }, - "fs-promise": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", - "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", - "dev": true, - "requires": { - "any-promise": "1.3.0", - "fs-extra": "2.1.2", - "mz": "2.7.0", - "thenify-all": "1.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.11" - } - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "1.3.0", - "object-assign": "4.1.1", - "thenify-all": "1.6.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "parsimmon": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.8.0.tgz", - "integrity": "sha512-qRUCyM2Z2QX1N3EueexSWkzSzVvQQFwvX/mfGlpL7UiJdPhzkOBFd4H0O0YwZ6Ud0cOxuawrN7WSi9/R3a1gqQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "dev": true, - "requires": { - "any-promise": "1.3.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dev": true, - "requires": { - "thenify": "3.3.0" - } - }, - "tslib": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", - "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==", - "dev": true - }, - "tslint": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz", - "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=", - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "builtin-modules": "1.1.1", - "chalk": "2.4.1", - "commander": "2.15.1", - "diff": "3.5.0", - "glob": "7.1.2", - "js-yaml": "3.12.0", - "minimatch": "3.0.4", - "resolve": "1.7.1", - "semver": "5.5.0", - "tslib": "1.9.2", - "tsutils": "2.27.1" - } - }, - "tsutils": { - "version": "2.27.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.1.tgz", - "integrity": "sha512-AE/7uzp32MmaHvNNFES85hhUDHFdFZp6OAiZcd6y4ZKKIg6orJTm8keYWBhIhrJQH3a4LzNKat7ZPXZt5aTf6w==", - "dev": true, - "requires": { - "tslib": "1.9.2" - } - }, - "typescript": { - "version": "3.0.0-dev.20180609", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.0-dev.20180609.tgz", - "integrity": "sha512-bqO5mSGbxZoiY/9Y1bnnU36dC5CfnrA9I9WKf3QB0qMuJakoofO2DNTDRwsypyhCThlNtF2Ls/OMj3Txglu4Xg==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - } - } -} diff --git a/package.json b/package.json index d89184fd..c73f63cf 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,17 @@ { "name": "react-native-google-analytics-bridge", - "version": "5.9.0", + "version": "6.0.0-rc11", "description": "React Native bridge for using native Google Analytics libraries on iOS and Android", - "main": "./index.js", - "types": "types/index.d.ts", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "scripts": { - "test": "npm run dtslint", - "dtslint": "dtslint types" + "prepublishOnly": "yarn run build-all", + "test": "echo \"Error: no test yet!\" && exit 0", + "build": "tsc", + "build-watch": "tsc --watch", + "docs": "documentation readme dist/** --section=\"JavaScript API\"", + "build-all": "rm -rf dist && yarn run build && yarn run docs", + "precommit": "yarn run build-all && git add README.md" }, "repository": { "type": "git", @@ -44,6 +49,11 @@ } }, "devDependencies": { - "dtslint": "^0.2.0" + "@types/react": "16.3.1", + "@types/react-native": "0.55.4", + "documentation": "^8.0.0", + "husky": "^0.14.3", + "prettier": "^1.6.1", + "typescript": "^2.5.2" } } diff --git a/src/GoogleAnalyticsBackwardsCompability.js b/src/GoogleAnalyticsBackwardsCompability.js deleted file mode 100644 index 1697457b..00000000 --- a/src/GoogleAnalyticsBackwardsCompability.js +++ /dev/null @@ -1,119 +0,0 @@ -import { GoogleTagManager } from './GoogleTagManager'; -import { GoogleAnalyticsSettings } from './GoogleAnalyticsSettings'; -import { GoogleAnalyticsTracker } from './GoogleAnalyticsTracker'; - -function createNewTracker(trackerId, customDimensionsKeysIndexMap) { - return trackerId && new GoogleAnalyticsTracker(trackerId, customDimensionsKeysIndexMap); -} - -/** - * Backwards compatibility for static implementation - */ -export class GoogleAnalyticsBackwardsCompability { - // GoogleTagManager was static property of GoogleAnalytics class in previous version. - static GoogleTagManager = GoogleTagManager; - - constructor(trackerId, customDimensionsKeysIndexMap) { - this.tracker = createNewTracker(trackerId, customDimensionsKeysIndexMap); - } - - /** - * Versions below 3.1.0 had singleton that could "lazily" set trackerId. - * @param trackerId - */ - setTrackerId(trackerId, customDimensionsKeysIndexMap) { - this.tracker = createNewTracker(trackerId, customDimensionsKeysIndexMap); - } - - // Proxying previously static methods to Settings - - setDryRun(enabled) { - GoogleAnalyticsSettings.setDryRun(enabled); - } - - setDispatchInterval(intervalInSeconds) { - GoogleAnalyticsSettings.setDispatchInterval(intervalInSeconds); - } - - setOptOut(enabled) { - GoogleAnalyticsSettings.setOptOut(enabled); - } - - // Proxying previously static methods to Tracker - - trackScreenView(screenName) { - this.tracker.trackScreenView(screenName); - } - - trackEvent(category, action, optionalValues = {}) { - this.tracker.trackEvent(category, action, optionalValues); - } - - trackScreenViewWithCustomDimensionValues(screenName, customDimensionValues) { - this.tracker.trackScreenViewWithCustomDimensionValues(screenName, customDimensionValues); - } - - trackEventWithCustomDimensionValues(category, action, optionalValues = {}, customDimensionValues) { - this.tracker.trackEventWithCustomDimensionValues(category, action, optionalValues, customDimensionValues); - } - - trackTiming(category, value, optionalValues = {}) { - this.tracker.trackTiming(category, value, optionalValues); - } - - trackPurchaseEvent(product = {}, transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase") { - this.tracker.trackPurchaseEvent(product, transaction, eventCategory, eventAction); - } - - trackMultiProductsPurchaseEvent(products = [], transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase") { - this.tracker.trackMultiProductsPurchaseEvent(products, transaction, eventCategory, eventAction); - } - - trackMultiProductsPurchaseEventWithCustomDimensionValues(products = [], transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase", customDimensionValues) { - this.tracker.trackMultiProductsPurchaseEventWithCustomDimensionValues(products, transaction, eventCategory, eventAction, customDimensionValues); - } - - trackException(error, fatal = false) { - this.tracker.trackException(error, fatal); - } - - setUser(userId) { - this.tracker.setUser(userId); - } - - allowIDFA(enabled = true) { - this.tracker.allowIDFA(enabled); - } - - trackSocialInteraction(network, action, targetUrl) { - this.tracker.trackSocialInteraction(network, action, targetUrl); - } - - setTrackUncaughtExceptions(enabled) { - this.tracker.setTrackUncaughtExceptions(enabled); - } - - setAppName(appName) { - this.tracker.setAppName(appName); - } - - setAppVersion(appVersion) { - this.tracker.setAppVersion(appVersion); - } - - setAnonymizeIp(enabled) { - this.tracker.setAnonymizeIp(enabled); - } - - setSamplingRate(sampleRatio) { - this.tracker.setSamplingRate(sampleRatio); - } - - setCurrency(currencyCode) { - this.tracker.setCurrency(currencyCode); - } - - createNewSession(screenName) { - this.tracker.createNewSession(screenName); - } -} diff --git a/src/GoogleAnalyticsSettings.js b/src/GoogleAnalyticsSettings.js deleted file mode 100644 index 77d8e5bf..00000000 --- a/src/GoogleAnalyticsSettings.js +++ /dev/null @@ -1,34 +0,0 @@ -import { GoogleAnalyticsBridge } from './NativeBridges'; - -/** - * Google analytics settings shared across all GoogleAnalyticsTracker instances. - */ -export class GoogleAnalyticsSettings { - /** - * Sets if OptOut is active and disables Google Analytics - * This has to be set each time the App starts - * @param {Boolean} enabled - */ - static setOptOut(enabled) { - GoogleAnalyticsBridge.setOptOut(enabled); - } - - /** - * Sets the trackers dispatch interval - * This will influence how often batches of events, screen views, etc - * are sent to your tracker. - * @param {Number} intervalInSeconds - */ - static setDispatchInterval(intervalInSeconds) { - GoogleAnalyticsBridge.setDispatchInterval(intervalInSeconds); - } - - /** - * Sets if the tracker should have dry run enabled. - * If dry run is enabled, no analytics data will be sent to your tracker. - * @param {Boolean} enabled - */ - static setDryRun(enabled) { - GoogleAnalyticsBridge.setDryRun(enabled); - } -} diff --git a/src/GoogleAnalyticsSettings.ts b/src/GoogleAnalyticsSettings.ts new file mode 100644 index 00000000..dd8fa7bd --- /dev/null +++ b/src/GoogleAnalyticsSettings.ts @@ -0,0 +1,37 @@ +import { AnalyticsSettings } from "./NativeBridges"; + +/** + * Settings which are applied across all trackers. + * @name GoogleAnalyticsSettings + */ +class GoogleAnalyticsSettings { + /** + * Sets if OptOut is active and disables Google Analytics. This is disabled by default. Note: This has to be set each time the App starts. + * @example GoogleAnalyticsSettings.setOptOut(true); + * @param {boolean} enabled + */ + static setOptOut(enabled: boolean): void { + AnalyticsSettings.setOptOut(enabled); + } + + /** + * Sets the trackers dispatch interval. + * Events, screen views, etc, are sent in batches to your tracker. This function allows you to configure how often (in seconds) the batches are sent to your tracker. Recommended to keep this around 20-120 seconds to preserve battery and network traffic. This is set to 20 seconds by default. + * @example GoogleAnalyticsSettings.setDispatchInterval(30); + * @param {number} intervalInSeconds + */ + static setDispatchInterval(intervalInSeconds: number): void { + AnalyticsSettings.setDispatchInterval(intervalInSeconds); + } + + /** + * When enabled the native library prevents any data from being sent to Google Analytics. This allows you to test or debug the implementation, without your test data appearing in your Google Analytics reports. + * @example GoogleAnalyticsSettings.setDryRun(true); + * @param {boolean} enabled + */ + static setDryRun(enabled: boolean): void { + AnalyticsSettings.setDryRun(enabled); + } +} + +export default GoogleAnalyticsSettings; diff --git a/src/GoogleAnalyticsTracker.js b/src/GoogleAnalyticsTracker.js deleted file mode 100644 index 0819fd14..00000000 --- a/src/GoogleAnalyticsTracker.js +++ /dev/null @@ -1,304 +0,0 @@ -import { GoogleAnalyticsBridge } from './NativeBridges'; - -const DEFAULT_DISPATCH_TIMEOUT = 15000; - -/** - * Custom dimensions accept only strings and numbers. - * @param customDimensionVal - * @returns {boolean} - */ -function isValidCustomDimension(customDimensionVal) { - const customDimensionValType = typeof customDimensionVal; - return customDimensionValType === 'string' || customDimensionValType === 'number'; -} - -/** - * Used to bridge tracker data to native Google analytics. - * Saves necessary tracker (specific) data to format data as native part of Google analytics expect. - */ -export class GoogleAnalyticsTracker { - /** - * Save all tracker related data that is needed to call native methods with proper data. - * @param trackerId {String} - * @param customDimensionsFieldsIndexMap {{fieldName: fieldIndex}} Custom dimensions field/index pairs - */ - constructor(trackerId, customDimensionsFieldsIndexMap) { - this.id = trackerId; - this.customDimensionsFieldsIndexMap = customDimensionsFieldsIndexMap; - } - - /** - * If Tracker has customDimensionsFieldsIndexMap, it will transform - * customDimensions map pairs {field: value} to {fieldIndex: value}. - * Otherwise customDimensions are passed trough untouched. - * Underlay native methods will transform provided customDimensions map to expected format. - * Google analytics expect dimensions to be tracker with 'dimension{index}' keys, - * not dimension field names. - * @param customDimensions {Object} - * @returns {Object} - */ - transformCustomDimensionsFieldsToIndexes(customDimensions) { - if (this.customDimensionsFieldsIndexMap) { - return Object.keys(this.customDimensionsFieldsIndexMap) - .filter(key => isValidCustomDimension(customDimensions[key])) - .reduce((mappedCustomDimensions, key) => { - const dimensionIndex = this.customDimensionsFieldsIndexMap[key]; - mappedCustomDimensions[dimensionIndex] = customDimensions[key]; - return mappedCustomDimensions; - }, {}); - } - return customDimensions; - } - - /** - * Track the current screen/view - * @param {String} screenName The name of the current screen - */ - trackScreenView(screenName) { - GoogleAnalyticsBridge.trackScreenView(this.id, screenName); - } - - /** - * Track the campaign from url - * @param {String} urlString The url of the deep link - */ - trackCampaignFromUrl(urlString) { - GoogleAnalyticsBridge.trackCampaignFromUrl(this.id, urlString); - } - - /** - * Track an event that has occured - * @param {String} category The event category - * @param {String} action The event action - * @param {Object} optionalValues An object containing optional label and value - */ - trackEvent(category, action, optionalValues = {}) { - GoogleAnalyticsBridge.trackEvent(this.id, category, action, optionalValues); - } - - /** - * Track the current screen/view with custom dimension values - * @param {String} screenName The name of the current screen - * @param {Object} customDimensionValues An object containing custom dimension key/value pairs - */ - trackScreenViewWithCustomDimensionValues(screenName, customDimensionValues) { - const formattedCustomDimensions = this.transformCustomDimensionsFieldsToIndexes(customDimensionValues); - GoogleAnalyticsBridge.trackScreenViewWithCustomDimensionValues(this.id, screenName, formattedCustomDimensions); - } - - /** - * Track an event that has occured with custom dimension values - * @param {String} category The event category - * @param {String} action The event action - * @param {Object} optionalValues An object containing optional label and value - * @param {Object} customDimensionValues An object containing custom dimension key/value pairs - */ - trackEventWithCustomDimensionValues(category, action, optionalValues = {}, customDimensionValues) { - const formattedCustomDimensions = this.transformCustomDimensionsFieldsToIndexes(customDimensionValues); - GoogleAnalyticsBridge.trackEventWithCustomDimensionValues(this.id, category, action, optionalValues, formattedCustomDimensions); - } - /** - * Track an event that has occured with custom dimension and metric values. - * @param {String} category The event category - * @param {String} action The event action - * @param {Object} optionalValues An object containing optional label and value - * @param {Object} customDimensionValues An object containing custom dimension key/value pairs - * @param {Object} customMetricValues An object containing custom metric key/value pairs - */ - trackEventWithCustomDimensionAndMetricValues(category, action, optionalValues = {}, customDimensionValues, customMetricValues) { - GoogleAnalyticsBridge.trackEventWithCustomDimensionAndMetricValues(this.id, category, action, optionalValues, customDimensionValues, customMetricValues); - } - - /** - * Track an event that has occured - * @param {String} category The event category - * @param {Number} value The timing measurement in milliseconds - * @param {Object} optionalValues An object containing optional name and label - */ - trackTiming(category, value, optionalValues = {}) { - GoogleAnalyticsBridge.trackTiming(this.id, category, value, optionalValues); - } - - /** - * Track a purchase event. This uses the Enhanced Ecommerce GA feature. - * @param {Object} product An object with product values - * @param {Object} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - */ - trackPurchaseEvent(product = {}, transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase") { - GoogleAnalyticsBridge.trackPurchaseEvent(this.id, product, transaction, eventCategory, eventAction); - } - - /** - * Track a purchase event. This uses the Enhanced Ecommerce GA feature. - * @param {Array} products An array with products - * @param {Object} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - */ - trackMultiProductsPurchaseEvent(products = [], transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase") { - GoogleAnalyticsBridge.trackMultiProductsPurchaseEvent(this.id, products, transaction, eventCategory, eventAction); - } - - /** - * Track a purchase event with custom dimensions. This uses the Enhanced Ecommerce GA feature. - * @param {Array} products An array with products - * @param {Object} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - * @param {Object} customDimensionValues An object containing custom dimension key/value pairs - */ - trackMultiProductsPurchaseEventWithCustomDimensionValues(products = [], transaction = {}, eventCategory = "Ecommerce", eventAction = "Purchase", customDimensions) { - const formattedCustomDimensions = this.transformCustomDimensionsFieldsToIndexes(customDimensions); - GoogleAnalyticsBridge.trackMultiProductsPurchaseEventWithCustomDimensionValues(this.id, products, transaction, eventCategory, eventAction, formattedCustomDimensions); - } - - /** - * Track an exception - * @param {String} error The description of the error - * @param {Boolean} fatal A value indiciating if the error was fatal, defaults to false - */ - trackException(error, fatal = false) { - GoogleAnalyticsBridge.trackException(this.id, error, fatal); - } - - /** - * Sets the current userId for tracking. - * @param {String} userId The current userId - */ - setUser(userId) { - GoogleAnalyticsBridge.setUser(this.id, userId); - } - - /** - * Sets the current clientId for tracking. - * @param {String} clientId The current userId - */ - setClient(clientId) { - GoogleAnalyticsBridge.setClient(this.id, clientId); - } - - /** - * Get the current clientId. - * @returns {Promise} Returns when done - */ - getClientId() { - return GoogleAnalyticsBridge.getClientId(this.id); - } - - /** - * Sets if IDFA (identifier for advertisers) collection should be enabled - * @param {Boolean} enabled Defaults to true - */ - allowIDFA(enabled = true) { - GoogleAnalyticsBridge.allowIDFA(this.id, enabled); - } - - /** - * Track a social interaction, Facebook, Twitter, etc. - * @param {String} network - * @param {String} action - * @param {String} targetUrl - */ - trackSocialInteraction(network, action, targetUrl) { - GoogleAnalyticsBridge.trackSocialInteraction(this.id, network, action, targetUrl); - } - - /** - * Sets if uncaught exceptions should be tracked - * @param {Boolean} enabled - */ - setTrackUncaughtExceptions(enabled) { - GoogleAnalyticsBridge.setTrackUncaughtExceptions(this.id, enabled); - } - - /** - * Sets the trackers appName - * The Bundle name is used by default - * @param {String} appName - */ - setAppName(appName) { - GoogleAnalyticsBridge.setAppName(this.id, appName); - } - - /** - * Sets the trackers appVersion - * @param {String} appVersion - */ - setAppVersion(appVersion) { - GoogleAnalyticsBridge.setAppVersion(this.id, appVersion); - } - - /** - * Sets if AnonymizeIp is enabled - * If enabled the last octet of the IP address will be removed - * @param {Boolean} enabled - */ - setAnonymizeIp(enabled) { - GoogleAnalyticsBridge.setAnonymizeIp(this.id, enabled); - } - - /** - * Sets tracker sampling rate. - * @param {Float} sampleRatio Percentage 0 - 100 - */ - setSamplingRate(sampleRatio) { - GoogleAnalyticsBridge.setSamplingRate(this.id, sampleRatio); - } - - /** - * Sets the currency for tracking. - * @param {String} currencyCode The currency ISO 4217 code - */ - setCurrency(currencyCode) { - GoogleAnalyticsBridge.setCurrency(this.id, currencyCode); - } - - createNewSession(screenName) { - GoogleAnalyticsBridge.createNewSession(this.id, screenName); - } - - /** - * This function lets you manually dispatch all hits which are queued. - * Use this function sparingly, as it will normally happen automatically - * as a batch. - * @returns {Promise} Returns when done - */ - dispatch() { - return GoogleAnalyticsBridge.dispatch(); - } - - /** - * The same as dispatch(), but also gives you the ability to time out - * the Promise in case dispatch takes too long. - * @param {Number} timeout The timeout. Default value is 15 sec. - * @returns {Promise} Returns when done or timed out - */ - dispatchWithTimeout(timeout = -1) { - if (timeout < 0) { - return GoogleAnalyticsBridge.dispatch(); - } - - let timer = null; - - const withTimeout = timeout => ( - new Promise(resolve => { - timer = setTimeout(() => { - timer = null; - resolve(); - }, Math.min(timeout, DEFAULT_DISPATCH_TIMEOUT)); - }) - ); - - return Promise.race([ - GoogleAnalyticsBridge.dispatch(), - withTimeout(timeout) - ]).then(result => { - if (timer) { - clearTimeout(timer); - } - return result; - }); - } -} diff --git a/src/GoogleAnalyticsTracker.ts b/src/GoogleAnalyticsTracker.ts new file mode 100644 index 00000000..ad5acbca --- /dev/null +++ b/src/GoogleAnalyticsTracker.ts @@ -0,0 +1,390 @@ +import { AnalyticsBridge } from "./NativeBridges"; +import { HitPayload, EventMetadata, TimingMetadata } from "./models/Analytics"; + +import { + CustomDimensionsByField, + CustomDimensionsByIndex, + CustomDimensionsFieldIndexMap +} from "./models/Custom"; + +const DEFAULT_DISPATCH_TIMEOUT = 15000; + +/** + * Custom dimensions accept only strings and numbers. + * @ignore + * @param customDimensionVal + * @returns {boolean} + */ +function isValidCustomDimension(customDimensionVal) { + const customDimensionValType = typeof customDimensionVal; + return ( + customDimensionValType === "string" || customDimensionValType === "number" + ); +} + +/** + * @name GoogleAnalyticsTracker + * @example + * // Constructing a tracker is simple: + * import { GoogleAnalyticsTracker } from "react-native-google-analytics-bridge"; + * const tracker = new GoogleAnalyticsTracker("UA-12345-1"); + * tracker.trackScreenView("Home"); + * + * // You can have multiple trackers if you have several tracking ids + * const tracker2 = new GoogleAnalyticsTracker("UA-12345-2"); + * @example + * // One optional feature as well is constructing a tracker with a CustomDimensionsFieldIndexMap, to map custom dimension field names to index keys: + * const fieldIndexMap = { customerType: 1 }; + * const tracker3 = new GoogleAnalyticsTracker("UA-12345-3", fieldIndexMap); + * + * // This is because the Google Analytics API expects custom dimensions to be tracked by index keys, and not field names. + * // Here the underlying logic will transform the custom dimension, so what ends up being sent to GA is { 1: 'Premium' }: + * tracker3.trackScreenView("Home", { customDimensions: { customerType: "Premium" } }); + * + * // If you do not use a CustomDimensionsFieldIndexMap, you will have to use index as keys instead for custom dimensions: + * tracker.trackScreenView("Home", { customDimensions: { 1: "Premium" } }); + */ +class GoogleAnalyticsTracker { + id: string; + customDimensionsFieldsIndexMap: CustomDimensionsFieldIndexMap; + + /** + * Save all tracker related data that is needed to call native methods with proper data. + * @param {string} trackerId Your tracker id, something like: UA-12345-1 + * @param {{fieldName: fieldIndex}} customDimensionsFieldsIndexMap Custom dimensions field/index pairs + */ + constructor( + trackerId: string, + customDimensionsFieldsIndexMap?: CustomDimensionsFieldIndexMap + ) { + this.id = trackerId; + this.customDimensionsFieldsIndexMap = customDimensionsFieldsIndexMap; + } + + /** + * If Tracker has customDimensionsFieldsIndexMap, it will transform + * customDimensions map pairs {field: value} to {fieldIndex: value}. + * Otherwise customDimensions are passed trough untouched. + * Underlay native methods will transform provided customDimensions map to expected format. + * Google analytics expect dimensions to be tracker with 'dimension{index}' keys, + * not dimension field names. + * @ignore + * @param {{fieldName: value}} customDimensions + * @returns {{fieldIndex: value}} + */ + private transformCustomDimensionsFieldsToIndexes( + customDimensions: CustomDimensionsByField | CustomDimensionsByIndex + ): CustomDimensionsByField | CustomDimensionsByIndex { + if (this.customDimensionsFieldsIndexMap) { + return Object.keys(this.customDimensionsFieldsIndexMap) + .filter(key => isValidCustomDimension(customDimensions[key])) + .reduce((mappedCustomDimensions, key) => { + const dimensionIndex = this.customDimensionsFieldsIndexMap[key]; + mappedCustomDimensions[dimensionIndex] = customDimensions[key]; + return mappedCustomDimensions; + }, {}); + } + return customDimensions; + } + + private transformPayload(payload: HitPayload) { + if (payload && payload.customDimensions) { + let customDimensions = payload.customDimensions; + let transformed = this.transformCustomDimensionsFieldsToIndexes( + customDimensions + ); + payload.customDimensions = transformed; + } + } + + /** + * Track the current screen/view. Calling this will also set the "current view" for other calls. + * So events tracked will be tagged as having occured on the current view, `Home` in this example. + * This means it is important to track navigation, especially if events can fire on different views. + * @example + * tracker.trackScreenView('Home'); + * @example + * // With payload: + * const payload = { impressionList: "Sale", impressionProducts: [ { id: "PW928", name: "Premium bundle" } ] }; + * tracker.trackScreenView("SplashModal", payload); + * @param {string} screenName (Required) The name of the current screen + * @param {HitPayload} payload (Optional) An object containing the hit payload + */ + trackScreenView(screenName: string, payload: HitPayload = null): void { + this.transformPayload(payload); + AnalyticsBridge.trackScreenView(this.id, screenName, payload); + } + + /** + * Track an event that has occured + * @example + * tracker.trackEvent("DetailsButton", "Click"); + * @example + * // Track event with label and value + * tracker.trackEvent("AppVersionButton", "Click", { label: "v1.0.3", value: 22 }); + * @example + * // Track with a payload (ecommerce in this case): + * const product = { + * id: "P12345", + * name: "Android Warhol T-Shirt", + * category: "Apparel/T-Shirts", + * brand: "Google", + * variant: "Black", + * price: 29.2, + * quantity: 1, + * couponCode: "APPARELSALE" + * }; + * const transaction = { + * id: "T12345", + * affiliation: "Google Store - Online", + * revenue: 37.39, + * tax: 2.85, + * shipping: 5.34, + * couponCode: "SUMMER2013" + * }; + * const productAction = { + * transaction, + * action: 7 // Purchase action, see ProductActionEnum + * } + * const payload = { products: [ product ], productAction: productAction } + * tracker.trackEvent("FinalizeOrderButton", "Click", null, payload); + * @param {string} category (Required) The event category + * @param {string} action (Required) The event action + * @param {EventMetadata} eventMetadata (Optional) An object containing event metadata + * @param {HitPayload} payload (Optional) An object containing the hit payload + */ + trackEvent( + category: string, + action: string, + eventMetadata?: EventMetadata, + payload: HitPayload = null + ): void { + this.transformPayload(payload); + AnalyticsBridge.trackEvent( + this.id, + category, + action, + eventMetadata && eventMetadata.label, + eventMetadata && eventMetadata.value, + payload + ); + } + + /** + * Track a timing measurement + * @example + * tracker.trackTiming("testcategory", 2000, { name: "LoadList" }); // name metadata is required + * @example + * // With optional label: + * tracker.trackTiming("testcategory", 2000, { name: "LoadList", label: "v1.0.3" }); + * @example + * @param {string} category (Required) The event category + * @param {number} interval (Required) The timing measurement in milliseconds + * @param {TimingMetadata} timingMetadata (Required) An object containing timing metadata + * @param {HitPayload} payload (Optional) An object containing the hit payload + */ + trackTiming( + category: string, + interval: number, + timingMetadata: TimingMetadata, + payload: HitPayload = null + ): void { + this.transformPayload(payload); + AnalyticsBridge.trackTiming( + this.id, + category, + interval, + timingMetadata.name, + timingMetadata.label, + payload + ); + } + + /** + * Track an exception + * @example + * try { + * ... + * } catch(error) { + * tracker.trackException(error.message, false); + * } + * @param {string} error (Required) The description of the error + * @param {boolean} fatal (Optional) A value indiciating if the error was fatal, defaults to false + * @param {HitPayload} payload (Optional) An object containing the hit payload + */ + trackException( + error: string, + fatal: boolean = false, + payload: HitPayload = null + ): void { + this.transformPayload(payload); + AnalyticsBridge.trackException(this.id, error, fatal, payload); + } + + /** + * Track a social interaction, Facebook, Twitter, etc. + * @example tracker.trackSocialInteraction("Twitter", "Post"); + * @param {string} network + * @param {string} action + * @param {string} targetUrl + * @param {HitPayload} payload (Optional) An object containing the hit payload + */ + trackSocialInteraction( + network: string, + action: string, + targetUrl: string, + payload: HitPayload + ): void { + this.transformPayload(payload); + AnalyticsBridge.trackSocialInteraction( + this.id, + network, + action, + targetUrl, + payload + ); + } + + /** + * Sets the current userId for tracking. + * @example tracker.setUser("12345678"); + * @param {string} userId An anonymous identifier that complies with Google Analytic's user ID policy + */ + setUser(userId: string): void { + AnalyticsBridge.setUser(this.id, userId); + } + + /** + * Sets the current clientId for tracking. + * @example tracker.setClient("35009a79-1a05-49d7-b876-2b884d0f825b"); + * @param {string} clientId A anonymous identifier that complies with Google Analytic's client ID policy + */ + setClient(clientId: string): void { + AnalyticsBridge.setClient(this.id, clientId); + } + + /** + * Get the client id to be used for purpose of logging etc. + * @example tracker.getClientId().then(clientId => console.log("Client id is: ", clientId)); + * @returns {Promise} + */ + getClientId(): Promise { + return AnalyticsBridge.getClientId(this.id); + } + + /** + * Also called advertising identifier collection, and is used for advertising features. + * + * **Important**: For iOS you can only use this method if you have done the optional step 6 from the installation guide. Only enable this (and link the appropriate libraries) if you plan to use advertising features in your app, or else your app may get rejected from the AppStore. + * @example tracker.allowIDFA(true); + * @param {boolean} enabled (Optional) Defaults to true + */ + allowIDFA(enabled: boolean = true): void { + AnalyticsBridge.allowIDFA(this.id, enabled); + } + + /** + * Overrides the app name logged in Google Analytics. The Bundle name is used by default. Note: This has to be set each time the App starts. + * @example tracker.setAppName("YourAwesomeApp"); + * @param {string} appName (Required) + */ + setAppName(appName: string): void { + AnalyticsBridge.setAppName(this.id, appName); + } + + /** + * Sets the trackers appVersion + * @example tracker.setAppVersion("1.3.2"); + * @param {string} appVersion (Required) + */ + setAppVersion(appVersion: string): void { + AnalyticsBridge.setAppVersion(this.id, appVersion); + } + + /** + * Sets if AnonymizeIp is enabled + * If enabled the last octet of the IP address will be removed + * @example tracker.setAnonymizeIp(true); + * @param {boolean} enabled (Required) + */ + setAnonymizeIp(enabled: boolean): void { + AnalyticsBridge.setAnonymizeIp(this.id, enabled); + } + + /** + * Sets tracker sampling rate. + * @example tracker.setSamplingRate(50); + * @param {number} sampleRatio (Required) Percentage 0 - 100 + */ + setSamplingRate(sampleRatio: number): void { + AnalyticsBridge.setSamplingRate(this.id, sampleRatio); + } + + /** + * Sets the currency for tracking. + * @example tracker.setCurrency("EUR"); + * @param {string} currencyCode (Required) The currency ISO 4217 code + */ + setCurrency(currencyCode: string): void { + AnalyticsBridge.setCurrency(this.id, currencyCode); + } + + /** + * Sets if uncaught exceptions should be tracked + * Important to note: On iOS this option is set on all trackers. On Android it is set per tracker. + * If you are using multiple trackers on iOS, this will enable & disable on all trackers. + * @param {boolean} enabled + */ + setTrackUncaughtExceptions(enabled: boolean): void { + AnalyticsBridge.setTrackUncaughtExceptions(this.id, enabled); + } + + /** + * This function lets you manually dispatch all hits which are queued. + * Use this function sparingly, as it will normally happen automatically + * as a batch. This function will also dispatch for all trackers. + * @example tracker.dispatch().then(done => console.log("Dispatch is done: ", done)); + * @returns {Promise} Returns when done + */ + dispatch(): Promise { + return AnalyticsBridge.dispatch(); + } + + /** + * The same as `dispatch`, but also gives you the ability to time out + * the Promise in case dispatch takes too long. + * @example + * tracker + * .dispatchWithTimeout(10000) + * .then(done => console.log("Dispatch is done: ", done)); + * @param {number} timeout The timeout. Default value is 15 sec. + * @returns {Promise} Returns when done or timed out + */ + dispatchWithTimeout(timeout = -1): Promise { + if (timeout < 0) { + return AnalyticsBridge.dispatch(); + } + + let timer = null; + + const withTimeout = (timeout: number): Promise => + new Promise(resolve => { + timer = setTimeout(() => { + timer = null; + resolve(false); + }, Math.min(timeout, DEFAULT_DISPATCH_TIMEOUT)); + }); + + return Promise.race([ + AnalyticsBridge.dispatch(), + withTimeout(timeout) + ]).then(result => { + if (timer) { + clearTimeout(timer); + } + return result; + }); + } +} + +export default GoogleAnalyticsTracker; diff --git a/src/GoogleTagManager.js b/src/GoogleTagManager.js deleted file mode 100644 index 921f4242..00000000 --- a/src/GoogleTagManager.js +++ /dev/null @@ -1,64 +0,0 @@ -import { GoogleTagManagerBridge } from './NativeBridges'; -import FunctionCallTagHandler from './Helpers/FunctionCallTagHandler'; - -export class GoogleTagManager { - /** - * Call once to open the container for all subsequent static calls. - * @param {String} containerId - */ - static openContainerWithId(containerId){ - return GoogleTagManagerBridge.openContainerWithId(containerId); - } - - /** - * Retrieves a boolean value with the given key from the opened container. - * @param {String} key - */ - static boolForKey(key){ - return GoogleTagManagerBridge.booleanForKey(key); - } - - /** - * Retrieves a string with the given key from the opened container. - * @param {String} key - */ - static stringForKey(key){ - return GoogleTagManagerBridge.stringForKey(key); - } - - /** - * Retrieves a number with the given key from the opened container. - * @param {String} key - */ - static doubleForKey(key){ - return GoogleTagManagerBridge.doubleForKey(key); - } - - /** - * push a datalayer event for Google Analytics through Google Tag Manager. - * @param {String} eventName - * @param {Object} dictionary An Map containing key and value pairs. - it must have at least one key "event" with event name - * example: {event: "eventName", pageId: "/home"} - */ - static pushDataLayerEvent(dictionary = {}){ - return GoogleTagManagerBridge.pushDataLayerEvent(dictionary); - } - - /** - * Register Function Call tag handler - * @param {String} functionName - * @param {Function} handler - */ - static registerFunctionCallTagHandler(functionName, handler){ - return FunctionCallTagHandler(GoogleTagManagerBridge, functionName, handler) - } - - /** - * Sets logger to verbose - * @param {Boolean} enabled - */ - static setVerboseLoggingEnabled(enabled){ - return GoogleTagManagerBridge.setVerboseLoggingEnabled(enabled); - } -} diff --git a/src/GoogleTagManager.ts b/src/GoogleTagManager.ts new file mode 100644 index 00000000..25c01814 --- /dev/null +++ b/src/GoogleTagManager.ts @@ -0,0 +1,89 @@ +import DataLayerEvent from "./models/DataLayerEvent"; +import { TagManagerBridge } from "./NativeBridges"; +import FunctionCallTagHandler from "./Helpers/FunctionCallTagHandler"; + +/** + * Can only be used with one container. All functions returns a Promise. + * + * @name GoogleTagManager + * @example + * import { GoogleTagManager } from "react-native-google-analytics-bridge"; + * GoogleTagManager.openContainerWithId("GT-NZT48") + * .then(() => GoogleTagManager.stringForKey("pack")) + * .then(str => console.log("Pack: ", str)); + */ +class GoogleTagManager { + /** + * Call once to open the container for all subsequent static calls. + * @example + * GoogleTagManager.openContainerWithId('GT-NZT48').then((..) => ..) + * @param {string} containerId + * @returns {Promise} + */ + static openContainerWithId(containerId: string): Promise { + return TagManagerBridge.openContainerWithId(containerId); + } + + /** + * Retrieves a boolean value with the given key from the opened container. + * @example GoogleTagManager.boolForKey("key").then(val => console.log(val)); + * @param {string} key + * @returns {Promise} + */ + static boolForKey(key: string): Promise { + return TagManagerBridge.booleanForKey(key); + } + + /** + * Retrieves a string with the given key from the opened container. + * @example GoogleTagManager.stringForKey("key").then(val => console.log(val)); + * @param {string} key + * @returns {Promise} + */ + static stringForKey(key: string): Promise { + return TagManagerBridge.stringForKey(key); + } + + /** + * Retrieves a number with the given key from the opened container. + * @example GoogleTagManager.doubleForKey("key").then(val => console.log(val)); + * @param {string} key + * @returns {Promise} + */ + static doubleForKey(key): Promise { + return TagManagerBridge.doubleForKey(key); + } + + /** + * Push a datalayer event for Google Analytics through Google Tag Manager. The event must have at least one key "event" with event name. + * @example + * GoogleTagManager.pushDataLayerEvent({ + * event: "eventName", + * pageId: "/home" + * }).then(success => console.log(success)); + * @param {DataLayerEvent} event An Map containing key and value pairs. It must have at least one key "event" with event name + * @returns {Promise} + */ + static pushDataLayerEvent(event: DataLayerEvent): Promise { + return TagManagerBridge.pushDataLayerEvent(event); + } + + /** + * Register Function Call tag handler + * @param {String} functionName + * @param {Function} handler + */ + static registerFunctionCallTagHandler(functionName, handler) { + return FunctionCallTagHandler(functionName, handler); + } + + /** + * Sets logger to verbose, default is warning + * @param {boolean} enabled + */ + static setVerboseLoggingEnabled(enabled: boolean): Promise { + return TagManagerBridge.setVerboseLoggingEnabled(enabled); + } +} + +export default GoogleTagManager; diff --git a/src/Helpers/FunctionCallTagHandler/index.android.js b/src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerAndroid.ts similarity index 59% rename from src/Helpers/FunctionCallTagHandler/index.android.js rename to src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerAndroid.ts index 146c8ce6..95f8ba24 100644 --- a/src/Helpers/FunctionCallTagHandler/index.android.js +++ b/src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerAndroid.ts @@ -1,4 +1,6 @@ -import { DeviceEventEmitter } from 'react-native'; +import { DeviceEventEmitter } from "react-native"; +import { TagManagerBridge } from "../../NativeBridges"; +import { Handler } from "./models"; /* * FunctionTagHandler module for Android adds an event listener per each Function Call registration. @@ -9,17 +11,17 @@ import { DeviceEventEmitter } from 'react-native'; * APIs of the module. */ -const TAG_EVENT_PREFIX = 'GTM_FUNCTION_CALL_TAG_'; - -export default (GoogleTagManagerBridge, functionName, handler) => { +const TAG_EVENT_PREFIX = "GTM_FUNCTION_CALL_TAG_"; +export default (functionName: string, handler: Handler): Promise => { const event = TAG_EVENT_PREFIX + functionName; - - return GoogleTagManagerBridge.registerFunctionCallTagHandler(functionName) - .then(() => { - DeviceEventEmitter.addListener(event, (payload) => { + + return TagManagerBridge.registerFunctionCallTagHandler(functionName).then( + () => { + DeviceEventEmitter.addListener(event, payload => { handler(functionName, payload); }); return true; - }); -} + } + ); +}; diff --git a/src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerIOS.ts b/src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerIOS.ts new file mode 100644 index 00000000..6775303f --- /dev/null +++ b/src/Helpers/FunctionCallTagHandler/FunctionCallTagHandlerIOS.ts @@ -0,0 +1,58 @@ +import { NativeEventEmitter } from "react-native"; +import { TagManagerBridge } from "../../NativeBridges"; +import { Handler } from "./models"; + +/* + * FunctionTagHandler module for iOS lazily adds the global event listner the first time a function tag + * needs to be registered. Due to some limitations in native enviroment all Function Call tag events + * from native realm are sent over as GTM_FUNCTION_CALL_TAG event. The event objects + * include _fn (function name) and payload attributes which are passed down to registered + * handlers respectively + */ + +const GTM_FUNCTION_CALL_TAG_EVENT = "GTM_FUNCTION_CALL_TAG"; + +interface Listener { + functionName: string; + handler: Handler; +} + +// Downstream events from native realm +const functionCallTagEventEmitter = new NativeEventEmitter(TagManagerBridge); +const listeners: Array = []; +let listenerRegistered = false; + +// tagEventEmmiter is used to handle callbacks in JS +let jsEventEmitter; + +export default (functionName: string, handler: Handler): Promise => { + if (!listenerRegistered) { + // Register a global listener for Function Tag events + functionCallTagEventEmitter.addListener( + GTM_FUNCTION_CALL_TAG_EVENT, + ({ _fn, payload }) => { + // Pass on the event to listeners + // _fn is basically the same as functionName + jsEventEmitter.emit(_fn, payload); + listeners.forEach(listener => { + if (listener.functionName === _fn) { + handler(_fn, payload); + } + }); + } + ); + + listenerRegistered = true; + } + + return TagManagerBridge.registerFunctionCallTagHandler(functionName).then( + () => { + listeners.push({ + functionName, + handler + }); + + return true; + } + ); +}; diff --git a/src/Helpers/FunctionCallTagHandler/index.ios.js b/src/Helpers/FunctionCallTagHandler/index.ios.js deleted file mode 100644 index e056778d..00000000 --- a/src/Helpers/FunctionCallTagHandler/index.ios.js +++ /dev/null @@ -1,42 +0,0 @@ -import { NativeEventEmitter } from 'react-native'; -import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter'; -import { GoogleTagManagerBridge } from '../../NativeBridges'; - -/* - * FunctionTagHandler module for iOS lazily adds the global event listner the first time a function tag - * needs to be registered. Due to some limitations in native enviroment all Function Call tag events - * from native realm are sent over as GTM_FUNCTION_CALL_TAG event. The event objects - * include _fn (function name) and payload attributes which are passed down to registered - * handlers respectively - */ - -const GTM_FUNCTION_CALL_TAG_EVENT = 'GTM_FUNCTION_CALL_TAG'; - -// Downstream events from native realm -const functionCallTagEventEmitter = new NativeEventEmitter(GoogleTagManagerBridge); - -// tagEventEmmiter is used to handle callbacks in JS -let jsEventEmitter; - -export default (GoogleTagManagerBridge, functionName, handler) => { - - if (!jsEventEmitter) { - // Initialize JS event emitter - jsEventEmitter = new EventEmitter(); - - // Register a global listener for Function Tag events - functionCallTagEventEmitter.addListener(GTM_FUNCTION_CALL_TAG_EVENT, ({_fn, payload}) => { - // Pass on the event JS emitter - // _fn is basically the same as functionName - jsEventEmitter.emit(_fn, payload); - }); - } - - return GoogleTagManagerBridge.registerFunctionCallTagHandler(functionName) - .then(() => { - jsEventEmitter.addListener(functionName, (payload) => { - handler(functionName, payload) - }); - return true; - }); -} diff --git a/src/Helpers/FunctionCallTagHandler/index.ts b/src/Helpers/FunctionCallTagHandler/index.ts new file mode 100644 index 00000000..a6aa5c0e --- /dev/null +++ b/src/Helpers/FunctionCallTagHandler/index.ts @@ -0,0 +1,11 @@ +import { Platform } from "react-native"; +import { RegisterHandler } from "./models"; +import FunctionCallTagHandlerAndroid from "./FunctionCallTagHandlerAndroid"; +import FunctionCallTagHandlerIOS from "./FunctionCallTagHandlerIOS"; + +const FunctionCallTagHandler = Platform.select({ + ios: FunctionCallTagHandlerIOS, + android: FunctionCallTagHandlerAndroid +}); + +export default FunctionCallTagHandler; diff --git a/src/Helpers/FunctionCallTagHandler/models.ts b/src/Helpers/FunctionCallTagHandler/models.ts new file mode 100644 index 00000000..74d9d066 --- /dev/null +++ b/src/Helpers/FunctionCallTagHandler/models.ts @@ -0,0 +1,5 @@ +export type Handler = (functionName: string, tagArguments: any) => any; +export type RegisterHandler = ( + functionName: string, + handler: Handler +) => Promise; diff --git a/src/NativeBridges.js b/src/NativeBridges.js deleted file mode 100644 index 18f546cc..00000000 --- a/src/NativeBridges.js +++ /dev/null @@ -1,2 +0,0 @@ -import { NativeModules } from 'react-native'; -export const { GoogleTagManagerBridge, GoogleAnalyticsBridge } = NativeModules; diff --git a/src/NativeBridges.ts b/src/NativeBridges.ts new file mode 100644 index 00000000..aa42746e --- /dev/null +++ b/src/NativeBridges.ts @@ -0,0 +1,90 @@ +import { HitPayload } from "./models/Analytics"; +import { NativeModules, EventSubscriptionVendor } from "react-native"; +import DataLayerEvent from "./models/DataLayerEvent"; +const { + GoogleTagManagerBridge, + GoogleAnalyticsBridge, + GoogleAnalyticsSettings +} = NativeModules; + +if ( + !GoogleTagManagerBridge || + !GoogleAnalyticsBridge || + !GoogleAnalyticsSettings +) { + console.error( + "Something went wrong initializing the native react-native-google-analytics-bridge module.\nPlease check your configuration.\nDid you forget to run 'react-native link' or install your node_modules?" + ); +} + +export interface IGoogleAnalyticsBridge { + trackScreenView( + trackerId: string, + screenName: string, + payload: HitPayload + ): void; + trackEvent( + trackerId: string, + category: string, + action: string, + label: string, + value: number, + payload: HitPayload + ): void; + trackTiming( + trackerId: string, + category: string, + interval: number, + name: string, + label: string, + payload: HitPayload + ): void; + trackException( + trackerId: string, + error: string, + fatal: boolean, + payload: HitPayload + ): void; + trackSocialInteraction( + trackerId: string, + network: string, + action: string, + targetUrl: string, + payload: HitPayload + ): void; + setUser(trackerId: string, userId: string): void; + setClient(trackerId: string, clientId: string): void; + getClientId(trackerId: string): Promise; + allowIDFA(trackerId: string, enabled: boolean): void; + setSamplingRate(trackerId: string, sampleRate: number): void; + setAnonymizeIp(trackerId: string, enabled: boolean): void; + setAppName(trackerId: string, appName: string): void; + setAppVersion(trackerId: string, appVersion: string): void; + setCurrency(trackerId: string, currencyCode: string): void; + setTrackUncaughtExceptions(trackerId: string, enabled: boolean): void; + dispatch(): Promise; +} + +export interface IGoogleTagManagerBridge extends EventSubscriptionVendor { + openContainerWithId(containerId: string): Promise; + booleanForKey(key: string): Promise; + stringForKey(key: string): Promise; + doubleForKey(key: any): Promise; + pushDataLayerEvent(event: DataLayerEvent): Promise; + registerFunctionCallTagHandler(functionName: string): Promise; + setVerboseLoggingEnabled(enabled: boolean): Promise; +} + +export interface IGoogleAnalyticsSettings { + setOptOut(enabled): void; + setDispatchInterval(intervalInSeconds): void; + setDryRun(enabled): void; +} + +const AnalyticsBridge = GoogleAnalyticsBridge as IGoogleAnalyticsBridge; +const TagManagerBridge = GoogleTagManagerBridge as IGoogleTagManagerBridge; +const AnalyticsSettings = GoogleAnalyticsSettings as IGoogleAnalyticsSettings; + +export { TagManagerBridge }; +export { AnalyticsBridge }; +export { AnalyticsSettings }; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..70a3f6c9 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,17 @@ +export { default as GoogleAnalyticsTracker } from "./GoogleAnalyticsTracker"; +export { default as GoogleAnalyticsSettings } from "./GoogleAnalyticsSettings"; +export { default as GoogleTagManager } from "./GoogleTagManager"; +export { default as DataLayerEvent } from "./models/DataLayerEvent"; +export { + Product, + ProductActionEnum, + ProductAction, + Transaction +} from "./models/Product"; +export { + CustomDimensionsByField, + CustomDimensionsByIndex, + CustomDimensionsFieldIndexMap, + CustomMetrics +} from "./models/Custom"; +export { HitPayload, EventMetadata, TimingMetadata } from "./models/Analytics"; diff --git a/src/models/Analytics.ts b/src/models/Analytics.ts new file mode 100644 index 00000000..5473c9ae --- /dev/null +++ b/src/models/Analytics.ts @@ -0,0 +1,108 @@ +import { + CustomDimensionsByIndex, + CustomMetrics, + CustomDimensionsByField +} from "./Custom"; +import { Product, ProductAction } from "./Product"; + +export interface EventMetadata { + label?: string; + value?: number; +} + +export interface TimingMetadata { + name: string; + label?: string; +} + +export interface HitPayload { + products?: Product[]; + impressionProducts?: Product[]; + impressionList?: string; + impressionSource?: string; + productAction?: ProductAction; + customDimensions?: CustomDimensionsByIndex | CustomDimensionsByField; + customMetrics?: CustomMetrics; + utmCampaignUrl?: string; + session?: SessionState; +} + +export enum SessionState { + Start = "start", + End = "end" +} + +/** + * + * Used when tracking event + * + * @interface EventMetadata + * @example + * const eventMetadata = { label: "v1.0.3", value: 22 } + * tracker.trackEvent("FinalizeOrderButton", "Click", eventMetadata); + * @param {string} label (Optional) + * @param {number} value (Optional) + */ + +/** + * + * Used when tracking time measurements + * + * @interface TimingMetadata + * @example + * const timingMetadata = { name: "LoadList" } // name is a required value when tracking timing + * tracker.trackTiming("testcategory", 13000, timingMetadata); + * @param {string} name (Required) + * @param {string} label (Optional) + */ + +/** + * The HitPayload object and possible values + * + * Used by the different tracking methods for adding metadata to the hit. + * + * @interface HitPayload + * @example + * // If you want to do send a purchase payload with an event: + * const product = { + * id: "P12345", + * name: "Android Warhol T-Shirt", + * category: "Apparel/T-Shirts", + * brand: "Google", + * variant: "Black", + * price: 29.2, + * quantity: 1, + * couponCode: "APPARELSALE" + * }; + * const transaction = { + * id: "T12345", + * affiliation: "Google Store - Online", + * revenue: 37.39, + * tax: 2.85, + * shipping: 5.34, + * couponCode: "SUMMER2013" + * }; + * const productAction = { + * transaction, + * action: 7 // Purchase action, see ProductActionEnum + * } + * const payload = { products: [ product ], productAction: productAction } + * tracker.trackEvent("FinalizeOrderButton", "Click", null, payload); + * @example + * // If you want to send custom dimensions with a screen view: + * const customDimensions = { + * 1: "Beta", + * 3: "Premium" + * }; + * const payload = { customDimensions }; + * tracker.trackScreenView("SaleScreen", payload); + * @param {Product[]} products (Optional) Used for ecommerce + * @param {Product[]} impressionProducts (Optional) Used for ecommerce + * @param {string} impressionList (Optional) Used for ecommerce + * @param {string} impressionSource (Optional) Used for ecommerce + * @param {ProductAction} productAction (Optional) Used for ecommerce + * @param {CustomDimensionsByIndex | CustomDimensionsByField} customDimensions (Optional) + * @param {CustomMetrics} customMetrics (Optional) + * @param {string} utmCampaignUrl (Optional) Used for campaigns + * @param {string} session (Optional) Only two possible values, "start" or "end". This will either start or end a session. + */ diff --git a/src/models/Custom.ts b/src/models/Custom.ts new file mode 100644 index 00000000..33e0baf7 --- /dev/null +++ b/src/models/Custom.ts @@ -0,0 +1,62 @@ +export interface CustomDimensionsFieldIndexMap { + [key: string]: number; +} + +export interface CustomDimensionsByIndex { + [key: number]: number | string | boolean; +} + +export interface CustomDimensionsByField { + [key: string]: number | string | boolean; +} + +export interface CustomMetrics { + [key: number]: number; +} + +/** + * A dictionary describing mapping of field names to indices for custom dimensions. + * This is an optional object used by the tracker. + * @example + * // Create something like: + * const fieldIndexMap = { customerType: 1 }; + * // Construct tracker with it: + * const tracker = new GoogleAnalyticsTracker("UA-12345-3", fieldIndexMap); + * // This allows you to send in customDimensions in the`HitPayload by field name instead of index: + * tracker.trackScreenView("Home", { customDimensions: { customerType: "Premium" } }); + * // If you do not provide a map, you instead have to send in by index: + * tracker.trackScreenView("Home", { customDimensions: { 1: "Premium" } }); + * @see CustomDimensionsFieldIndexMap + * @see CustomDimensionsByField + * @interface CustomDimensionsFieldIndexMap + */ + +/** + * A dictionary with custom dimensions values and their index keys. + * @example + * const customDimensions = { 1: "Premium", 3: "Beta", 5: 1200 } + * tracker.trackScreenView("Home", { customDimensions }); + * @see CustomDimensionsFieldIndexMap + * @see CustomDimensionsByField + * @interface CustomDimensionsByIndex + */ + +/** + * A dictionary with custom dimensions values and their (mapped) field name keys. + * In order to use this and send in custom dimensions by field name, you must have + * provided a `CustomDimensionsFieldIndexMap` when constructing the tracker. + * @example + * const customDimensions = { customerType: "Premium", appType: "Beta", credit: 1200 } + * tracker.trackScreenView("Home", { customDimensions }); + * @see CustomDimensionsFieldIndexMap + * @see CustomDimensionsByIndex + * @interface CustomDimensionsByField + */ + +/** + * A dictionary with custom metric values and their index keys. + * @example + * const customMetrics = { 1: 2389, 4: 15000 } + * tracker.trackScreenView("Home", { customMetrics }); + * @interface CustomMetrics + */ diff --git a/src/models/DataLayerEvent.ts b/src/models/DataLayerEvent.ts new file mode 100644 index 00000000..6162621c --- /dev/null +++ b/src/models/DataLayerEvent.ts @@ -0,0 +1,19 @@ +export default interface DataLayerEvent { + event: string; + [key: string]: any; +} + +/** + * The Google Tag Manager DataLayerEvent dictionary. + * + * Populate this event-object with values to push to the DataLayer. The only required property is `event`. + * @example + * const dataLayerEvent = { + * event: "eventName", + * pageId: "/home" + * }; + * GoogleTagManager.pushDataLayerEvent(dataLayerEvent); + * + * @interface DataLayerEvent + * @param {string} event + */ diff --git a/src/models/Product.ts b/src/models/Product.ts new file mode 100644 index 00000000..2f454f2e --- /dev/null +++ b/src/models/Product.ts @@ -0,0 +1,127 @@ +export interface Product { + id: string; + name: string; + category?: string; + brand?: string; + variant?: string; + price?: number; + couponCode?: string; + quantity?: number; +} + +/** + * Enhanced Ecommerce ProductActionEnum + * + * Used by `ProductAction` when describing the type of product action. The possible values (numbers) are: + * + * * Detail = 1, + * * Click = 2, + * * Add = 3, + * * Remove = 4, + * * Checkout = 5, + * * CheckoutOption = 6, + * * Purchase = 7, + * * Refund = 8 + * + * @export + * @enum {number} + */ +export enum ProductActionEnum { + Detail = 1, + Click = 2, + Add = 3, + Remove = 4, + Checkout = 5, + CheckoutOption = 6, + Purchase = 7, + Refund = 8 +} + +export interface Transaction { + id: string; + affiliation?: string; + revenue?: number; + tax?: number; + shipping?: number; + couponCode?: string; +} + +export interface ProductAction { + action: ProductActionEnum; + transaction?: Transaction; + checkoutStep?: number; + checkoutOption?: string; + productActionList?: string; + productListSource?: string; +} + +/** + * Enhanced Ecommerce Product + * + * Used by `HitPayload` when populating product actions or impressions + * + * @example + * const product = { + * id: "P12345", + * name: "Android Warhol T-Shirt", + * category: "Apparel/T-Shirts", + * brand: "Google", + * variant: "Black", + * price: 29.2, + * quantity: 1, + * couponCode: "APPARELSALE" + * }; + * @interface Product + * @param {string} id + * @param {string} name + * @param {string} category (Optional) + * @param {string} brand (Optional) + * @param {string} variant (Optional) + * @param {number} price (Optional) + * @param {string} couponCode (Optional) + * @param {number} quantity (Optional) + */ + +/** + * Enhanced Ecommerce Transaction + * + * Used by `ProductAction` when populating describing a purchase/transaction + * @example + * const transaction = { + * id: "T12345", + * affiliation: "Google Store - Online", + * revenue: 37.39, + * tax: 2.85, + * shipping: 5.34, + * couponCode: "SUMMER2013" + * }; + * @interface Transaction + * @param {string} id + * @param {string} affiliation (Optional) + * @param {number} revenue (Optional - but not really) + * @param {number} tax (Optional) + * @param {number} shipping (Optional) + * @param {string} couponCode (Optional) + */ + +/** + * Enhanced Ecommerce Product Action + * + * Used by `HitPayload` when describing a product action + * @example + * const productAction = { + * transaction, + * action: 7 // Purchase action, see ProductActionEnum + * } + * @example + * const productAction = { + * action: 3 // Add action, see ProductActionEnum + * } + * @interface ProductAction + * @param {ProductActionEnum} action + * @param {Transaction} transaction (Optional) + * @param {number} checkoutStep (Optional) + * @param {string} checkoutOption (Optional) + * @param {string} productActionList (Optional) + * @param {string} productListSource (Optional) + */ diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d5a0e05c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "es2015", + "moduleResolution": "node", + "declaration": true, + "allowSyntheticDefaultImports": true, + "outDir": "./dist", + "noUnusedLocals": true, + "noImplicitAny": false, + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/types/index.d.ts b/types/index.d.ts deleted file mode 100644 index db56860f..00000000 --- a/types/index.d.ts +++ /dev/null @@ -1,362 +0,0 @@ -export interface Product { - id: string - name: string - category?: string - brand?: string - variant?: string - price?: number - quantity?: number - couponCode?: string -} - -export interface Transaction { - id: string - affiliation?: string - revenue?: number - tax?: number - shipping?: number - couponCode?: string -} - -export interface OptionalValue { - label?: string - value?: number -} - -export interface OptionalTimingValue { - name: string - label?: string -} - -export interface CustomDimensionsFieldIndexMap { - [key: string]: number -} - -export interface CustomDimensionsByIndex { - [key: number]: any -} - -export interface CustomDimensionsByField { - [key: string]: any -} - -export interface CustomMetrics { - [key: number]: number -} - -/** - * Used to bridge tracker data to native Google analytics. - * Saves necessary tracker (specific) data to format data as native part of Google analytics expect. - */ -export class GoogleAnalyticsTracker { - /** - * Save all tracker related data that is needed to call native methods with proper data. - * @param {String} trackerId - * @param {{fieldName: fieldIndex}} customDimensionsFieldsIndexMap Custom dimensions field/index pairs - */ - constructor(trackerId: string, customDimensionsFieldsIndexMap?: CustomDimensionsFieldIndexMap) - - /** - * If Tracker has customDimensionsFieldsIndexMap, it will transform - * customDimensions map pairs {field: value} to {fieldIndex: value}. - * Otherwise customDimensions are passed trough untouched. - * Underlay native methods will transform provided customDimensions map to expected format. - * Google analytics expect dimensions to be tracker with 'dimension{index}' keys, - * not dimension field names. - * @param {CustomDimensionsByIndex} customDimensions - * @returns {CustomDimensionsByField} - */ - transformCustomDimensionsFieldsToIndexes(customDimensions: CustomDimensionsByIndex): CustomDimensionsByField - - /** - * Track the current screen/view - * @param {String} screenName The name of the current screen - */ - trackScreenView(screenName: string): void - - /** - * Track the campaign from url - * @param {String} urlString The url of the deep link - */ - trackCampaignFromUrl(urlString: string): void - - /** - * Track an event that has occured - * @param {String} category The event category - * @param {String} action The event action - * @param {OptionalValue} optionalValues An object containing optional label and value - */ - trackEvent(category: string, action: string, optionalValues?: OptionalValue): void - - /** - * Track the current screen/view with custom dimension values - * @param {String} screenName The name of the current screen - * @param {CustomDimensionsByIndex | CustomDimensionsByField} customDimensionValues An object containing custom dimension key/value pairs - */ - trackScreenViewWithCustomDimensionValues( - screenName: string, - customDimensionValues: CustomDimensionsByIndex | CustomDimensionsByField - ): void - - /** - * Track an event that has occured with custom dimension values - * @param {String} category The event category - * @param {String} action The event action - * @param {OptionalValue} optionalValues An object containing optional label and value - * @param {CustomDimensionsByIndex | CustomDimensionsByField} customDimensionValues An object containing custom dimension key/value pairs - */ - trackEventWithCustomDimensionValues( - category: string, - action: string, - optionalValues?: OptionalValue, - customDimensionValues?: CustomDimensionsByIndex | CustomDimensionsByField - ): void - /** - * Track an event that has occured with custom dimension and metric values. - * @param {String} category The event category - * @param {String} action The event action - * @param {OptionalValue} optionalValues An object containing optional label and value - * @param {CustomDimensionsByIndex | CustomDimensionsByField} customDimensionValues An object containing custom dimension key/value pairs - * @param {CustomMetrics} customMetricValues An object containing custom metric key/value pairs - */ - trackEventWithCustomDimensionAndMetricValues( - category: string, - action: string, - optionalValues?: OptionalValue, - customDimensionValues?: CustomDimensionsByIndex | CustomDimensionsByField, - customMetricValues?: CustomMetrics - ): void - - /** - * Track an event that has occured - * @param {String} category The event category - * @param {Number} value The timing measurement in milliseconds - * @param {OptionalTimingValue} optionalValues An object containing optional name and label - */ - trackTiming(category: string, value: number, optionalValues: OptionalTimingValue): void - - /** - * Track a purchase event. This uses the Enhanced Ecommerce GA feature. - * @param {Product} product An object with product values - * @param {Transaction} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - */ - trackPurchaseEvent( - product: Product, - transaction: Transaction, - eventCategory?: string, - eventAction?: string - ): void - - /** - * Track a purchase event. This uses the Enhanced Ecommerce GA feature. - * @param {Product[]} products An array with products - * @param {Transaction} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - */ - trackMultiProductsPurchaseEvent( - products: Product[], - transaction: Transaction, - eventCategory?: string, - eventAction?: string - ): void - - /** - * Track a purchase event with custom dimensions. This uses the Enhanced Ecommerce GA feature. - * @param {Product[]} products An array with products - * @param {Transaction} transaction An object with transaction values - * @param {String} eventCategory The event category, defaults to Ecommerce - * @param {String} eventAction The event action, defaults to Purchase - * @param {CustomDimensionsByIndex | CustomDimensionsByField} customDimensionValues An object containing custom dimension key/value pairs - */ - trackMultiProductsPurchaseEventWithCustomDimensionValues( - products: Product[], - transaction: Transaction, - eventCategory?: string, - eventAction?: string, - customDimensions?: CustomDimensionsByIndex | CustomDimensionsByField - ): void - - /** - * Track an exception - * @param {String} error The description of the error - * @param {Boolean} fatal A value indiciating if the error was fatal, defaults to false - */ - trackException(error: string, fatal?: boolean): void - - /** - * Sets the current userId for tracking. - * @param {String} userId The current userId - */ - setUser(userId: string): void - - /** - * Sets the current clientId for tracking. - * @param {String} clientId The current userId - */ - setClient(clientId: string): void - - /** - * Sets if IDFA (identifier for advertisers) collection should be enabled - * @param {Boolean} enabled Defaults to true - */ - allowIDFA(enabled: boolean): void - - /** - * Track a social interaction, Facebook, Twitter, etc. - * @param {String} network - * @param {String} action - * @param {String} targetUrl - */ - trackSocialInteraction( - network: string, - action: string, - targetUrl: string - ): void - - /** - * Sets if uncaught exceptions should be tracked - * @param {Boolean} enabled - */ - setTrackUncaughtExceptions(enabled: boolean): void - - /** - * Sets the trackers appName - * The Bundle name is used by default - * @param {String} appName - */ - setAppName(appName: string): void - - /** - * Sets the trackers appVersion - * @param {String} appVersion - */ - setAppVersion(appVersion: string): void - - /** - * Sets if AnonymizeIp is enabled - * If enabled the last octet of the IP address will be removed - * @param {Boolean} enabled - */ - setAnonymizeIp(enabled: boolean): void - /** - * Sets tracker sampling rate. - * @param {Float} sampleRatio Percentage 0 - 100 - */ - setSamplingRate(sampleRatio: number): void - - /** - * Sets the currency for tracking. - * @param {String} currencyCode The currency ISO 4217 code - */ - setCurrency(currencyCode: string): void - - /** - * This function lets you create a session manually. By default, Google Analytics will group hits that are received - * within 30 minutes of one another into the same session. So it is strictly not necessary to create a session manually. - * @param {String} screenName The current screen which the session started on - */ - createNewSession(screenName: string): void - - /** - * This function lets you manually dispatch all hits which are queued. - * Use this function sparingly, as it will normally happen automatically - * as a batch. - * @returns {Promise} Returns when done - */ - dispatch(): Promise - - /** - * The same as dispatch(), but also gives you the ability to time out - * the Promise in case dispatch takes too long. - * @param {Number} timeout The timeout. Default value is 15 sec. - * @returns {Promise} Returns when done or timed out - */ - dispatchWithTimeout(timeout?: number): Promise -} - -/** - * Google analytics settings shared across all GoogleAnalyticsTracker instances. - */ -export class GoogleAnalyticsSettings { - /** - * Sets if OptOut is active and disables Google Analytics - * This has to be set each time the App starts - * @param {Boolean} enabled - */ - static setOptOut(enabled: boolean): void - - /** - * Sets the trackers dispatch interval - * This will influence how often batches of events, screen views, etc - * are sent to your tracker. - * @param {Number} intervalInSeconds - */ - static setDispatchInterval(intervalInSeconds: number): void - - /** - * Sets if the tracker should have dry run enabled. - * If dry run is enabled, no analytics data will be sent to your tracker. - * @param {Boolean} enabled - */ - static setDryRun(enabled: boolean): void -} - -export interface DataLayerEvent { - event: string - [key: string]: any -} - -export class GoogleTagManager { - /** - * Call once to open the container for all subsequent static calls. - * @param {String} containerId - * @returns {Promise} - */ - static openContainerWithId(containerId: string): Promise - - /** - * Retrieves a boolean value with the given key from the opened container. - * @param {String} key - * @returns {Promise} - */ - static boolForKey(key: string): Promise - - /** - * Retrieves a string with the given key from the opened container. - * @param {String} key - * @returns {String} - */ - static stringForKey(key: string): Promise - - /** - * Retrieves a number with the given key from the opened container. - * @param {String} key - * @returns {Promise} - */ - static doubleForKey(key: string): Promise - - /** - * Push a datalayer event for Google Analytics through Google Tag Manager. The event must have at least one key "event" with event name. - * You can add optional values on top of that, example: {event: "eventName", pageId: "/home"} - * @param {Object} event An Map containing key and value pairs. It must have at least one key "event" with event name - * @returns {Promise} - */ - static pushDataLayerEvent(event: DataLayerEvent): Promise - - /** - * Sets logger to verbose - * @param {Boolean} enabled - * @returns {Promise} - */ - static setVerboseLoggingEnabled(enabled: boolean): Promise - - /** - * Register Function Call tag handler - * @param {String} functionName - * @param {Function} handler - */ - static registerFunctionCallTagHandler(functionName: string, handler: (functionName: string, tagArguments: any) => any): Promise -} diff --git a/types/tsconfig.json b/types/tsconfig.json deleted file mode 100644 index aaa52285..00000000 --- a/types/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "lib": ["es6"], - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "strictFunctionTypes": false, - "noEmit": true, - "baseUrl": ".", - "paths": { "react-native-google-analytics-bridge": ["."] } - } -} diff --git a/types/tslint.json b/types/tslint.json deleted file mode 100644 index 48fe3bcd..00000000 --- a/types/tslint.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "dtslint/dtslint.json", - "rules": { - "semicolon": false, - "indent": [true, "spaces"], - "no-redundant-jsdoc": false, - "no-unnecessary-class": false, - "no-implicit-dependencies": false, - "file-name-casing": false - } -} diff --git a/types/type-tests.ts b/types/type-tests.ts deleted file mode 100644 index fe652976..00000000 --- a/types/type-tests.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - GoogleAnalyticsTracker, - GoogleTagManager, - GoogleAnalyticsSettings -} from "react-native-google-analytics-bridge"; - -const tracker = new GoogleAnalyticsTracker("trackerId"); - -// $ExpectType void -tracker.trackScreenView("Home"); - -// $ExpectType void -tracker.trackEvent("MyEvent", "MyAction"); - -// $ExpectType Promise -tracker.dispatch(); - -// $ExpectType void -GoogleAnalyticsSettings.setDispatchInterval(30); - -// $ExpectType void -GoogleAnalyticsSettings.setDryRun(false); - -// $ExpectType void -GoogleAnalyticsSettings.setOptOut(false); - -// $ExpectType Promise -GoogleTagManager.openContainerWithId("containerId"); - -// $ExpectType Promise -GoogleTagManager.doubleForKey("someKey"); - -// $ExpectType Promise -GoogleTagManager.boolForKey("someKey"); - -// $ExpectType Promise -GoogleTagManager.stringForKey("someKey"); - -// $ExpectType Promise -GoogleTagManager.setVerboseLoggingEnabled(true); - -// $ExpectType Promise -GoogleTagManager.pushDataLayerEvent({ - event: "myEvent", - someKey: "myKey", - metadata: { - id: 1200 - } -}); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..439de387 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3811 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + +"@types/react-native@0.55.4": + version "0.55.4" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.55.4.tgz#866005d86490e2fd60543b143b2a5ac208aa925b" + dependencies: + "@types/react" "*" + +"@types/react@*": + version "16.4.1" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.1.tgz#c53bbfb4a78933db587da085ac60dbf5fcf73f8f" + dependencies: + csstype "^2.2.0" + +"@types/react@16.3.1": + version "16.3.1" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.1.tgz#6f6aaffaf7dba502ff5ca15e4aa18caee9b04995" + +JSONStream@^1.0.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.3.tgz#27b4b8fbbfeab4e71bcf551e7f27be8d952239bf" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +acorn@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + +ansi-html@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.0.1, ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + dependencies: + buffer-equal "^1.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-iterate@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.2.tgz#f66a57e84426f8097f4197fbb6c051b8e5cdf7d8" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +assertion-error@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +atob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-constructor-call@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-do-expressions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-function-bind@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-system-import-transformer@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-system-import-transformer/-/babel-plugin-system-import-transformer-3.1.0.tgz#d37f0cae8e61ef39060208331d931b5e630d7c5f" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-constructor-call@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators-legacy@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz#0e492dffa0edd70529072887f8aa86d4dd8b40a1" + dependencies: + babel-plugin-syntax-decorators "^6.1.18" + babel-runtime "^6.2.0" + babel-template "^6.3.0" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-do-expressions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz#28ccaf92812d949c2cd1281f690c8fdc468ae9bb" + dependencies: + babel-plugin-syntax-do-expressions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-export-extensions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" + dependencies: + babel-plugin-syntax-export-extensions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-function-bind@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz#c6fb8e96ac296a310b8cf8ea401462407ddf6a97" + dependencies: + babel-plugin-syntax-function-bind "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-react@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-preset-stage-0@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz#5642d15042f91384d7e5af8bc88b1db95b039e6a" + dependencies: + babel-plugin-transform-do-expressions "^6.22.0" + babel-plugin-transform-function-bind "^6.22.0" + babel-preset-stage-1 "^6.24.1" + +babel-preset-stage-1@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" + dependencies: + babel-plugin-transform-class-constructor-call "^6.24.1" + babel-plugin-transform-export-extensions "^6.22.0" + babel-preset-stage-2 "^6.24.1" + +babel-preset-stage-2@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babelify@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +bail@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +binary-extensions@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + +body@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" + dependencies: + continuable-cache "^0.3.1" + error "^7.0.0" + raw-body "~1.1.0" + safe-json-parse "~1.0.1" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browser-resolve@^1.7.0: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + dependencies: + resolve "1.1.7" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + +buffer-from@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +bytes@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caniuse-lite@^1.0.30000844: + version "1.0.30000858" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000858.tgz#f6f203a9128bac507136de1cf6cfd966d2df027c" + +ccount@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" + +chai@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^3.0.0" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +character-entities-html4@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610" + +character-entities-legacy@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c" + +character-entities@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363" + +character-reference-invalid@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed" + +check-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + +chokidar@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +ci-info@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + dependencies: + mimic-response "^1.0.0" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + dependencies: + color-name "1.1.1" + +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + +comma-separated-tokens@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.5.tgz#b13793131d9ea2d2431cf5b507ddec258f0ce0db" + dependencies: + trim "0.0.1" + +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concat-stream@~1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +continuable-cache@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" + +convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +csstype@^2.2.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.5.5.tgz#4125484a3d42189a863943f23b9e4b80fedfa106" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + +debug@3.1.0, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + +deep-eql@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + dependencies: + type-detect "^4.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detab@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.1.tgz#531f5e326620e2fd4f03264a905fb3bcc8af4df4" + dependencies: + repeat-string "^1.5.4" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detective@^4.0.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +diff@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + +diff@^1.3.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +disparity@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/disparity/-/disparity-2.0.0.tgz#57ddacb47324ae5f58d2cc0da886db4ce9eeb718" + dependencies: + ansi-styles "^2.0.1" + diff "^1.3.2" + +doctrine-temporary-fork@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/doctrine-temporary-fork/-/doctrine-temporary-fork-2.0.1.tgz#23f0b6275c65f48893324b02338178e496b2e4bf" + dependencies: + esutils "^2.0.2" + +documentation@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/documentation/-/documentation-8.0.0.tgz#075a05d30d47256c1defd710f3d5346220639822" + dependencies: + ansi-html "^0.0.7" + babel-core "^6.26.0" + babel-generator "^6.26.0" + babel-plugin-system-import-transformer "3.1.0" + babel-plugin-transform-decorators-legacy "^1.3.4" + babel-preset-env "^1.6.1" + babel-preset-react "^6.24.1" + babel-preset-stage-0 "^6.24.1" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babelify "^8.0.0" + babylon "^6.18.0" + chalk "^2.3.0" + chokidar "^2.0.0" + concat-stream "^1.6.0" + disparity "^2.0.0" + doctrine-temporary-fork "2.0.1" + get-port "^3.2.0" + git-url-parse "^9.0.0" + github-slugger "1.2.0" + glob "^7.1.2" + globals-docs "^2.4.0" + highlight.js "^9.12.0" + js-yaml "^3.10.0" + lodash "^4.17.10" + mdast-util-inject "^1.1.0" + micromatch "^3.1.5" + mime "^2.2.0" + module-deps-sortable "4.0.6" + parse-filepath "^1.0.2" + pify "^3.0.0" + read-pkg-up "^3.0.0" + remark "^9.0.0" + remark-html "7.0.0" + remark-reference-links "^4.0.1" + remark-toc "^5.0.0" + remote-origin-url "0.4.0" + stream-array "^1.1.2" + strip-json-comments "^2.0.1" + tiny-lr "^1.1.0" + unist-builder "^1.0.2" + unist-util-visit "^1.3.0" + vfile "^2.3.0" + vfile-reporter "^4.0.0" + vfile-sort "^2.1.0" + vinyl "^2.1.0" + vinyl-fs "^3.0.2" + vue-template-compiler "^2.5.16" + yargs "^9.0.1" + +duplexer2@^0.1.2, duplexer2@~0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexify@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +electron-to-chromium@^1.3.47: + version "1.3.50" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.50.tgz#7438b76f92b41b919f3fbdd350fbd0757dacddf7" + +"emoji-regex@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +error@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" + dependencies: + string-template "~0.2.1" + xtend "~4.0.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flush-write-stream@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-copy-file-sync@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz#11bf32c096c10d126e5f6b36d06eece776062918" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +git-up@^2.0.0: + version "2.0.10" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-2.0.10.tgz#20fe6bafbef4384cae253dc4f463c49a0c3bd2ec" + dependencies: + is-ssh "^1.3.0" + parse-url "^1.3.0" + +git-url-parse@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-9.0.1.tgz#2905b897a3db6e5cb9e10819f0fac2e740b4481b" + dependencies: + git-up "^2.0.0" + parse-domain "^2.0.0" + +github-slugger@1.2.0, github-slugger@^1.0.0, github-slugger@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.0.tgz#8ada3286fd046d8951c3c952a8d7854cfd90fd9a" + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob@7.1.2, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals-docs@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/globals-docs/-/globals-docs-2.4.0.tgz#f2c647544eb6161c7c38452808e16e693c2dafbb" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +got@^8.0.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.1.tgz#093324403d4d955f5a16a7a8d39955d055ae10ed" + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hast-util-is-element@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.0.1.tgz#c76e8aafbdb6e5c83265bf50324e2f2e024eb12a" + +hast-util-sanitize@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-1.2.0.tgz#1a46bc8e8554f4747d219dd1d85f9cb245b1b08d" + dependencies: + xtend "^4.0.1" + +hast-util-to-html@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-3.1.0.tgz#882c99849e40130e991c042e456d453d95c36cff" + dependencies: + ccount "^1.0.0" + comma-separated-tokens "^1.0.1" + hast-util-is-element "^1.0.0" + hast-util-whitespace "^1.0.0" + html-void-elements "^1.0.0" + kebab-case "^1.0.0" + property-information "^3.1.0" + space-separated-tokens "^1.0.0" + stringify-entities "^1.0.1" + unist-util-is "^2.0.0" + xtend "^4.0.1" + +hast-util-whitespace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.1.tgz#d67da2c87637b1ce1d85dd15b270ba057930149a" + +he@1.1.1, he@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + +highlight.js@^9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" + +html-void-elements@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.3.tgz#956707dbecd10cf658c92c5d27fee763aa6aa982" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + +http-parser-js@>=0.4.0: + version "0.4.13" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" + +husky@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" + dependencies: + is-ci "^1.0.10" + normalize-path "^1.0.0" + strip-indent "^2.0.0" + +iconv-lite@^0.4.4: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.3.3, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-alphabetical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41" + +is-alphanumeric@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" + +is-alphanumerical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40" + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.4, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-decimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.0" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + dependencies: + is-unc-path "^1.0.0" + +is-retry-allowed@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-ssh@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.0.tgz#ebea1169a2614da392a63740366c3ce049d8dff6" + dependencies: + protocols "^1.1.0" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + +is-whitespace-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +is-word-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.10.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + +json-stable-stringify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + +kebab-case@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.0.tgz#3f9e4990adcad0c686c0e701f7645868f75f91eb" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + dependencies: + flush-write-stream "^1.0.2" + +livereload-js@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash@^4.17.10, lodash@^4.17.4: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +longest-streak@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + +lru-cache@^4.0.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +markdown-escapes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122" + +markdown-table@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786" + +mdast-util-compact@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz#cdb5f84e2b6a2d3114df33bd05d9cb32e3c4083a" + dependencies: + unist-util-modify-children "^1.0.0" + unist-util-visit "^1.1.0" + +mdast-util-definitions@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.2.tgz#673f4377c3e23d3de7af7a4fe2214c0e221c5ac7" + dependencies: + unist-util-visit "^1.0.0" + +mdast-util-inject@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz#db06b8b585be959a2dcd2f87f472ba9b756f3675" + dependencies: + mdast-util-to-string "^1.0.0" + +mdast-util-to-hast@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-3.0.1.tgz#0f91a2d3e3f9415705c0849ff8c2cbe5cc73b307" + dependencies: + collapse-white-space "^1.0.0" + detab "^2.0.0" + mdast-util-definitions "^1.2.0" + mdurl "^1.0.1" + trim "0.0.1" + trim-lines "^1.0.0" + unist-builder "^1.0.1" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.0" + xtend "^4.0.1" + +mdast-util-to-string@^1.0.0, mdast-util-to-string@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.4.tgz#5c455c878c9355f0c1e7f3e8b719cf583691acfb" + +mdast-util-toc@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-2.0.1.tgz#b1d2cb23bfb01f812fa7b55bffe8b0a8bedf6f21" + dependencies: + github-slugger "^1.1.1" + mdast-util-to-string "^1.0.2" + unist-util-visit "^1.1.0" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +micromatch@^3.1.4, micromatch@^3.1.5: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +mimic-response@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + +module-deps-sortable@4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz#1251a4ba2c44a92df6989bd029da121a4f2109b0" + dependencies: + JSONStream "^1.0.3" + browser-resolve "^1.7.0" + concat-stream "~1.5.0" + defined "^1.0.0" + detective "^4.0.0" + duplexer2 "^0.1.2" + inherits "^2.0.1" + parents "^1.0.0" + readable-stream "^2.0.2" + resolve "^1.1.3" + stream-combiner2 "^1.1.1" + subarg "^1.0.0" + through2 "^2.0.0" + xtend "^4.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +nan@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-odd "^2.0.0" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +node-pre-gyp@^0.10.0: + version "0.10.2" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.2.tgz#e8945c20ef6795a20aac2b44f036eb13cf5146e3" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.0" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +now-and-later@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" + dependencies: + once "^1.3.2" + +npm-bundled@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + +npm-packlist@^1.1.6: + version "1.1.10" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.11, object-keys@^1.0.8: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + dependencies: + readable-stream "^2.0.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +parents@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" + dependencies: + path-platform "~0.11.15" + +parse-domain@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/parse-domain/-/parse-domain-2.1.2.tgz#8c536bdecf7a9af01bb6d7ad30eb794791d6c2c7" + dependencies: + chai "^4.1.2" + fs-copy-file-sync "^1.1.1" + got "^8.0.1" + mkdirp "^0.5.1" + mocha "^4.0.1" + +parse-entities@^1.0.2, parse-entities@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.2.tgz#9eaf719b29dc3bd62246b4332009072e01527777" + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-filepath@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-git-config@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-0.2.0.tgz#272833fdd15fea146fb75d336d236b963b6ff706" + dependencies: + ini "^1.3.3" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-url@^1.3.0: + version "1.3.11" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.11.tgz#57c15428ab8a892b1f43869645c711d0e144b554" + dependencies: + is-ssh "^1.3.0" + protocols "^1.4.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-platform@~0.11.15: + version "0.11.15" + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + dependencies: + path-root-regex "^0.1.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + +prettier@^1.6.1: + version "1.13.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.5.tgz#7ae2076998c8edce79d63834e9b7b09fead6bfd0" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +property-information@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.2.0.tgz#fd1483c8fbac61808f5fe359e7693a1f48a58331" + +protocols@^1.1.0, protocols@^1.4.0: + version "1.4.6" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.6.tgz#f8bb263ea1b5fd7a7604d26b8be39bd77678bf8a" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +qs@^6.4.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +raw-body@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" + dependencies: + bytes "1" + string_decoder "0.10" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.0: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remark-html@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/remark-html/-/remark-html-7.0.0.tgz#d13dc1ba9352e257fce8800c42c7690d9e3690c8" + dependencies: + hast-util-sanitize "^1.0.0" + hast-util-to-html "^3.0.0" + mdast-util-to-hast "^3.0.0" + xtend "^4.0.1" + +remark-parse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95" + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.1.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + +remark-reference-links@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/remark-reference-links/-/remark-reference-links-4.0.1.tgz#021aed1c55c187d712b3c76d0057bf510d300ba7" + dependencies: + unist-util-visit "^1.0.0" + +remark-slug@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-5.0.0.tgz#9de71fcdc2bfae33ebb4a41eb83035288a829980" + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^1.0.0" + +remark-stringify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-5.0.0.tgz#336d3a4d4a6a3390d933eeba62e8de4bd280afba" + dependencies: + ccount "^1.0.0" + is-alphanumeric "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + longest-streak "^2.0.1" + markdown-escapes "^1.0.0" + markdown-table "^1.1.0" + mdast-util-compact "^1.0.0" + parse-entities "^1.0.2" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + stringify-entities "^1.0.1" + unherit "^1.0.4" + xtend "^4.0.1" + +remark-toc@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-toc/-/remark-toc-5.0.0.tgz#f1e13ed11062ad4d102b02e70168bd85015bf129" + dependencies: + mdast-util-toc "^2.0.0" + remark-slug "^5.0.0" + +remark@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark/-/remark-9.0.0.tgz#c5cfa8ec535c73a67c4b0f12bfdbd3a67d8b2f60" + dependencies: + remark-parse "^5.0.0" + remark-stringify "^5.0.0" + unified "^6.0.0" + +remote-origin-url@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/remote-origin-url/-/remote-origin-url-0.4.0.tgz#4d3e2902f34e2d37d1c263d87710b77eb4086a30" + dependencies: + parse-git-config "^0.2.0" + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.0, repeat-string@^1.5.4, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +replace-ext@1.0.0, replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + dependencies: + path-parse "^1.0.5" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + dependencies: + lowercase-keys "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-json-parse@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + dependencies: + is-plain-obj "^1.0.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +space-separated-tokens@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.2.tgz#e95ab9d19ae841e200808cd96bc7bd0adbbb3412" + dependencies: + trim "0.0.1" + +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +state-toggle@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-array@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/stream-array/-/stream-array-1.1.2.tgz#9e5f7345f2137c30ee3b498b9114e80b52bb7eb5" + dependencies: + readable-stream "~2.1.0" + +stream-combiner2@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" + dependencies: + duplexer2 "~0.1.0" + readable-stream "^2.0.2" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + +string-template@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + +string-width@^1.0.0, string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@0.10, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +stringify-entities@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.2.tgz#a98417e5471fd227b3e45d3db1861c11caf668f7" + dependencies: + character-entities-html4 "^1.0.0" + character-entities-legacy "^1.0.0" + is-alphanumerical "^1.0.0" + is-hexadecimal "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +subarg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + dependencies: + minimist "^1.1.0" + +supports-color@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + +tar@^4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +through2-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +"through@>=2.2.7 <3": + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +tiny-lr@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab" + dependencies: + body "^5.1.0" + debug "^3.1.0" + faye-websocket "~0.10.0" + livereload-js "^2.3.0" + object-assign "^4.1.0" + qs "^6.4.0" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + dependencies: + through2 "^2.0.3" + +trim-lines@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.1.tgz#da738ff58fa74817588455e30b11b85289f2a396" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +trim-trailing-lines@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9" + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + +trough@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.2.tgz#7f1663ec55c480139e2de5e486c6aef6cc24a535" + +type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + +typedarray@^0.0.6, typedarray@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +typescript@^2.5.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + +unherit@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c" + dependencies: + inherits "^2.0.1" + xtend "^4.0.1" + +unified@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba" + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^1.1.0" + trough "^1.0.0" + vfile "^2.0.0" + x-is-string "^0.1.0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-stream@^2.0.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + dependencies: + json-stable-stringify "^1.0.0" + through2-filter "^2.0.0" + +unist-builder@^1.0.1, unist-builder@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.2.tgz#8c3b9903ef64bcfb117dd7cf6a5d98fc1b3b27b6" + dependencies: + object-assign "^4.1.0" + +unist-util-generated@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.2.tgz#8b993f9239d8e560be6ee6e91c3f7b7208e5ce25" + +unist-util-is@^2.0.0, unist-util-is@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" + +unist-util-modify-children@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.2.tgz#c7f1b91712554ee59c47a05b551ed3e052a4e2d1" + dependencies: + array-iterate "^1.0.0" + +unist-util-position@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.0.1.tgz#8e220c24658239bf7ddafada5725ed0ea1ebbc26" + +unist-util-remove-position@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz#86b5dad104d0bbfbeb1db5f5c92f3570575c12cb" + dependencies: + unist-util-visit "^1.1.0" + +unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" + +unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.1.tgz#c019ac9337a62486be58531bc27e7499ae7d55c7" + dependencies: + unist-util-is "^2.1.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + +use@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" + dependencies: + kind-of "^6.0.2" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +validate-npm-package-license@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + +vfile-location@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.3.tgz#083ba80e50968e8d420be49dd1ea9a992131df77" + +vfile-message@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.1.tgz#51a2ccd8a6b97a7980bb34efb9ebde9632e93677" + dependencies: + unist-util-stringify-position "^1.1.1" + +vfile-reporter@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-4.0.0.tgz#ea6f0ae1342f4841573985e05f941736f27de9da" + dependencies: + repeat-string "^1.5.0" + string-width "^1.0.0" + supports-color "^4.1.0" + unist-util-stringify-position "^1.0.0" + vfile-statistics "^1.1.0" + +vfile-sort@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-2.1.1.tgz#03acdc8a4d7870ecf0e35499f095ddd9d14cbc41" + +vfile-statistics@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-1.1.1.tgz#a22fd4eb844c9eaddd781ad3b3246db88375e2e3" + +vfile@^2.0.0, vfile@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a" + dependencies: + is-buffer "^1.1.4" + replace-ext "1.0.0" + unist-util-stringify-position "^1.0.0" + vfile-message "^1.0.0" + +vinyl-fs@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl@^2.0.0, vinyl@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vue-template-compiler@^2.5.16: + version "2.5.16" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb" + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +websocket-driver@>=0.5.1: + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + dependencies: + http-parser-js ">=0.4.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +x-is-string@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0"