From 17d778cf6659dba2fb9ff712b19944681531bf34 Mon Sep 17 00:00:00 2001 From: Michael Diarmid Date: Fri, 1 Feb 2019 10:37:48 +0000 Subject: [PATCH] Refactor into monorepo for v6 (#1837) > You can [learn more about this here](https://blog.invertase.io/react-native-firebase-2019-7e334ca9bcc6). --- .buckconfig | 9 + .circleci/config.yml | 497 +- .circleci/scripts/wait-for-avd.sh | 6 +- .eslintignore | 7 + .eslintrc | 48 +- .flowconfig | 39 +- .gitattributes | 2 + .github/ISSUE_TEMPLATE.md | 4 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/stale.yml | 1 - .gitignore | 594 +- .prettierignore | 3 + .prettierrc | 20 + .watchmanconfig | 1 + LICENSE | 23 +- README.md | 149 +- android/.editorconfig | 10 - android/build.gradle | 199 - android/src/main/AndroidManifest.xml | 7 - .../io/invertase/firebase/ErrorUtils.java | 27 - .../invertase/firebase/RNFirebaseModule.java | 182 - .../invertase/firebase/RNFirebasePackage.java | 41 - .../java/io/invertase/firebase/Utils.java | 193 - .../firebase/admob/RNFirebaseAdMob.java | 112 - .../firebase/admob/RNFirebaseAdMobBanner.java | 257 - .../admob/RNFirebaseAdMobNativeExpress.java | 302 - .../admob/RNFirebaseAdMobPackage.java | 41 - .../admob/RNFirebaseAdMobRewardedVideo.java | 140 - .../firebase/admob/RNFirebaseAdMobUtils.java | 160 - .../admob/RNFirebaseAdmobInterstitial.java | 110 - .../analytics/RNFirebaseAnalytics.java | 111 - .../analytics/RNFirebaseAnalyticsPackage.java | 43 - .../firebase/auth/RNFirebaseAuth.java | 2072 ---- .../firebase/auth/RNFirebaseAuthPackage.java | 38 - .../config/RNFirebaseRemoteConfig.java | 209 - .../config/RNFirebaseRemoteConfigPackage.java | 38 - .../firebase/database/RNFirebaseDatabase.java | 876 -- .../database/RNFirebaseDatabasePackage.java | 38 - .../database/RNFirebaseDatabaseReference.java | 615 -- .../database/RNFirebaseDatabaseUtils.java | 396 - .../RNFirebaseTransactionHandler.java | 164 - .../crashlytics/RNFirebaseCrashlytics.java | 73 - .../RNFirebaseCrashlyticsPackage.java | 38 - .../DocumentSnapshotSerializeAsyncTask.java | 49 - .../firestore/FirestoreSerialize.java | 518 - .../QuerySnapshotSerializeAsyncTask.java | 49 - .../firestore/RNFirebaseFirestore.java | 770 -- ...NFirebaseFirestoreCollectionReference.java | 335 - .../RNFirebaseFirestoreDocumentReference.java | 274 - .../firestore/RNFirebaseFirestorePackage.java | 38 - ...RNFirebaseFirestoreTransactionHandler.java | 166 - .../functions/RNFirebaseFunctionsPackage.java | 37 - .../instanceid/RNFirebaseInstanceId.java | 75 - .../RNFirebaseInstanceIdPackage.java | 38 - .../firebase/invites/RNFirebaseInvites.java | 268 - .../invites/RNFirebaseInvitesPackage.java | 38 - .../firebase/links/RNFirebaseLinks.java | 353 - .../links/RNFirebaseLinksPackage.java | 38 - .../messaging/BundleJSONConverter.java | 244 - .../messaging/MessagingSerializer.java | 44 - .../RNFirebaseBackgroundMessagingService.java | 30 - .../RNFirebaseInstanceIdService.java | 24 - .../messaging/RNFirebaseMessaging.java | 216 - .../messaging/RNFirebaseMessagingPackage.java | 38 - .../messaging/RNFirebaseMessagingService.java | 75 - .../DisplayNotificationTask.java | 580 -- ...eBackgroundNotificationActionReceiver.java | 69 - ...eBackgroundNotificationActionsService.java | 30 - .../RNFirebaseNotificationManager.java | 492 - .../RNFirebaseNotificationReceiver.java | 15 - .../RNFirebaseNotifications.java | 427 - .../RNFirebaseNotificationsPackage.java | 37 - ...RNFirebaseNotificationsRebootReceiver.java | 18 - .../firebase/perf/RNFirebasePerformance.java | 291 - .../perf/RNFirebasePerformancePackage.java | 38 - .../firebase/storage/RNFirebaseStorage.java | 803 -- .../storage/RNFirebaseStoragePackage.java | 43 - docs/README.md | 2 + docs/pages/contributing/index.mdx | 165 + docs/pages/contributing/testing.mdx | 109 + .../faqs/duplicate-undefined-symbols.mdx | 23 + .../faqs/enabling-database-persistence.mdx | 58 + ...-to-recognize-googleservice-info-plist.mdx | 29 + docs/pages/faqs/flow.mdx | 6 + docs/pages/faqs/index.mdx | 11 + docs/pages/faqs/missing-byte-code.mdx | 26 + docs/pages/faqs/multiple-dex-files.mdx | 63 + docs/pages/faqs/rnfb-vs-web-sdk.mdx | 70 + docs/pages/faqs/typescript.mdx | 8 + docs/pages/feedback/index.mdx | 6 + .../guides/getting-started-with-rnfb.mdx | 8 + docs/pages/guides/index.mdx | 9 + docs/pages/index.mdx | 105 + docs/pages/releases/index.mdx | 9 + docs/pages/releases/v5.1.x.mdx | 8 + docs/pages/releases/v5.2.x.mdx | 118 + docs/project.yaml | 14 + docs/v5.x.x/index.mdx | 3 + docs/v5.x.x/variables.yaml | 45 + docs/v6.x.x/.gitkeep | 0 docs/v6.x.x/typedoc.json | 1 + ios/RNFirebase.xcodeproj/project.pbxproj | 618 -- ios/RNFirebase/RNFirebase.h | 13 - ios/RNFirebase/RNFirebase.m | 122 - ios/RNFirebase/RNFirebaseEvents.h | 54 - ios/RNFirebase/RNFirebaseUtil.h | 25 - ios/RNFirebase/RNFirebaseUtil.m | 62 - ios/RNFirebase/admob/BannerComponent.h | 29 - ios/RNFirebase/admob/BannerComponent.m | 93 - ios/RNFirebase/admob/NativeExpressComponent.h | 29 - ios/RNFirebase/admob/NativeExpressComponent.m | 122 - ios/RNFirebase/admob/RNFirebaseAdMob.h | 29 - ios/RNFirebase/admob/RNFirebaseAdMob.m | 232 - .../admob/RNFirebaseAdMobBannerManager.h | 5 - .../admob/RNFirebaseAdMobBannerManager.m | 32 - .../admob/RNFirebaseAdMobInterstitial.h | 33 - .../admob/RNFirebaseAdMobInterstitial.m | 64 - .../RNFirebaseAdMobNativeExpressManager.h | 5 - .../RNFirebaseAdMobNativeExpressManager.m | 32 - .../admob/RNFirebaseAdMobRewardedVideo.h | 33 - .../admob/RNFirebaseAdMobRewardedVideo.m | 77 - .../analytics/RNFirebaseAnalytics.h | 19 - .../analytics/RNFirebaseAnalytics.m | 41 - ios/RNFirebase/auth/RNFirebaseAuth.h | 78 - ios/RNFirebase/auth/RNFirebaseAuth.m | 1586 --- .../config/RNFirebaseRemoteConfig.h | 17 - .../config/RNFirebaseRemoteConfig.m | 144 - .../RCTConvert+UIBackgroundFetchResult.h | 5 - .../RCTConvert+UIBackgroundFetchResult.m | 16 - ios/RNFirebase/database/RNFirebaseDatabase.h | 35 - ios/RNFirebase/database/RNFirebaseDatabase.m | 451 - .../database/RNFirebaseDatabaseReference.h | 35 - .../database/RNFirebaseDatabaseReference.m | 219 - .../crashlytics/RNFirebaseCrashlytics.h | 26 - .../crashlytics/RNFirebaseCrashlytics.m | 64 - .../firestore/RNFirebaseFirestore.h | 27 - .../firestore/RNFirebaseFirestore.m | 538 - .../RNFirebaseFirestoreCollectionReference.h | 36 - .../RNFirebaseFirestoreCollectionReference.m | 271 - .../RNFirebaseFirestoreDocumentReference.h | 40 - .../RNFirebaseFirestoreDocumentReference.m | 435 - .../functions/RNFirebaseFunctions.h | 20 - .../functions/RNFirebaseFunctions.m | 141 - .../instanceid/RNFirebaseInstanceId.h | 19 - .../instanceid/RNFirebaseInstanceId.m | 66 - ios/RNFirebase/invites/RNFirebaseInvites.h | 27 - ios/RNFirebase/invites/RNFirebaseInvites.m | 210 - ios/RNFirebase/links/RNFirebaseLinks.h | 26 - ios/RNFirebase/links/RNFirebaseLinks.m | 332 - .../messaging/RNFirebaseMessaging.h | 30 - .../messaging/RNFirebaseMessaging.m | 344 - .../notifications/RNFirebaseNotifications.h | 27 - .../notifications/RNFirebaseNotifications.m | 798 -- ios/RNFirebase/perf/RNFirebasePerformance.h | 22 - ios/RNFirebase/perf/RNFirebasePerformance.m | 270 - ios/RNFirebase/storage/RNFirebaseStorage.h | 20 - ios/RNFirebase/storage/RNFirebaseStorage.m | 547 - lerna.json | 22 + metro.config.js | 1 + package-lock.json | 9131 ----------------- package.json | 210 +- .npmignore => packages/analytics/.npmignore | 54 +- packages/analytics/LICENSE | 32 + packages/analytics/README.md | 52 + packages/analytics/android/build.gradle | 66 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + packages/analytics/android/gradlew | 160 + packages/analytics/android/gradlew.bat | 90 + packages/analytics/android/lint.xml | 5 + packages/analytics/android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 8 + .../ReactNativeFirebaseAnalyticsModule.java | 151 + .../ReactNativeFirebaseAnalyticsPackage.java | 42 + packages/analytics/e2e/analytics.e2e.js | 210 + packages/analytics/ios/RNFBAnalytics.podspec | 20 + .../RNFBAnalytics.xcodeproj/project.pbxproj | 349 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../xcshareddata/IDETemplateMacros.plist | 24 + .../ios/RNFBAnalytics/RNFBAnalyticsModule.h | 24 + .../ios/RNFBAnalytics/RNFBAnalyticsModule.m | 166 + packages/analytics/lib/index.d.ts | 169 + packages/analytics/lib/index.js | 158 + packages/analytics/lib/index.js.flow | 150 + packages/analytics/package.json | 42 + packages/app-types/index.d.ts | 256 + packages/app-types/index.js.flow | 75 + packages/app-types/package.json | 20 + packages/app-types/tsconfig.json | 7 + packages/app/.npmignore | 65 + packages/app/LICENSE | 32 + packages/app/README.md | 41 + packages/app/android/build.gradle | 69 + packages/app/android/expo.gradle | 21 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + packages/app/android/gradlew | 160 + packages/app/android/gradlew.bat | 90 + packages/app/android/lint.xml | 5 + packages/app/android/settings.gradle | 1 + .../app/android/src/main/AndroidManifest.xml | 12 + .../firebase/app/ReactNativeFirebaseApp.java | 40 + .../app/ReactNativeFirebaseAppModule.java | 138 + .../app/ReactNativeFirebaseAppPackage.java | 43 + .../app/ReactNativeFirebaseUtilsModule.java | 137 + .../firebase/common/RCTConvertFirebase.java | 193 + .../common/ReactNativeFirebaseEvent.java | 54 + .../ReactNativeFirebaseEventEmitter.java | 162 + .../ReactNativeFirebaseInitProvider.java | 102 + .../common/ReactNativeFirebaseModule.java | 88 + .../ReactNativeFirebasePreferences.java | 62 + .../firebase/common/SharedUtils.java | 201 + .../firebase/interfaces/ContextProvider.java | 29 + .../firebase/interfaces/NativeError.java | 28 + .../firebase/interfaces/NativeEvent.java | 27 + packages/app/e2e/app/app.constants.e2e.js | 25 + packages/app/e2e/app/app.e2e.js | 76 + packages/app/e2e/app/events.e2e.js | 76 + packages/app/e2e/utils/util.e2e.js | 3 + packages/app/e2e/utils/utils.constants.e2e.js | 16 + .../app/ios/RNFBApp.podspec | 8 +- .../app/ios/RNFBApp.xcodeproj/project.pbxproj | 384 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../xcshareddata/IDETemplateMacros.plist | 24 + packages/app/ios/RNFBApp/RNFBAppModule.h | 24 + packages/app/ios/RNFBApp/RNFBAppModule.m | 172 + .../ios/RNFBApp/common/RNFBRCTEventEmitter.h | 69 + .../ios/RNFBApp/common/RNFBRCTEventEmitter.m | 143 + .../app/ios/RNFBApp/common/RNFBSharedUtils.h | 50 + .../app/ios/RNFBApp/common/RNFBSharedUtils.m | 79 + .../RNFBApp/converters/RCTConvert+FIRApp.h | 23 + .../RNFBApp/converters/RCTConvert+FIRApp.m | 31 + .../converters/RCTConvert+FIROptions.h | 23 + .../converters/RCTConvert+FIROptions.m | 37 + packages/app/lib/FirebaseApp.js | 79 + packages/app/lib/index.d.ts | 39 + packages/app/lib/index.js | 22 + packages/app/lib/index.js.flow | 31 + packages/app/lib/internal/FirebaseModule.js | 45 + .../app/lib/internal/NativeFirebaseError.js | 73 + .../lib/internal/RNFBNativeEventEmitter.js | 43 + .../app/lib/internal/SharedEventEmitter.js | 20 + packages/app/lib/internal/constants.js | 46 + packages/app/lib/internal/index.js | 24 + packages/app/lib/internal/registry/app.js | 194 + .../app/lib/internal/registry/namespace.js | 292 + .../app/lib/internal/registry/nativeModule.js | 213 + packages/app/package.json | 75 + packages/common/.npmignore | 65 + packages/common/LICENSE | 32 + packages/common/README.md | 32 + packages/common/lib/index.js | 15 + packages/common/lib/validate.js | 94 + packages/common/package.json | 22 + packages/functions/.npmignore | 65 + packages/functions/LICENSE | 32 + packages/functions/README.md | 49 + packages/functions/android/build.gradle | 66 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + packages/functions/android/gradlew | 160 + packages/functions/android/gradlew.bat | 90 + packages/functions/android/lint.xml | 5 + packages/functions/android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 7 + .../ReactNativeFirebaseFunctionsModule.java | 106 +- .../ReactNativeFirebaseFunctionsPackage.java | 42 + packages/functions/e2e/functions.e2e.js | 255 + packages/functions/ios/RNFBFunctions.podspec | 20 + .../RNFBFunctions.xcodeproj/project.pbxproj | 349 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../xcshareddata/IDETemplateMacros.plist | 24 + .../ios/RNFBFunctions/RNFBFunctionsModule.h | 24 + .../ios/RNFBFunctions/RNFBFunctionsModule.m | 40 + packages/functions/lib/HttpsError.js | 39 + packages/functions/lib/index.d.ts | 234 + packages/functions/lib/index.js | 111 + packages/functions/lib/index.js.flow | 222 + packages/functions/package.json | 45 + packages/hooks/.gitkeep | 0 scripts/docs-parse-typedoc.js | 23 + scripts/docs-version-name.js | 21 + src/common/NativeError.js | 14 - src/common/commonTypes.flow.js | 19 - src/index.d.ts | 2938 ------ src/index.js | 81 - src/modules/admob/AdMobComponent.js | 102 - src/modules/admob/AdRequest.js | 58 - src/modules/admob/Banner.js | 14 - src/modules/admob/EventTypes.js | 23 - src/modules/admob/Interstitial.js | 119 - src/modules/admob/NativeExpress.js | 14 - src/modules/admob/RewardedVideo.js | 118 - src/modules/admob/VideoOptions.js | 16 - src/modules/admob/index.js | 122 - src/modules/analytics/index.js | 167 - src/modules/auth/AuthSettings.js | 70 - src/modules/auth/User.js | 347 - src/modules/auth/index.js | 641 -- src/modules/auth/phone/ConfirmationResult.js | 38 - src/modules/auth/phone/PhoneAuthListener.js | 365 - .../auth/providers/EmailAuthProvider.js | 50 - .../auth/providers/FacebookAuthProvider.js | 27 - .../auth/providers/GithubAuthProvider.js | 27 - .../auth/providers/GoogleAuthProvider.js | 27 - src/modules/auth/providers/OAuthProvider.js | 27 - .../auth/providers/PhoneAuthProvider.js | 27 - .../auth/providers/TwitterAuthProvider.js | 27 - src/modules/auth/types.js | 91 - src/modules/config/index.js | 190 - src/modules/core/app.js | 208 - src/modules/core/firebase.js | 262 - src/modules/crashlytics/index.js | 90 - src/modules/database/DataSnapshot.js | 181 - src/modules/database/OnDisconnect.js | 70 - src/modules/database/Query.js | 109 - src/modules/database/Reference.js | 848 -- src/modules/database/index.js | 135 - src/modules/database/transaction.js | 165 - src/modules/firestore/Blob.js | 91 - src/modules/firestore/CollectionReference.js | 112 - src/modules/firestore/DocumentChange.js | 44 - src/modules/firestore/DocumentReference.js | 272 - src/modules/firestore/DocumentSnapshot.js | 72 - src/modules/firestore/FieldPath.js | 22 - src/modules/firestore/FieldValue.js | 53 - src/modules/firestore/GeoPoint.js | 30 - src/modules/firestore/Path.js | 52 - src/modules/firestore/Query.js | 481 - src/modules/firestore/QuerySnapshot.js | 81 - src/modules/firestore/SnapshotError.js | 12 - src/modules/firestore/Transaction.js | 154 - src/modules/firestore/TransactionHandler.js | 242 - src/modules/firestore/WriteBatch.js | 77 - src/modules/firestore/firestoreTypes.flow.js | 69 - src/modules/firestore/index.js | 282 - src/modules/firestore/utils/any.js | 4 - src/modules/firestore/utils/index.js | 75 - src/modules/firestore/utils/serialize.js | 222 - src/modules/functions/HttpsError.js | 16 - src/modules/functions/index.js | 125 - src/modules/functions/types.flow.js | 30 - src/modules/iid/index.js | 71 - src/modules/invites/AndroidInvitation.js | 73 - src/modules/invites/Invitation.js | 118 - src/modules/invites/index.js | 90 - src/modules/invites/types.js | 21 - src/modules/links/AnalyticsParameters.js | 84 - src/modules/links/AndroidParameters.js | 63 - src/modules/links/DynamicLink.js | 86 - src/modules/links/IOSParameters.js | 121 - src/modules/links/ITunesParameters.js | 58 - src/modules/links/NavigationParameters.js | 32 - src/modules/links/SocialParameters.js | 58 - src/modules/links/index.js | 117 - src/modules/links/types.js | 53 - src/modules/messaging/IOSMessaging.js | 25 - src/modules/messaging/RemoteMessage.js | 162 - src/modules/messaging/index.js | 196 - src/modules/messaging/types.js | 38 - src/modules/notifications/AndroidAction.js | 157 - src/modules/notifications/AndroidChannel.js | 244 - .../notifications/AndroidChannelGroup.js | 43 - .../notifications/AndroidNotification.js | 783 -- .../notifications/AndroidNotifications.js | 132 - .../notifications/AndroidRemoteInput.js | 127 - src/modules/notifications/IOSNotification.js | 206 - src/modules/notifications/IOSNotifications.js | 31 - src/modules/notifications/Notification.js | 186 - src/modules/notifications/index.js | 348 - src/modules/notifications/types.js | 232 - src/modules/perf/HttpMetric.js | 98 - src/modules/perf/Trace.js | 74 - src/modules/perf/index.js | 100 - src/modules/storage/index.js | 178 - src/modules/storage/reference.js | 107 - src/modules/storage/task.js | 220 - src/modules/utils/database.js | 12 - src/modules/utils/index.js | 125 - src/types/index.js | 230 - src/utils/Base64.js | 68 - src/utils/ModuleBase.js | 61 - src/utils/ReferenceBase.js | 29 - src/utils/SyncTree.js | 336 - src/utils/apps.js | 235 - src/utils/events.js | 77 - src/utils/index.js | 357 - src/utils/internals.js | 244 - src/utils/log.js | 47 - src/utils/native.js | 86 - tests/.babelrc | 2 +- tests/.buckconfig | 7 +- tests/.eslintrc | 39 - tests/.gitignore | 41 - tests/android/.editorconfig | 2 +- tests/android/app/build.gradle | 80 +- .../android/app/src/main/AndroidManifest.xml | 51 +- .../main/java/com/testing/MainActivity.java | 2 + .../java/com/testing/MainApplication.java | 56 +- tests/android/build.gradle | 34 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 52266 -> 56177 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 +- tests/android/gradlew | 110 +- tests/android/gradlew.bat | 174 +- tests/android/settings.gradle | 19 +- tests/app.js | 43 +- tests/e2e/core/core.e2e.js | 115 - tests/e2e/firestore/collection/dates.e2e.js | 417 - tests/e2e/firestore/fieldValue.e2e.js | 208 - tests/e2e/helpers.js | 144 + tests/e2e/init.js | 29 +- tests/e2e/messaging/messaging.e2e.js | 140 - tests/e2e/mocha.ci.opts | 9 - tests/e2e/mocha.opts | 5 +- .../analytics/analytics.e2e.js | 0 tests/{e2e => e2e_copy}/auth/auth.e2e.js | 0 tests/{e2e => e2e_copy}/auth/emailLink.e2e.js | 0 tests/{e2e => e2e_copy}/auth/phone.e2e.js | 0 tests/{e2e => e2e_copy}/auth/provider.e2e.js | 0 tests/{e2e => e2e_copy}/auth/rnReload.e2e.js | 0 tests/{e2e => e2e_copy}/auth/user.e2e.js | 0 tests/{e2e => e2e_copy}/config/config.e2e.js | 0 .../crashlytics/crashlytics.e2e.js | 0 .../database/issueSpecific.e2e.js | 0 .../database/ref/child.e2e.js | 0 .../database/ref/factory.e2e.js | 0 .../database/ref/isEqual.e2e.js | 0 .../{e2e => e2e_copy}/database/ref/key.e2e.js | 0 .../{e2e => e2e_copy}/database/ref/on.e2e.js | 0 .../database/ref/once.e2e.js | 0 .../database/ref/parent.e2e.js | 0 .../database/ref/priority.e2e.js | 0 .../database/ref/push.e2e.js | 0 .../database/ref/query.e2e.js | 0 .../{e2e => e2e_copy}/database/ref/set.e2e.js | 0 .../database/ref/transactions.e2e.js | 0 .../database/rnReload.e2e.js | 0 .../database/snapshot.e2e.js | 0 .../{e2e => e2e_copy}/firestore/batch.e2e.js | 0 tests/{e2e => e2e_copy}/firestore/blob.e2e.js | 0 .../firestore/collection/cursors.e2e.js | 0 .../firestore/collection/limit.e2e.js | 0 .../firestore/collection/snapshot.e2e.js | 0 .../firestore/collection/where.e2e.js | 0 .../firestore/collectionReference.e2e.js | 0 .../firestore/documentReference.e2e.js | 0 .../firestore/documentSnapshot.e2e.js | 0 .../firestore/fieldPath.e2e.js | 0 tests/e2e_copy/firestore/fieldValue.e2e.js | 87 + .../firestore/firestore.e2e.js | 0 tests/{e2e => e2e_copy}/firestore/path.e2e.js | 4 +- .../firestore/transactions.e2e.js | 0 .../functions/functions.e2e.js | 0 tests/{e2e => e2e_copy}/iid/iid.e2e.js | 0 .../notifications/ios.e2e.js | 0 .../{e2e => e2e_copy}/perf/httpMetric.e2e.js | 0 tests/{e2e => e2e_copy}/perf/perf.e2e.js | 0 tests/{e2e => e2e_copy}/perf/trace.e2e.js | 0 .../{e2e => e2e_copy}/storage/storage.e2e.js | 0 tests/flow-typed/firebase.js | 6 +- tests/helpers/index.js | 2 +- tests/index.android.js | 0 tests/ios/Podfile | 57 +- tests/ios/Podfile.lock | 323 +- tests/ios/testing.xcodeproj/project.pbxproj | 801 +- .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/testing Release.xcscheme | 2 - .../xcshareddata/xcschemes/testing.xcscheme | 2 - .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + tests/ios/testing/AppDelegate.m | 69 +- tests/metro.config.js | 27 +- tests/package.json | 71 +- tests/patches/detox+9.1.2.patch | 33 + tests/type-test.js.flow | 13 + tests/type-test.ts | 25 + tests/yarn.lock | 7261 ------------- tsconfig.json | 9 +- tslint.json | 9 + typedoc.json | 4445 ++++++++ yarn.lock | 5564 +++++++--- 489 files changed, 20500 insertions(+), 59528 deletions(-) create mode 100755 .buckconfig mode change 100755 => 100644 .circleci/scripts/wait-for-avd.sh create mode 100644 .gitattributes create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .watchmanconfig delete mode 100644 android/.editorconfig delete mode 100644 android/build.gradle delete mode 100644 android/src/main/AndroidManifest.xml delete mode 100644 android/src/main/java/io/invertase/firebase/ErrorUtils.java delete mode 100644 android/src/main/java/io/invertase/firebase/RNFirebaseModule.java delete mode 100644 android/src/main/java/io/invertase/firebase/RNFirebasePackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/Utils.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMob.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobBanner.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobNativeExpress.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobRewardedVideo.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobUtils.java delete mode 100644 android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdmobInterstitial.java delete mode 100644 android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalytics.java delete mode 100644 android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalyticsPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java delete mode 100644 android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuthPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfig.java delete mode 100644 android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfigPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabase.java delete mode 100644 android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabasePackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseReference.java delete mode 100644 android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseUtils.java delete mode 100644 android/src/main/java/io/invertase/firebase/database/RNFirebaseTransactionHandler.java delete mode 100644 android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java delete mode 100644 android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/DocumentSnapshotSerializeAsyncTask.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/QuerySnapshotSerializeAsyncTask.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestorePackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreTransactionHandler.java delete mode 100644 android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctionsPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceId.java delete mode 100644 android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceIdPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvites.java delete mode 100644 android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvitesPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java delete mode 100644 android/src/main/java/io/invertase/firebase/links/RNFirebaseLinksPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/BundleJSONConverter.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/MessagingSerializer.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/RNFirebaseBackgroundMessagingService.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/RNFirebaseInstanceIdService.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessaging.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingService.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/DisplayNotificationTask.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionReceiver.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionsService.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationManager.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationReceiver.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotifications.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsPackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsRebootReceiver.java delete mode 100644 android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformance.java delete mode 100644 android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformancePackage.java delete mode 100644 android/src/main/java/io/invertase/firebase/storage/RNFirebaseStorage.java delete mode 100644 android/src/main/java/io/invertase/firebase/storage/RNFirebaseStoragePackage.java create mode 100644 docs/README.md create mode 100644 docs/pages/contributing/index.mdx create mode 100644 docs/pages/contributing/testing.mdx create mode 100644 docs/pages/faqs/duplicate-undefined-symbols.mdx create mode 100644 docs/pages/faqs/enabling-database-persistence.mdx create mode 100644 docs/pages/faqs/failed-to-recognize-googleservice-info-plist.mdx create mode 100644 docs/pages/faqs/flow.mdx create mode 100644 docs/pages/faqs/index.mdx create mode 100644 docs/pages/faqs/missing-byte-code.mdx create mode 100644 docs/pages/faqs/multiple-dex-files.mdx create mode 100644 docs/pages/faqs/rnfb-vs-web-sdk.mdx create mode 100644 docs/pages/faqs/typescript.mdx create mode 100644 docs/pages/feedback/index.mdx create mode 100644 docs/pages/guides/getting-started-with-rnfb.mdx create mode 100644 docs/pages/guides/index.mdx create mode 100644 docs/pages/index.mdx create mode 100644 docs/pages/releases/index.mdx create mode 100644 docs/pages/releases/v5.1.x.mdx create mode 100644 docs/pages/releases/v5.2.x.mdx create mode 100644 docs/project.yaml create mode 100644 docs/v5.x.x/index.mdx create mode 100644 docs/v5.x.x/variables.yaml create mode 100644 docs/v6.x.x/.gitkeep create mode 100644 docs/v6.x.x/typedoc.json delete mode 100644 ios/RNFirebase.xcodeproj/project.pbxproj delete mode 100644 ios/RNFirebase/RNFirebase.h delete mode 100644 ios/RNFirebase/RNFirebase.m delete mode 100644 ios/RNFirebase/RNFirebaseEvents.h delete mode 100644 ios/RNFirebase/RNFirebaseUtil.h delete mode 100644 ios/RNFirebase/RNFirebaseUtil.m delete mode 100644 ios/RNFirebase/admob/BannerComponent.h delete mode 100644 ios/RNFirebase/admob/BannerComponent.m delete mode 100644 ios/RNFirebase/admob/NativeExpressComponent.h delete mode 100644 ios/RNFirebase/admob/NativeExpressComponent.m delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMob.h delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMob.m delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.h delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.m delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.h delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.m delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.h delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.h delete mode 100644 ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.m delete mode 100644 ios/RNFirebase/analytics/RNFirebaseAnalytics.h delete mode 100644 ios/RNFirebase/analytics/RNFirebaseAnalytics.m delete mode 100644 ios/RNFirebase/auth/RNFirebaseAuth.h delete mode 100644 ios/RNFirebase/auth/RNFirebaseAuth.m delete mode 100644 ios/RNFirebase/config/RNFirebaseRemoteConfig.h delete mode 100644 ios/RNFirebase/config/RNFirebaseRemoteConfig.m delete mode 100644 ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.h delete mode 100644 ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.m delete mode 100644 ios/RNFirebase/database/RNFirebaseDatabase.h delete mode 100644 ios/RNFirebase/database/RNFirebaseDatabase.m delete mode 100644 ios/RNFirebase/database/RNFirebaseDatabaseReference.h delete mode 100644 ios/RNFirebase/database/RNFirebaseDatabaseReference.m delete mode 100644 ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h delete mode 100644 ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestore.h delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestore.m delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.h delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h delete mode 100644 ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m delete mode 100644 ios/RNFirebase/functions/RNFirebaseFunctions.h delete mode 100644 ios/RNFirebase/functions/RNFirebaseFunctions.m delete mode 100644 ios/RNFirebase/instanceid/RNFirebaseInstanceId.h delete mode 100644 ios/RNFirebase/instanceid/RNFirebaseInstanceId.m delete mode 100644 ios/RNFirebase/invites/RNFirebaseInvites.h delete mode 100644 ios/RNFirebase/invites/RNFirebaseInvites.m delete mode 100644 ios/RNFirebase/links/RNFirebaseLinks.h delete mode 100644 ios/RNFirebase/links/RNFirebaseLinks.m delete mode 100644 ios/RNFirebase/messaging/RNFirebaseMessaging.h delete mode 100644 ios/RNFirebase/messaging/RNFirebaseMessaging.m delete mode 100644 ios/RNFirebase/notifications/RNFirebaseNotifications.h delete mode 100644 ios/RNFirebase/notifications/RNFirebaseNotifications.m delete mode 100644 ios/RNFirebase/perf/RNFirebasePerformance.h delete mode 100644 ios/RNFirebase/perf/RNFirebasePerformance.m delete mode 100644 ios/RNFirebase/storage/RNFirebaseStorage.h delete mode 100644 ios/RNFirebase/storage/RNFirebaseStorage.m create mode 100644 lerna.json create mode 100644 metro.config.js delete mode 100644 package-lock.json rename .npmignore => packages/analytics/.npmignore (69%) create mode 100644 packages/analytics/LICENSE create mode 100644 packages/analytics/README.md create mode 100644 packages/analytics/android/build.gradle create mode 100644 packages/analytics/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 packages/analytics/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/analytics/android/gradlew create mode 100644 packages/analytics/android/gradlew.bat create mode 100644 packages/analytics/android/lint.xml create mode 100644 packages/analytics/android/settings.gradle create mode 100644 packages/analytics/android/src/main/AndroidManifest.xml create mode 100644 packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java create mode 100644 packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsPackage.java create mode 100644 packages/analytics/e2e/analytics.e2e.js create mode 100644 packages/analytics/ios/RNFBAnalytics.podspec create mode 100644 packages/analytics/ios/RNFBAnalytics.xcodeproj/project.pbxproj create mode 100644 packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 packages/analytics/ios/RNFBAnalytics.xcodeproj/xcshareddata/IDETemplateMacros.plist create mode 100644 packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.h create mode 100644 packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m create mode 100644 packages/analytics/lib/index.d.ts create mode 100644 packages/analytics/lib/index.js create mode 100644 packages/analytics/lib/index.js.flow create mode 100644 packages/analytics/package.json create mode 100644 packages/app-types/index.d.ts create mode 100644 packages/app-types/index.js.flow create mode 100644 packages/app-types/package.json create mode 100644 packages/app-types/tsconfig.json create mode 100644 packages/app/.npmignore create mode 100644 packages/app/LICENSE create mode 100644 packages/app/README.md create mode 100644 packages/app/android/build.gradle create mode 100644 packages/app/android/expo.gradle create mode 100644 packages/app/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 packages/app/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/app/android/gradlew create mode 100644 packages/app/android/gradlew.bat create mode 100644 packages/app/android/lint.xml create mode 100644 packages/app/android/settings.gradle create mode 100644 packages/app/android/src/main/AndroidManifest.xml create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppModule.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseUtilsModule.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/RCTConvertFirebase.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/common/SharedUtils.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/interfaces/ContextProvider.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeError.java create mode 100644 packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeEvent.java create mode 100644 packages/app/e2e/app/app.constants.e2e.js create mode 100644 packages/app/e2e/app/app.e2e.js create mode 100644 packages/app/e2e/app/events.e2e.js create mode 100644 packages/app/e2e/utils/util.e2e.js create mode 100644 packages/app/e2e/utils/utils.constants.e2e.js rename ios/RNFirebase.podspec => packages/app/ios/RNFBApp.podspec (81%) create mode 100644 packages/app/ios/RNFBApp.xcodeproj/project.pbxproj create mode 100644 packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 packages/app/ios/RNFBApp.xcodeproj/xcshareddata/IDETemplateMacros.plist create mode 100644 packages/app/ios/RNFBApp/RNFBAppModule.h create mode 100644 packages/app/ios/RNFBApp/RNFBAppModule.m create mode 100644 packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.h create mode 100644 packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.m create mode 100644 packages/app/ios/RNFBApp/common/RNFBSharedUtils.h create mode 100644 packages/app/ios/RNFBApp/common/RNFBSharedUtils.m create mode 100644 packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.h create mode 100644 packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.m create mode 100644 packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.h create mode 100644 packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.m create mode 100644 packages/app/lib/FirebaseApp.js create mode 100644 packages/app/lib/index.d.ts create mode 100644 packages/app/lib/index.js create mode 100644 packages/app/lib/index.js.flow create mode 100644 packages/app/lib/internal/FirebaseModule.js create mode 100644 packages/app/lib/internal/NativeFirebaseError.js create mode 100644 packages/app/lib/internal/RNFBNativeEventEmitter.js create mode 100644 packages/app/lib/internal/SharedEventEmitter.js create mode 100644 packages/app/lib/internal/constants.js create mode 100644 packages/app/lib/internal/index.js create mode 100644 packages/app/lib/internal/registry/app.js create mode 100644 packages/app/lib/internal/registry/namespace.js create mode 100644 packages/app/lib/internal/registry/nativeModule.js create mode 100644 packages/app/package.json create mode 100644 packages/common/.npmignore create mode 100644 packages/common/LICENSE create mode 100644 packages/common/README.md create mode 100644 packages/common/lib/index.js create mode 100644 packages/common/lib/validate.js create mode 100644 packages/common/package.json create mode 100644 packages/functions/.npmignore create mode 100644 packages/functions/LICENSE create mode 100644 packages/functions/README.md create mode 100644 packages/functions/android/build.gradle create mode 100644 packages/functions/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 packages/functions/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/functions/android/gradlew create mode 100644 packages/functions/android/gradlew.bat create mode 100644 packages/functions/android/lint.xml create mode 100644 packages/functions/android/settings.gradle create mode 100644 packages/functions/android/src/main/AndroidManifest.xml rename android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctions.java => packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsModule.java (54%) create mode 100644 packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsPackage.java create mode 100644 packages/functions/e2e/functions.e2e.js create mode 100644 packages/functions/ios/RNFBFunctions.podspec create mode 100644 packages/functions/ios/RNFBFunctions.xcodeproj/project.pbxproj create mode 100644 packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 packages/functions/ios/RNFBFunctions.xcodeproj/xcshareddata/IDETemplateMacros.plist create mode 100644 packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.h create mode 100644 packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m create mode 100644 packages/functions/lib/HttpsError.js create mode 100644 packages/functions/lib/index.d.ts create mode 100644 packages/functions/lib/index.js create mode 100644 packages/functions/lib/index.js.flow create mode 100644 packages/functions/package.json create mode 100644 packages/hooks/.gitkeep create mode 100644 scripts/docs-parse-typedoc.js create mode 100644 scripts/docs-version-name.js delete mode 100644 src/common/NativeError.js delete mode 100644 src/common/commonTypes.flow.js delete mode 100644 src/index.d.ts delete mode 100644 src/index.js delete mode 100644 src/modules/admob/AdMobComponent.js delete mode 100644 src/modules/admob/AdRequest.js delete mode 100644 src/modules/admob/Banner.js delete mode 100644 src/modules/admob/EventTypes.js delete mode 100644 src/modules/admob/Interstitial.js delete mode 100644 src/modules/admob/NativeExpress.js delete mode 100644 src/modules/admob/RewardedVideo.js delete mode 100644 src/modules/admob/VideoOptions.js delete mode 100644 src/modules/admob/index.js delete mode 100644 src/modules/analytics/index.js delete mode 100644 src/modules/auth/AuthSettings.js delete mode 100644 src/modules/auth/User.js delete mode 100644 src/modules/auth/index.js delete mode 100644 src/modules/auth/phone/ConfirmationResult.js delete mode 100644 src/modules/auth/phone/PhoneAuthListener.js delete mode 100644 src/modules/auth/providers/EmailAuthProvider.js delete mode 100644 src/modules/auth/providers/FacebookAuthProvider.js delete mode 100644 src/modules/auth/providers/GithubAuthProvider.js delete mode 100644 src/modules/auth/providers/GoogleAuthProvider.js delete mode 100644 src/modules/auth/providers/OAuthProvider.js delete mode 100644 src/modules/auth/providers/PhoneAuthProvider.js delete mode 100644 src/modules/auth/providers/TwitterAuthProvider.js delete mode 100644 src/modules/auth/types.js delete mode 100644 src/modules/config/index.js delete mode 100644 src/modules/core/app.js delete mode 100644 src/modules/core/firebase.js delete mode 100644 src/modules/crashlytics/index.js delete mode 100644 src/modules/database/DataSnapshot.js delete mode 100644 src/modules/database/OnDisconnect.js delete mode 100644 src/modules/database/Query.js delete mode 100644 src/modules/database/Reference.js delete mode 100644 src/modules/database/index.js delete mode 100644 src/modules/database/transaction.js delete mode 100644 src/modules/firestore/Blob.js delete mode 100644 src/modules/firestore/CollectionReference.js delete mode 100644 src/modules/firestore/DocumentChange.js delete mode 100644 src/modules/firestore/DocumentReference.js delete mode 100644 src/modules/firestore/DocumentSnapshot.js delete mode 100644 src/modules/firestore/FieldPath.js delete mode 100644 src/modules/firestore/FieldValue.js delete mode 100644 src/modules/firestore/GeoPoint.js delete mode 100644 src/modules/firestore/Path.js delete mode 100644 src/modules/firestore/Query.js delete mode 100644 src/modules/firestore/QuerySnapshot.js delete mode 100644 src/modules/firestore/SnapshotError.js delete mode 100644 src/modules/firestore/Transaction.js delete mode 100644 src/modules/firestore/TransactionHandler.js delete mode 100644 src/modules/firestore/WriteBatch.js delete mode 100644 src/modules/firestore/firestoreTypes.flow.js delete mode 100644 src/modules/firestore/index.js delete mode 100644 src/modules/firestore/utils/any.js delete mode 100644 src/modules/firestore/utils/index.js delete mode 100644 src/modules/firestore/utils/serialize.js delete mode 100644 src/modules/functions/HttpsError.js delete mode 100644 src/modules/functions/index.js delete mode 100644 src/modules/functions/types.flow.js delete mode 100644 src/modules/iid/index.js delete mode 100644 src/modules/invites/AndroidInvitation.js delete mode 100644 src/modules/invites/Invitation.js delete mode 100644 src/modules/invites/index.js delete mode 100644 src/modules/invites/types.js delete mode 100644 src/modules/links/AnalyticsParameters.js delete mode 100644 src/modules/links/AndroidParameters.js delete mode 100644 src/modules/links/DynamicLink.js delete mode 100644 src/modules/links/IOSParameters.js delete mode 100644 src/modules/links/ITunesParameters.js delete mode 100644 src/modules/links/NavigationParameters.js delete mode 100644 src/modules/links/SocialParameters.js delete mode 100644 src/modules/links/index.js delete mode 100644 src/modules/links/types.js delete mode 100644 src/modules/messaging/IOSMessaging.js delete mode 100644 src/modules/messaging/RemoteMessage.js delete mode 100644 src/modules/messaging/index.js delete mode 100644 src/modules/messaging/types.js delete mode 100644 src/modules/notifications/AndroidAction.js delete mode 100644 src/modules/notifications/AndroidChannel.js delete mode 100644 src/modules/notifications/AndroidChannelGroup.js delete mode 100644 src/modules/notifications/AndroidNotification.js delete mode 100644 src/modules/notifications/AndroidNotifications.js delete mode 100644 src/modules/notifications/AndroidRemoteInput.js delete mode 100644 src/modules/notifications/IOSNotification.js delete mode 100644 src/modules/notifications/IOSNotifications.js delete mode 100644 src/modules/notifications/Notification.js delete mode 100644 src/modules/notifications/index.js delete mode 100644 src/modules/notifications/types.js delete mode 100644 src/modules/perf/HttpMetric.js delete mode 100644 src/modules/perf/Trace.js delete mode 100644 src/modules/perf/index.js delete mode 100644 src/modules/storage/index.js delete mode 100644 src/modules/storage/reference.js delete mode 100644 src/modules/storage/task.js delete mode 100644 src/modules/utils/database.js delete mode 100644 src/modules/utils/index.js delete mode 100644 src/types/index.js delete mode 100644 src/utils/Base64.js delete mode 100644 src/utils/ModuleBase.js delete mode 100644 src/utils/ReferenceBase.js delete mode 100644 src/utils/SyncTree.js delete mode 100644 src/utils/apps.js delete mode 100644 src/utils/events.js delete mode 100644 src/utils/index.js delete mode 100644 src/utils/internals.js delete mode 100644 src/utils/log.js delete mode 100644 src/utils/native.js delete mode 100644 tests/.eslintrc delete mode 100755 tests/.gitignore delete mode 100644 tests/e2e/core/core.e2e.js delete mode 100644 tests/e2e/firestore/collection/dates.e2e.js delete mode 100644 tests/e2e/firestore/fieldValue.e2e.js create mode 100644 tests/e2e/helpers.js delete mode 100644 tests/e2e/messaging/messaging.e2e.js delete mode 100755 tests/e2e/mocha.ci.opts rename tests/{e2e => e2e_copy}/analytics/analytics.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/auth.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/emailLink.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/phone.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/provider.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/rnReload.e2e.js (100%) rename tests/{e2e => e2e_copy}/auth/user.e2e.js (100%) rename tests/{e2e => e2e_copy}/config/config.e2e.js (100%) rename tests/{e2e => e2e_copy}/crashlytics/crashlytics.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/issueSpecific.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/child.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/factory.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/isEqual.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/key.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/on.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/once.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/parent.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/priority.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/push.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/query.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/set.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/ref/transactions.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/rnReload.e2e.js (100%) rename tests/{e2e => e2e_copy}/database/snapshot.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/batch.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/blob.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/collection/cursors.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/collection/limit.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/collection/snapshot.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/collection/where.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/collectionReference.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/documentReference.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/documentSnapshot.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/fieldPath.e2e.js (100%) create mode 100644 tests/e2e_copy/firestore/fieldValue.e2e.js rename tests/{e2e => e2e_copy}/firestore/firestore.e2e.js (100%) rename tests/{e2e => e2e_copy}/firestore/path.e2e.js (97%) rename tests/{e2e => e2e_copy}/firestore/transactions.e2e.js (100%) rename tests/{e2e => e2e_copy}/functions/functions.e2e.js (100%) rename tests/{e2e => e2e_copy}/iid/iid.e2e.js (100%) rename tests/{e2e => e2e_copy}/notifications/ios.e2e.js (100%) rename tests/{e2e => e2e_copy}/perf/httpMetric.e2e.js (100%) rename tests/{e2e => e2e_copy}/perf/perf.e2e.js (100%) rename tests/{e2e => e2e_copy}/perf/trace.e2e.js (100%) rename tests/{e2e => e2e_copy}/storage/storage.e2e.js (100%) mode change 100755 => 100644 tests/index.android.js create mode 100644 tests/ios/testing.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 tests/ios/testing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 tests/ios/testing.xcworkspace/contents.xcworkspacedata create mode 100644 tests/ios/testing.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 tests/ios/testing.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 tests/patches/detox+9.1.2.patch create mode 100644 tests/type-test.js.flow create mode 100644 tests/type-test.ts delete mode 100644 tests/yarn.lock create mode 100644 tslint.json create mode 100644 typedoc.json diff --git a/.buckconfig b/.buckconfig new file mode 100755 index 00000000..3ba6dba2 --- /dev/null +++ b/.buckconfig @@ -0,0 +1,9 @@ +[android] + target = android-28 + +[download] + max_number_of_retries = 3 + +[maven_repositories] + central = https://repo1.maven.org/maven2 + google = https://dl.google.com/dl/android/maven2/ diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e7df51d..e085630a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,92 +1,164 @@ -# ------------------------- -# ALIASES -# ------------------------- - +--- aliases: # ------------------------- # CACHE # ------------------------- - &restore-yarn-cache - keys: - - v4-yarn-cache-{{ arch }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}-{{ checksum "tests/package.json" }}-{{ checksum "tests/yarn.lock" }} + key: v1-yarn-cache-{{ arch }}-{{ checksum "~/.checksumfiles/package.json" }}-{{ checksum "yarn.lock" }} - &save-yarn-cache paths: - ~/.cache/yarn - - ~/Library/Detox/ios - key: v4-yarn-cache-{{ arch }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}-{{ checksum "tests/package.json" }}-{{ checksum "tests/yarn.lock" }} + - ~/Library/Detox + key: v1-yarn-cache-{{ arch }}-{{ checksum "~/.checksumfiles/package.json" }}-{{ checksum "yarn.lock" }} + + # ------------------------- + # iOS + # ------------------------- - &save-pods-cache paths: - ~/react-native-firebase/tests/ios/Pods - key: v4-pods-cache-{{ arch }}-{{ checksum "ios/RNFirebase.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + key: v1-pods-cache-{{ arch }}-{{ checksum "~/.checksumfiles/combined.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + when: always - &restore-pods-cache - keys: - - v4-pods-cache-{{ arch }}-{{ checksum "ios/RNFirebase.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + key: v1-pods-cache-{{ arch }}-{{ checksum "~/.checksumfiles/combined.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} - &save-ios-build-cache paths: - ~/react-native-firebase/tests/ios/build/Build - key: v4-ios-build-cache-{{ arch }}-{{ checksum "ios/RNFirebase.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + key: v1-ios-pods-build-cache-{{ arch }}-{{ checksum "~/.checksumfiles/combined.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + when: always - &restore-ios-build-cache + key: v1-ios-pods-build-cache-{{ arch }}-{{ checksum "~/.checksumfiles/combined.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + + # ------------------------- + # Android + # ------------------------- + - &save-gradle-home-caches + name: Saving Gradle home cache + paths: + - ~/.gradle/caches/ + key: v1-gradle-home-cache-{{ checksum "~/.checksumfiles/build.gradle" }}-{{ checksum "~/.checksumfiles/settings.gradle" }} + + - &restore-gradle-home-caches keys: - - v4-ios-build-cache-{{ arch }}-{{ checksum "ios/RNFirebase.podspec" }}-{{ checksum "tests/ios/Podfile" }}-{{ checksum "tests/ios/Podfile.lock" }} + - v1-gradle-home-cache-{{ checksum "~/.checksumfiles/build.gradle" }}-{{ checksum "~/.checksumfiles/settings.gradle" }} + - v1-gradle-home-cache + + - &save-gradle-wrapper-cache + name: Saving Gradle wrapper cache + paths: + - ~/.gradle/wrapper/ + key: v1-gradle-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} + + - &restore-gradle-wrapper-cache + keys: + - v1-gradle-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} + + - &collect-gradle-build-caches + name: Collecting Gradle Build caches for saving + command: | + mkdir -p ~/gradle-build-caches + [ -d ~/.gradle/caches ] && + [ -n "$(ls -Ad ~/.gradle/caches/build-cache-* 2>/dev/null)" ] && + rm -rf ~/gradle-build-caches/* && + mv ~/.gradle/caches/build-cache-* ~/gradle-build-caches || true + when: always + + - &save-gradle-debug-build-cache + name: Saving Gradle Build caches + paths: + - ~/gradle-build-caches + key: v1-gradle-debug-build-cache-{{ .Revision }} + when: always + + - &save-gradle-release-build-cache + name: Saving Gradle Build caches + paths: + - ~/gradle-build-caches + key: v1-gradle-release-build-cache-{{ .Revision }} + when: always + + - &disperse-gradle-build-caches + name: Dispersing Gradle Build caches for restoring + command: | + [ -d ~/gradle-build-caches ] && + [ -n "$(ls -A ~/gradle-build-caches)" ] && + rm -rf ~/.gradle/caches/build-cache-* && + mkdir -p ~/.gradle/caches/ && + mv ~/gradle-build-caches/* ~/.gradle/caches/ || true + + - &restore-gradle-debug-build-cache + name: Restoring Gradle Build caches + keys: + - v1-gradle-debug-build-cache-{{ .Revision }} + - v1-gradle-debug-build-cache + + - &restore-gradle-release-build-cache + name: Restoring Gradle Build caches + keys: + - v1-gradle-release-build-cache-{{ .Revision }} + - v1-gradle-release-build-cache + + + # ------------------------- + # DETOX + # ------------------------- - &save-brew-cache paths: - /usr/local/Homebrew - ~/Library/Caches/Homebrew - key: v4-brew-cache-{{ arch }} + key: v7-brew-cache-{{ arch }} - &restore-brew-cache keys: - - v4-brew-cache-{{ arch }} + - v7-brew-cache-{{ arch }} - - &configure-jet-detox-environment + + # ------------------------- + # SHARED RUN COMMANDS + # ------------------------- + + - &configure-ios-detox-environment name: Configure Jet + Detox Environment command: | - brew install node@8 >/dev/null - brew tap wix/brew >/dev/null - brew install applesimutils >/dev/null - brew install watchman >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew install node@8 >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew install watchman >/dev/null touch .watchmanconfig node -v - &packager-jet - name: Start React Native Pacakager (background) + name: Start React Native Packager (background) background: true - command: cd tests && yarn run packager-jet || true + command: yarn run tests:packager:jet || true - &packager-warmup - name: Warming up Packager + name: Warm up Packager background: true command: node .circleci/scripts/packager-warmup.js + - &make-cache-check-files + name: Make Cache Checksum Files + command: | + mkdir -p ~/.checksumfiles + find . -type f -name 'build.gradle' -not -path "*node_modules*" -exec cat {} + >> ~/.checksumfiles/build.gradle + find . -type f -name 'settings.gradle' -not -path "*node_modules*" -exec cat {} + >> ~/.checksumfiles/settings.gradle + find . -type f -name '*.podspec' -not -path "*node_modules*" -exec cat {} + >> ~/.checksumfiles/combined.podspec + find . -type f -name 'package.json' -not -path "*node_modules*" -exec cat {} + >> ~/.checksumfiles/package.json # ------------------------- # INSTALLATION # ------------------------- - &yarn - name: Yarn Install ./ and ./tests + name: Yarn Install command: | yarn install --non-interactive --cache-folder ~/.cache/yarn - cd tests && yarn install --non-interactive - - # ------------------------- - # ANDROID - # ------------------------- - - # - &android-launch-avd - # name: Launch AVD - # background: true - # command: avd-launch - # - # - &android-wait-avd - # name: Wait for AVD to be ready - # command: timeout 300 avd-wait-ready - # ------------------------- # ANALYSE @@ -94,22 +166,34 @@ aliases: # eslint - &eslint - name: Lint Code - command: yarn run lint - - # flow - - &validate-flow-declarations - name: Validate Flow Declarations - command: yarn run validate-flow-declarations + name: Lint JS Code (ESLint) + command: yarn run validate:all:js # typescript - &validate-ts-declarations name: Validate TypeScript Declarations - command: yarn run validate-ts-declarations + command: yarn run validate:all:ts + + # flow + - &validate-flow-declarations + name: Validate Flow Declarations + command: yarn run validate:all:flow + + # ------------------------- + # ANDROID + # ------------------------- + +# - &android-accept-licenses +# name: Accept Android Licenses +# shell: /bin/bash -e +# command: | +# yes | sdkmanager --licenses +# yes | sdkmanager --update # ------------------------- # DEFAULTS # ------------------------- + defaults: &defaults working_directory: ~/react-native-firebase environment: @@ -121,25 +205,25 @@ js_defaults: &js_defaults docker: - image: circleci/node:8 environment: - - PATH: "/opt/yarn/yarn-v1.5.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - PATH: '/opt/yarn/yarn-v1.5.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # ANDROID android_defaults: &android_defaults <<: *defaults docker: - - image: invertase/react-native-firebase-android:standard - resource_class: "xlarge" + - image: invertase/react-native-firebase-android:release + resource_class: 'xlarge' working_directory: ~/react-native-firebase environment: - - _JAVA_OPTIONS: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xmx2048m" + - _JAVA_OPTIONS: '-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xmx2048m' - GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-XX:+HeapDumpOnOutOfMemoryError -Xmx2048m"' # IOS macos_defaults: &macos_defaults <<: *defaults - resource_class: "large" + resource_class: 'medium' macos: - xcode: "10.1.0" + xcode: '10.1.0' # ------------------------- # JOBS @@ -160,6 +244,8 @@ jobs: steps: - attach_workspace: at: ~/react-native-firebase + - run: *make-cache-check-files + - restore-cache: *restore-yarn-cache - run: *yarn - save-cache: *save-yarn-cache @@ -167,181 +253,211 @@ jobs: - run: *validate-flow-declarations - run: *validate-ts-declarations + # ------------------------- + # ANDROID - BUILD + # ------------------------- android-build-debug: <<: *android_defaults steps: - attach_workspace: at: ~/react-native-firebase + - run: *make-cache-check-files - restore-cache: *restore-yarn-cache - run: *yarn - save-cache: *save-yarn-cache - # # must always be after environment config job but before android build - # - run: *packager-jet - # - run: *packager-warmup# - # - run: *android-launch-avd + - restore-cache: *restore-gradle-wrapper-cache + - restore_cache: *restore-gradle-home-caches - # restore saved caches - - restore_cache: - keys: - - gradle-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} + - restore-cache: *restore-gradle-debug-build-cache + - run: *disperse-gradle-build-caches - - restore_cache: - keys: - # for multi-project builds where dependencies are not defined in one central file, - # an additional run step before is necessary that concatenates affected files - # into one file that can be checksummed - - gradle-cache-{{ checksum "tests/android/build.gradle" }} - - gradle-cache - - - restore_cache: - keys: - - gradle-build-caches-{{ .Revision }} - - gradle-build-caches - - - run: - name: Restoring Gradle Build Caches - command: | - [ -d ~/gradle-build-caches ] && - [ -n "$(ls -A ~/gradle-build-caches)" ] && - rm -rf ~/.gradle/caches/build-cache-* && - mkdir -p ~/.gradle/caches/ && - mv ~/gradle-build-caches/* ~/.gradle/caches/ || true +# - run: *android-accept-licenses # download and cache dependencies and Gradle - run: - name: Downloading Dependencies + name: Downloading Gradle Dependencies command: cd tests/android && ./gradlew --max-workers 6 downloadDependencies - - save_cache: - paths: - - ~/.gradle/wrapper/ - key: gradle-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} - - - save_cache: - paths: - - ~/.gradle/caches/ - key: gradle-cache-{{ checksum "tests/android/build.gradle" }} + - save-cache: *save-gradle-wrapper-cache + - save-cache: *save-gradle-home-caches - run: name: Build Android Testing App command: cd tests/android && chmod +x gradlew && ./gradlew --build-cache --max-workers 6 --continue assembleDebug assembleAndroidTest -DtestBuildType=debug --stacktrace - # cache gradle build caches - - run: - name: Collecting Gradle Build Caches - command: | - mkdir -p ~/gradle-build-caches - [ -d ~/.gradle/caches ] && - [ -n "$(ls -Ad ~/.gradle/caches/build-cache-* 2>/dev/null)" ] && - rm -rf ~/gradle-build-caches/* && - mv ~/.gradle/caches/build-cache-* ~/gradle-build-caches || true - when: always + - run: *collect-gradle-build-caches + - save-cache: *save-gradle-debug-build-cache - - save_cache: + - persist_to_workspace: + root: ~/react-native-firebase paths: - - ~/gradle-build-caches - key: gradle-build-caches-{{ .Revision }} - when: always - - # - run: *android-wait-avd - # - # # Now Test \o/ - # - run: - # name: Run Jet Tests - # command: cd tests && yarn run test-android-cover - # - # # TODO merge coverage output from android and iOS - # - run: - # name: Submit Coverage - # command: yarn run codecov - # - # - store_artifacts: - # path: ~/detox-artifacts - # - store_artifacts: - # path: ~/react-native-firebase/coverage + - tests/android/app/build/outputs/apk android-build-release: <<: *android_defaults steps: - attach_workspace: at: ~/react-native-firebase + - run: *make-cache-check-files - restore-cache: *restore-yarn-cache - run: *yarn - save-cache: *save-yarn-cache - # restore saved caches - - restore_cache: - keys: - - gradle-release-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} + - restore-cache: *restore-gradle-wrapper-cache + - restore_cache: *restore-gradle-home-caches - - restore_cache: - keys: - # for multi-project builds where dependencies are not defined in one central file, - # an additional run step before is necessary that concatenates affected files - # into one file that can be checksummed - - gradle-release-cache-{{ checksum "tests/android/build.gradle" }} - - gradle-release-cache + - restore-cache: *restore-gradle-release-build-cache + - run: *disperse-gradle-build-caches - - restore_cache: - keys: - - gradle-release-build-caches-{{ .Revision }} - - gradle-release-build-caches - - - run: - name: Restoring Gradle Build Caches - command: | - [ -d ~/gradle-build-caches ] && - [ -n "$(ls -A ~/gradle-build-caches)" ] && - rm -rf ~/.gradle/caches/build-cache-* && - mkdir -p ~/.gradle/caches/ && - mv ~/gradle-build-caches/* ~/.gradle/caches/ || true +# - run: *android-accept-licenses # download and cache dependencies and Gradle - run: name: Downloading Dependencies command: cd tests/android && ./gradlew --max-workers 6 downloadDependencies - - save_cache: - paths: - - ~/.gradle/wrapper/ - key: gradle-release-wrapper-{{ checksum "tests/android/gradle/wrapper/gradle-wrapper.properties" }} - - - save_cache: - paths: - - ~/.gradle/caches/ - key: gradle-release-cache-{{ checksum "tests/android/build.gradle" }} + - save-cache: *save-gradle-wrapper-cache + - save-cache: *save-gradle-home-caches - run: name: Build Android Testing App command: cd tests/android && chmod +x gradlew && ./gradlew --build-cache --max-workers 2 --continue assembleRelease - # cache gradle build caches - - run: - name: Collecting Gradle Build Caches - command: | - mkdir -p ~/gradle-build-caches - [ -d ~/.gradle/caches ] && - [ -n "$(ls -Ad ~/.gradle/caches/build-cache-* 2>/dev/null)" ] && - rm -rf ~/gradle-build-caches/* && - mv ~/.gradle/caches/build-cache-* ~/gradle-build-caches || true - when: always + - run: *collect-gradle-build-caches + - save-cache: *save-gradle-release-build-cache - - save_cache: + - persist_to_workspace: + root: ~/react-native-firebase paths: - - ~/gradle-build-caches - key: gradle-release-build-caches-{{ .Revision }} - when: always + - tests/android/app/build/outputs/apk + # ------------------------- + # ANDROID - TEST E2E + # ------------------------- + + android-test-e2e: + <<: *macos_defaults + steps: + - attach_workspace: + at: ~/react-native-firebase + - run: *make-cache-check-files + + - run: + name: Configure Environment Variables + command: | + echo 'export PATH="$PATH:/usr/local/opt/node@8/bin:~/.yarn/bin:~/react-native-firebase/node_modules/.bin:~/react-native-firebase/tests/node_modules/.bin"' >> $BASH_ENV + echo 'export ANDROID_HOME="/usr/local/share/android-sdk"' >> $BASH_ENV + echo 'export ANDROID_SDK_ROOT="/usr/local/share/android-sdk"' >> $BASH_ENV + echo 'export PATH="$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:$PATH"' >> $BASH_ENV + echo 'export QEMU_AUDIO_DRV=none' >> $BASH_ENV + echo 'export JAVA_HOME=/Library/Java/Home' >> $BASH_ENV + source $BASH_ENV + + - run: + name: Install Android SDK Tools + command: | + HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/cask >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew cask install android-sdk >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew cask install intel-haxm >/dev/null + HOMEBREW_NO_AUTO_UPDATE=1 brew install node@8 >/dev/null >/dev/null + + # Yarn install - to ensure detox post install builds + - restore-cache: *restore-yarn-cache + - run: *yarn + - save-cache: *save-yarn-cache + + # must always be after environment config job but before ios build + - run: *packager-jet + - run: *packager-warmup + + - run: + name: Install Android Emulator + shell: /bin/bash -e + command: | + yes | sdkmanager "platform-tools" "tools" >/dev/null + yes | sdkmanager "platforms;android-28" "system-images;android-27;google_apis;x86" "system-images;android-28;google_apis;x86" >/dev/null + yes | sdkmanager "emulator" --channel=3 >/dev/null + yes | sdkmanager "build-tools;28.0.3" >/dev/null + yes | sdkmanager --licenses >/dev/null + yes | sdkmanager --list + + # to force ssh key generation for emulators + - run: + name: ADB Start Stop + command: | + adb start-server + adb devices + adb kill-server + ls -la ~/.android + +# - run: +# name: Create Android Emulator (API 27) +# command: avdmanager create avd -n TestingAVD -k "system-images;android-27;google_apis;x86" -g google_apis -d "Nexus 4" +# +# - run: +# name: Start Android Emulator (API 27) in background +# command: | +# /usr/local/share/android-sdk/emulator/emulator @TestingAVD -version +# /usr/local/share/android-sdk/emulator/emulator @TestingAVD -skin 470x860 -cores 2 -gpu auto -accel on -memory 2048 -no-audio -no-snapshot -no-window -logcat *:W | grep -i 'ReactNative\|RNFB\|com.testing\|io.invertase\|firebase' +# background: true +# +# - run: +# name: Wait for AVD to be ready (API 27) +# no_output_timeout: "5m" +# command: sh ./.circleci/scripts/wait-for-avd.sh +# +# - run: +# name: Run Tests (API 27) +# command: yarn run tests:android:test-cover +# +# - run: +# name: Stop Emulators (API 27) +# command: adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done + + - run: + name: Create Android Emulator (API 28) + command: avdmanager create avd --force -n TestingAVD -k "system-images;android-28;google_apis;x86" -g google_apis -d "Nexus 4" + + - run: + name: Start Android Emulator (API 28) in background + command: | + /usr/local/share/android-sdk/emulator/emulator @TestingAVD -version + /usr/local/share/android-sdk/emulator/emulator @TestingAVD -skin 470x860 -cores 2 -gpu auto -accel on -memory 2048 -no-audio -no-snapshot -no-window -logcat *:W | grep -i 'ReactNative\|RNFB\|com.testing\|io.invertase\|firebase' + background: true + + - run: + name: Wait for AVD to be ready (API 28) + no_output_timeout: "5m" + command: sh ./.circleci/scripts/wait-for-avd.sh + + - run: + name: Run Tests (API 28) + command: yarn run tests:android:test-cover + + - run: + name: Submit Coverage + command: yarn run codecov + + - store_artifacts: + path: ~/detox-artifacts + - store_artifacts: + path: ~/react-native-firebase/coverage + + # ------------------------- + # iOS - TEST E2E + # ------------------------- ios-test-e2e: <<: *macos_defaults steps: - attach_workspace: at: ~/react-native-firebase + - run: *make-cache-check-files + - run: name: Start iPhone X simulator (background) background: true @@ -349,11 +465,13 @@ jobs: - run: name: Configure Environment Variables command: | - echo 'export PATH=/usr/local/opt/node@8/bin:$PATH' >> $BASH_ENV + echo 'export PATH="$PATH:/usr/local/opt/node@8/bin:~/.yarn/bin:~/react-native-firebase/node_modules/.bin:~/react-native-firebase/tests/node_modules/.bin"' >> $BASH_ENV source $BASH_ENV + + # Brew - restore-cache: *restore-brew-cache - - run: *configure-jet-detox-environment + - run: *configure-ios-detox-environment - save-cache: *save-brew-cache # Yarn install - to ensure detox post install builds @@ -361,6 +479,10 @@ jobs: - run: *yarn - save-cache: *save-yarn-cache + # must always be after environment config job but before ios build + - run: *packager-jet + - run: *packager-warmup + # Pods - restore-cache: *restore-pods-cache - run: @@ -371,15 +493,11 @@ jobs: pod install - save-cache: *save-pods-cache - # must always be after environment config job but before ios build - - run: *packager-jet - - run: *packager-warmup - # XCode Build - restore-cache: *restore-ios-build-cache - run: name: Build iOS Testing App - command: cd tests && yarn run build-ios + command: yarn run tests:ios:build - save-cache: *save-ios-build-cache - run: mkdir ~/detox-artifacts @@ -387,9 +505,8 @@ jobs: # Now Test \o/ - run: name: Run Jet Tests - command: cd tests && yarn run test-ios-cover + command: yarn run tests:ios:test-cover - # TODO merge coverage output from android and iOS - run: name: Submit Coverage command: yarn run codecov @@ -399,31 +516,41 @@ jobs: - store_artifacts: path: ~/react-native-firebase/coverage - # ------------------------- # WORK FLOWS # ------------------------- workflows: version: 2 - Test: +# filters: +# branches: +# only: master + + JS: jobs: - checkout-code - - analyse: requires: - checkout-code + Android: + jobs: + - checkout-code + - android-build-debug: requires: - checkout-code - - analyse - android-build-release: requires: - checkout-code - - analyse + - android-test-e2e: + requires: + - android-build-debug + + iOS: + jobs: + - checkout-code - ios-test-e2e: requires: - checkout-code - - analyse diff --git a/.circleci/scripts/wait-for-avd.sh b/.circleci/scripts/wait-for-avd.sh old mode 100755 new mode 100644 index 797c4cd1..3229b1e0 --- a/.circleci/scripts/wait-for-avd.sh +++ b/.circleci/scripts/wait-for-avd.sh @@ -6,11 +6,11 @@ echo "Waiting for AVD to finish booting" export PATH=$(dirname $(dirname $(command -v android)))/platform-tools:$PATH until [[ "$bootanim" =~ "stopped" ]]; do - sleep 5 + sleep 10 bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1) - echo "Android device boot animation status is '$bootanim'" done -sleep 5 +# extra time to let the OS settle +sleep 25 echo "Android Virtual Device is now ready." diff --git a/.eslintignore b/.eslintignore index 9158fce1..966f8747 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,8 @@ src/version.js +packages/**/node_modules/** +**/*.ts +node_modules +tests/ +scripts/ +coverage +docs diff --git a/.eslintrc b/.eslintrc index 5fb91e5c..9e08d35d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,41 +1,41 @@ { - "extends": [ - "airbnb", - "prettier", - "prettier/flowtype", - "prettier/react" - ], + "root": true, + "extends": ["airbnb", "prettier", "prettier/flowtype", "prettier/react"], "parser": "babel-eslint", - "plugins": [ - "flowtype", - "prettier" - ], + "plugins": ["flowtype", "prettier"], "env": { "es6": true, - "jasmine": true + "node": true, + "shelljs": true, + "jest": true }, "rules": { - "prettier/prettier": ["error", { - "trailingComma": "es5", - "singleQuote": true - }], - - "react/forbid-prop-types": "warn", - "react/jsx-filename-extension": [ - "off", { "extensions": [".js", ".jsx"] } - ], - + "no-extend-native": 0, + "import/no-dynamic-require": 0, + "global-require": "off", "class-methods-use-this": 0, - "no-console": 0, + "no-console": 1, "no-plusplus": 0, "no-undef": 0, "no-underscore-dangle": "off", "no-use-before-define": 0, - "import/no-cycle": 0, - "import/no-useless-path-segments": 0 + "react/forbid-prop-types": "warn", + "react/jsx-filename-extension": ["off", { "extensions": [".js", ".jsx"] }], + "import/no-cycle": 1, + "import/no-unresolved": 0 }, + "overrides": [ + { + "files": ["packages/*/test/**/*.js", "test/**/*.js"], + "env": { + "jest": true + } + } + ], "globals": { "__DEV__": true, + "__RNFB__": true, "window": true + } } diff --git a/.flowconfig b/.flowconfig index 8b3ac4c1..9c629877 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,55 +1,25 @@ [ignore] -; We fork some components by platform -.*/*[.]android.js - -; Ignore "BUCK" generated dirs -/\.buckd/ - -; Ignore unexpected extra "@providesModule" -.*/node_modules/.*/node_modules/fbjs/.* - -; Ignore duplicate module providers -; For RN Apps installed via npm, "Libraries" folder is inside -; "node_modules/react-native" but in the source repo it is in the root -.*/Libraries/react-native/React.js - -; Ignore polyfills -.*/Libraries/polyfills/.* - ; Ignore metro .*/node_modules/metro/.* -# Ignore dist folder -.*/dist/.* - # Ignore tests project .*/tests/.* [include] +packages/**/lib/*.js.flow +packages/*-types/*.js.flow [lints] -[libs] -node_modules/react-native/Libraries/react-native/react-native-interface.js -node_modules/react-native/flow/ - [options] emoji=true esproposal.optional_chaining=enable esproposal.nullish_coalescing=enable -# Taken from: https://github.com/facebook/react-native/issues/19766 module.system=haste module.system.haste.use_name_reducers=true -# keep the following in sync with server/haste/hasteImpl.js -# get basename module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' -# strip .js or .js.flow suffix module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' -# strip .ios suffix -module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' module.system.haste.paths.blacklist=.*/__tests__/.* module.system.haste.paths.blacklist=.*/__mocks__/.* module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* @@ -60,9 +30,6 @@ munge_underscores=true module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' module.file_ext=.js -module.file_ext=.jsx -module.file_ext=.json -module.file_ext=.native.js suppress_type=$FlowIssue suppress_type=$FlowFixMe @@ -75,4 +42,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError [version] -^0.80.0 +^0.89.0 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..aef1e525 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.xcodeproj binary +*.xcworkspace binary diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 0342b449..db3d6f5b 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -115,14 +115,16 @@ This issue list of this repo is exclusively for bug reports. - [ ] Crashlytics - [ ] Dynamic **Links** - [ ] **Functions** Callable + - [ ] In App Messaging + - [ ] Indexing - [ ] Invites - [ ] Instance ID + - [ ] ML Kit - [ ] Notifications - [ ] Performance Monitoring - [ ] Realtime **Database** - [ ] Remote **Config** - [ ] Storage - - [ ] In App Messaging - **Are you using `TypeScript`?** - [ ] No - [ ] Yes, version: `N/A` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e312c12a..60ba737c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ - + ### Summary diff --git a/.github/stale.yml b/.github/stale.yml index 133aa68a..d2520054 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -4,7 +4,6 @@ daysUntilStale: 28 daysUntilClose: 14 # Issues with these labels will never be considered stale exemptLabels: - - 📌 pin - await-invertase-feedback - await-firebase-sdk-fix - await-maintainer-feedback diff --git a/.gitignore b/.gitignore index d8767b33..0240516b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,56 +1,134 @@ -coverage -coverage.ios.json -coverage.android.json -node_modules -npm-debug.log -*.DS_Store - -# Xcode -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 -*.xcuserstate -project.xcworkspace/ -atlassian-ide-plugin -xcuserdata/ - -# Example -example/demo/ios/demo.xcworkspace/ +# Created by https://www.gitignore.io/api/node,xcode,gradle,android,webstorm,firebase,reactnative,androidstudio,visualstudiocode +### Android ### # Built application files -**/android/**/build/ +*.apk +*.ap_ -# Crashlytics configuations -android/com_crashlytics_export_strings.xml +# Files for the ART/Dalvik VM +*.dex -# Signing files -android/.signing/ +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ # Local configuration file (sdk path, etc) -**/android/local.properties +local.properties -# Gradle generated files -**/android/.gradle/ +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +.idea/caches + +# Keystore files +# Uncomment the following line if you do not want to check your keystore files in. +#*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +### Android Patch ### +gen-external-apklibs + +### AndroidStudio ### +# Covers files to be ignored for android development using Android Studio. + +# Built application files + +# Files for the ART/Dalvik VM + +# Java class files + +# Generated files + +# Gradle files +.gradle # Signing files -android/.signing/ +.signing/ + +# Local configuration file (sdk path, etc) + +# Proguard folder generated by Eclipse + +# Log Files + +# Android Studio +/*/build/ +/*/local.properties +/*/out +/*/*/build +/*/*/production +*.ipr +*~ +*.swp + +# Android Patch + +# External native build folder generated in Android Studio 2.2 and later + +# NDK +obj/ + +# IntelliJ IDEA +*.iws +/out/ # User-specific configurations -android/.idea/gradle.xml -android/.idea/libraries/ -android/.idea/workspace.xml -android/.idea/tasks.xml -android/.idea/.name -android/.idea/compiler.xml -android/.idea/copyright/profiles_settings.xml -android/.idea/encodings.xml -android/.idea/misc.xml -android/.idea/modules.xml -android/.idea/scopes/scope_settings.xml -android/.idea/vcs.xml -**/android/**/*.iml -ios/RnFirebase.xcodeproj/xcuserdata +.idea/caches/ +.idea/libraries/ +.idea/shelf/ +.idea/.name +.idea/compiler.xml +.idea/copyright/profiles_settings.xml +.idea/encodings.xml +.idea/misc.xml +.idea/modules.xml +.idea/scopes/scope_settings.xml +.idea/vcs.xml +.idea/jsLibraryMappings.xml +.idea/datasources.xml +.idea/dataSources.ids +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml # OS-specific files .DS_Store @@ -59,32 +137,414 @@ ios/RnFirebase.xcodeproj/xcuserdata .Spotlight-V100 .Trashes ehthumbs.db -Thumbs.dbandroid/gradle -android/gradlew -android/build -android/.gradle -android/gradlew.bat -android/gradle -lib/.watchmanconfig +Thumbs.db + +# Legacy Eclipse project files +.classpath +.project +.cproject +.settings/ + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.war +*.ear + +# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) +hs_err_pid* + +## Plugin-specific files: + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Mongo Explorer plugin +.idea/mongoSettings.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### AndroidStudio Patch ### + +!/gradle/wrapper/gradle-wrapper.jar + +### Firebase ### .idea +**/node_modules/* +**/.firebaserc + +### Firebase Patch ### +.runtimeconfig.json + +### Node ### +# Logs +logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul coverage -.gradle -local.properties -*.iml - -**/ios/Pods/** -**/ios/ReactNativeFirebaseDemo.xcworkspace/ -dist -version.js +# nyc test coverage .nyc_output -ios.coverage.json -**/android/.project -**/android/.classpath -**/android/.settings -**/android/app/.settings -**/.vscode -tests/android/app/.project -tests/android/app/.classpath -**/*.xcworkspace/** -tests/functions/firebase-debug.log + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +### ReactNative ### +# React Native Stack Base + +### ReactNative.macOS Stack ### +# General +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.TemporaryItems +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### ReactNative.Xcode Stack ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +### ReactNative.Gradle Stack ### +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +### ReactNative.Buck Stack ### +buck-out/ +.buckconfig.local +.buckd/ +.buckversion +.fakebuckversion + +### ReactNative.Linux Stack ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### ReactNative.Node Stack ### +# Logs + +# Runtime data + +# Directory for instrumented libs generated by jscoverage/JSCover + +# Coverage directory used by tools like istanbul + +# nyc test coverage + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +# Bower dependency directory (https://bower.io/) + +# node-waf configuration + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +# Dependency directories + +# TypeScript v1 declaration files + +# Optional npm cache directory + +# Optional eslint cache + +# Optional REPL history + +# Output of 'npm pack' + +# Yarn Integrity file + +# dotenv environment variables file + +# parcel-bundler cache (https://parceljs.org/) + +# next.js build output + +# nuxt.js build output + +# vuepress build output + +# Serverless directories + +### ReactNative.Android Stack ### +# Built application files + +# Files for the ART/Dalvik VM + +# Java class files + +# Generated files + +# Gradle files + +# Local configuration file (sdk path, etc) + +# Proguard folder generated by Eclipse + +# Log Files + +# Android Studio Navigation editor temp files + +# Android Studio captures folder + +# IntelliJ + +# Keystore files +# Uncomment the following line if you do not want to check your keystore files in. +#*.jks + +# External native build folder generated in Android Studio 2.2 and later + +# Freeline + +# fastlane + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### WebStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/discord.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/codeStyles +.idea/**/codeStyleSettings.xml +.idea/**/markdown-navigator +.idea/**/markdown-navigator.xml +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +packages/**/.idea + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### WebStorm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Xcode ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) + +### Xcode Patch ### +*.xcodeproj/* +Pods/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcworkspace/contents.xcworkspacedata +/*.gcno + +### Gradle ### + +# Ignore Gradle GUI config + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) + +# Cache of project + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + + +# End of https://www.gitignore.io/api/node,xcode,gradle,android,webstorm,firebase,reactnative,androidstudio,visualstudiocode + +.idea/**/* +**/Pods/** +**/dist/ +**/version.js +typedoc.raw.json +tests/ios/Firebase +.tmp diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..8c44914c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +package.json +packages/**/node_modules/** +tests/node_modules/** diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..727f8868 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,20 @@ +{ + "arrowParens": "avoid", + "trailingComma": "all", + "useTabs": false, + "semi": true, + "singleQuote": true, + "bracketSpacing": true, + "jsxBracketSameLine": false, + "tabWidth": 2, + "printWidth": 100, + "overrides": [{ + "files": [ + "**/packages/library/**/*.js" + ], + "parser": "babylon", + "options": { + "trailingComma": "all" + } + }] +} diff --git a/.watchmanconfig b/.watchmanconfig new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/LICENSE b/LICENSE index d1a9739f..9a44423e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,12 @@ -Copyright (c) 2018 Invertase Limited +Apache-2.0 License +------------------ + +Copyright (c) 2016-present Invertase Limited Licensed under the Apache License, Version 2.0 (the "License"); you may not use this library except in compliance with the License. -You may obtain a copy of the License at + +You may obtain a copy of the Apache-2.0 License at http://www.apache.org/licenses/LICENSE-2.0 @@ -11,3 +15,18 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + +Creative Commons Attribution 3.0 License +---------------------------------------- + +Copyright (c) 2016-present Invertase Limited + +Documentation and other instructional materials provided for this project +(including on a separate documentation repository or it's documentation website) are +licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks +contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above. + +You may obtain a copy of the Creative Commons Attribution 3.0 License at + + https://creativecommons.org/licenses/by/3.0/ diff --git a/README.md b/README.md index 0d4a0606..313e0534 100644 --- a/README.md +++ b/README.md @@ -1,132 +1,87 @@

-
+
-

React Native Firebase

+

React Native Firebase

NPM downloads NPM version License - Backers on Open Collective - Sponsors on Open Collective + Backers on Open Collective + Sponsors on Open Collective Chat Follow on Twitter

-## Introduction +--- -**React Native Firebase** is a _light-weight_ javascript layer connecting you to the native Firebase SDKs for both iOS and Android which aims to mirror the official Firebase Web SDK as closely as possible. - -Although the official [Firebase JS SDK](https://www.npmjs.com/package/firebase) will work with React Native; it is mainly built for the web and has a limited feature-set compared to native. - -Using the native Firebase SDKs with **React Native Firebase** allows you to consume device SDKs which don't exist on the Firebase JS SDK - for example; Remote Config, Performance Monitoring, Dynamic Links, Analytics and more (see the feature table below for comparison). +> **WARNING**: This branch is a work in progress re-write of React Native Firebase, you're probably looking for the [v5.x.x branch](https://github.com/invertase/react-native-firebase/tree/v5.x.x) instead. You can [learn more about this here](https://blog.invertase.io/react-native-firebase-2019-7e334ca9bcc6). --- -## Supported Firebase Features +**React Native Firebase** is a collection of official React Native modules connecting you to Firebase services; each module is a light-weight javascript layer connecting you to the native Firebase SDKs for both iOS and Android. -> The Web SDK column indicates what modules/functionality from the Web SDK are usable within React Native. +React Native Firebase is built with four key principals in mind; -> '**?**' indicates partial support +- 🧪 **Well tested** + - every module is extensively tested to >95% coverage +- 👁 **Well typed** + - first class support for both Flow & Typescript included +- 📄 **Well documented** + - full reference & installation documentation alongside detailed guides and FAQs +- 🔥 **Mirrors official Firebase Web SDK** + - functions as drop-in replacement for the Firebase Web SDK in React Native + - maximises cross-platform code re-usability e.g. re-using code on web platforms -| Firebase Features | v5.x.x | Web SDK | -| --------------------------------------------------------------------------------------------------------------------------------- | :----: | :-----: | -| **AdMob** | ✅ | ❌ | -| **Analytics**             | ✅ | ❌ | -| **App Indexing**           | ❌ | ❌ | -| **Authentication** | ✅ | ✅ | -| _-- Phone Auth_ | ✅ | ✅ | -| **Core** | ✅ | ✅ | -| _-- Multiple Apps_ | ✅ | ✅ | -| **Cloud Firestore** | ✅ | ✅ | -| **Cloud Messaging (FCM)** | ✅ | ❌ | -| **Crashlytics**           | ✅ | ❌ | -| **Dynamic Links** | ✅ | ❌ | -| **[Functions Callable](https://firebase.googleblog.com/2018/04/launching-cloud-functions-for-firebase-1-0.html?m=1)**             |  ✅ |   ✅   | -| **Invites** | ✅ | ❌ | -| **Instance ID**          | ✅ | ❌ | -| **Performance Monitoring** | ✅ | ❌ | -| **Realtime Database** | ✅ | ✅ | -| _-- Offline Persistence_ | ✅ | **?** | -| **Remote Config** | ✅ | ❌ | -| **Storage** | ✅ | ✅ | +## Firebase Modules ---- +This in the root of the mono repo for React Native Firebase, if you're looking for a specific package please select the package link from below. -### Supported versions - React Native / Firebase +The main module that you interface with is `App` (`@react-native-firebase/app`) -> The table below shows the supported versions of React Native and the Firebase SDKs for different versions of `react-native-firebase`. +| Name | Downloads | Coverage | +| ----------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------: | +| [App](/packages/app) | [![badge](https://img.shields.io/npm/dm/@react-native-firebase/app.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@react-native-firebase/app) | ![badge](https://img.shields.io/badge/0%25-coverage-yellow.svg?style=for-the-badge) | +| [Analytics](/packages/analytics) | [![badge](https://img.shields.io/npm/dm/@react-native-firebase/analytics.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@react-native-firebase/analytics) | ![badge](https://img.shields.io/badge/0%25-coverage-yellow.svg?style=for-the-badge) | +| [Functions](/packages/functions) | [![badge](https://img.shields.io/npm/dm/@react-native-firebase/functions.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@react-native-firebase/functions) | ![badge](https://img.shields.io/badge/0%25-coverage-yellow.svg?style=for-the-badge) | +| [Instance ID](/packages/iid) | [![badge](https://img.shields.io/npm/dm/@react-native-firebase/iid.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@react-native-firebase/iid) | ![badge](https://img.shields.io/badge/0%25-coverage-yellow.svg?style=for-the-badge) | +| [Performance Monitoring](/packages/perf) | [![badge](https://img.shields.io/npm/dm/@react-native-firebase/perf.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@react-native-firebase/perf) | ![badge](https://img.shields.io/badge/0%25-coverage-yellow.svg?style=for-the-badge) | -| | 3.3.x | 4.3.x | 5.x.x | -| ------------------------- | :------: | :-----: | :---------------: | -| React Native | 0.50-52 | 0.52-55 | ^0.56 - ^0.58 | -| Play Services Android SDK | 11.8.0 + | 15.0.1 | ^16.0.1 | -| Firebase iOS SDK | 4.7.0 + | 5.3.0 | ^5.10.0 - ^5.15.0 | +> TODO +## Other Packages ---- +React Native Firebase also publishes several other packages, some only used internally, others for public consumption such as Hooks. + +| Name | Description | +| -------------------------------- | :--------------------------------------------: | +| [app-types](/packages/app-types) | Common Firebase types used by and all modules. | +| [common](/packages/common) | Common utilities used by all modules. | +| [hooks](/packages/hooks) | React Hooks for React Native Firebase. | + +> TODO ## Documentation -To check out our latest docs, visit [https://invertase.io/oss/react-native-firebase](https://invertase.io/oss/react-native-firebase) +- [Guides](#TODO) +- [Installation](#TODO) -## Questions +## Contributing -For questions and support please use our [Discord chat](https://discord.gg/C9aK28N) or [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native-firebase). The issue list of this repo is **exclusively** for bug reports. - -## Issues - -Please make sure to complete the issue template before opening an issue. Issues not conforming to the guidelines may be closed immediately. - -## Feature Requests - -For feature requests please visit our [Feature Request Board](https://boards.invertase.io/react-native-firebase). - -## Changelog - -Detailed changes for each release are documented in the [releases notes](https://github.com/invertase/react-native-firebase/releases). - ---- - -## Supporting RNFirebase - -RNFirebase is an Apache-2.0 licensed open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome [sponsors](#sponsors) and [backers](#backers). If you'd like to join them, please consider: - -- [Become a backer or sponsor on Open Collective](https://opencollective.com/react-native-firebase). - -### Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/react-native-firebase#sponsor)] - - - - - - - - - - - - -### Backers - -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/react-native-firebase#backer)] - - - -### Contributing - -Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before making a pull request. - -Thank you to all the people who have already contributed to RNFirebase! - - - -
+- [Contributing](/CONTRIBUTING.md) +- [Code of Conduct](/CODE_OF_CONDUCT.md) +- [Testing](/tests/README.md) ## License - See [LICENSE](/LICENSE) + +--- + +Built and maintained with 💛 by [Invertase](https://invertase.io). + +- [💼 Hire Us](https://invertase.io/hire-us) +- [☕️ Sponsor Us](https://opencollective.com/react-native-firebase) +- [👩‍💻 Work With Us](https://invertase.io/jobs) diff --git a/android/.editorconfig b/android/.editorconfig deleted file mode 100644 index 0f099897..00000000 --- a/android/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -# editorconfig.org -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index bc825c14..00000000 --- a/android/build.gradle +++ /dev/null @@ -1,199 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - maven { - url 'https://maven.fabric.io/public' - } - } - dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' - } -} - -apply plugin: 'com.android.library' - -def DEFAULT_COMPILE_SDK_VERSION = 27 -def DEFAULT_BUILD_TOOLS_VERSION = "28.0.2" -def DEFAULT_TARGET_SDK_VERSION = 27 -def DEFAULT_SUPPORT_LIB_VERSION = "27.1.1" - -android { - compileSdkVersion rootProject.hasProperty('compileSdkVersion') ? rootProject.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION - buildToolsVersion rootProject.hasProperty('buildToolsVersion') ? rootProject.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION - defaultConfig { - minSdkVersion 16 - targetSdkVersion rootProject.hasProperty('targetSdkVersion') ? rootProject.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION - versionCode 1 - versionName "1.0" - multiDexEnabled true - } - buildTypes { - release { - minifyEnabled false - } - } - productFlavors { - } - lintOptions { - disable 'GradleCompatible' - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -rootProject.gradle.buildFinished { buildResult -> - if (buildResult.getFailure() != null) { - //noinspection GroovyUnusedCatchParameter - try { - String message = buildResult.getFailure().properties.get("reportableCauses").toString() - if (message.contains("com.android.dex.DexException: Multiple dex files define Lcom/google/") || - message.contains("java.util.zip.ZipException: duplicate entry: com/google/android/gms/")) { - logger.log(LogLevel.ERROR, "") - logger.log(LogLevel.ERROR, " -----------------------------------------------------------") - logger.log(LogLevel.ERROR, "| REACT NATIVE FIREBASE |") - logger.log(LogLevel.ERROR, " ----------------------------------------------------------- ") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| This is a common build error when using libraries that |") - logger.log(LogLevel.ERROR, "| require google play services. |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| This error occurs because different versions of google |") - logger.log(LogLevel.ERROR, "| play services or google play services modules are being |") - logger.log(LogLevel.ERROR, "| required by different libraries. |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| A temporary fix would be to set: |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| android { multiDexEnabled true } |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| inside your build gradle, however it is recommended for |") - logger.log(LogLevel.ERROR, "| your prod build that you de-duplicate these to minimize |") - logger.log(LogLevel.ERROR, "| bundle size. |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, "| See http://invertase.link/dupe-dex for how to do this. |") - logger.log(LogLevel.ERROR, "| |") - logger.log(LogLevel.ERROR, " ----------------------------------------------------------- ") - } - } catch (Exception exception) { - } - } -} - -repositories { - google() - jcenter() - - def found = false - def parentDir = rootProject.projectDir - def androidSourcesName = 'React Native sources' - def androidPrebuiltBinaryName = 'React Native prebuilt binary' - - 1.upto(4, { - if (found) return true - parentDir = parentDir.parentFile - - // Running React Native from sources locally or for ExpoKit - def androidSourcesDir = new File( - parentDir, - 'node_modules/react-native' - ) - - // Official releases of React Native come with a prebuilt version of Android sources - // in ./android, e.g. react-native/android/**/react-native-0.57.1.aar - def androidPrebuiltBinaryDir = new File( - parentDir, - 'node_modules/react-native/android' - ) - - if (androidPrebuiltBinaryDir.exists()) { - maven { - url androidPrebuiltBinaryDir.toString() - name androidPrebuiltBinaryName - } - - println "${project.name}: using ${androidPrebuiltBinaryName} from ${androidPrebuiltBinaryDir.toString()}" - found = true - } else if (androidSourcesDir.exists()) { - maven { - url androidSourcesDir.toString() - name androidSourcesName - } - - println "${project.name}: using ${androidSourcesName} from ${androidSourcesDir.toString()}" - found = true - } - }) - - if (!found) { - throw new GradleException( - "${project.name}: unable to locate React Native android sources or prebuilt binary. " + - "Ensure you have you installed React Native as a dependency in your project and try again." - ) - } -} - -def supportVersion = rootProject.hasProperty('supportLibVersion') ? rootProject.supportLibVersion : DEFAULT_SUPPORT_LIB_VERSION - -dependencies { - //noinspection GradleDynamicVersion - api "com.facebook.react:react-native:+" - - /* ---------------------------- - * REACT NATIVE FIREBASE - * ---------------------------- */ - - // Required dependencies - //noinspection GradleCompatible - compileOnly "com.google.firebase:firebase-core:16.0.6" - compileOnly "com.google.android.gms:play-services-base:16.0.1" - - /* ------------------------- - * OPTIONAL FIREBASE SDKS - * ------------------------- */ - - // Ads - compileOnly('com.google.firebase:firebase-ads:15.0.1') { - // exclude `customtabs` as the support lib version is out of date - // we manually add it as a dependency below with a custom version - exclude group: 'com.android.support', module: 'customtabs' - } - // Authentication - compileOnly "com.google.firebase:firebase-auth:16.1.0" - // Analytics - compileOnly "com.google.firebase:firebase-analytics:16.0.6" - // Performance Monitoring - compileOnly "com.google.firebase:firebase-perf:16.2.3" - // Remote Config - compileOnly "com.google.firebase:firebase-config:16.1.2" - // Cloud Storage - compileOnly "com.google.firebase:firebase-storage:16.0.5" - // Invites - compileOnly "com.google.firebase:firebase-invites:16.0.6" - // Dynamic Links - compileOnly "com.google.firebase:firebase-dynamic-links:16.1.5" - // Real-time Database - compileOnly "com.google.firebase:firebase-database:16.0.5" - // Cloud Functions - compileOnly "com.google.firebase:firebase-functions:16.1.3" - // Cloud Firestore - compileOnly "com.google.firebase:firebase-firestore:17.1.5" - // Cloud Messaging / FCM - compileOnly "com.google.firebase:firebase-messaging:17.3.4" - // Crashlytics - compileOnly('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') { - transitive = true - } - /* -------------------------------- - * OPTIONAL SUPPORT LIBS - * -------------------------------- */ - - // For Firebase Ads - compileOnly "com.android.support:customtabs:$supportVersion" - - // For React Native Firebase Notifications - api "com.android.support:support-v4:$supportVersion" - - // For React Native Firebase Notifications - compileOnly 'me.leolin:ShortcutBadger:1.1.21@aar' -} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml deleted file mode 100644 index 8883e1d3..00000000 --- a/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/android/src/main/java/io/invertase/firebase/ErrorUtils.java b/android/src/main/java/io/invertase/firebase/ErrorUtils.java deleted file mode 100644 index 85d4fdb0..00000000 --- a/android/src/main/java/io/invertase/firebase/ErrorUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.invertase.firebase; - -public class ErrorUtils { - /** - * Wrap a message string with the specified service name e.g. 'Database' - * - * @param message - * @param service - * @param fullCode - * @return - */ - public static String getMessageWithService(String message, String service, String fullCode) { - // Service: Error message (service/code). - return service + ": " + message + " (" + fullCode.toLowerCase() + ")."; - } - - /** - * Generate a service error code string e.g. 'DATABASE/PERMISSION-DENIED' - * - * @param service - * @param code - * @return - */ - public static String getCodeWithService(String service, String code) { - return service.toLowerCase() + "/" + code.toLowerCase(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java b/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java deleted file mode 100644 index 24f472e8..00000000 --- a/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java +++ /dev/null @@ -1,182 +0,0 @@ -package io.invertase.firebase; - -import android.app.Activity; -import android.content.IntentSender; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Callback; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseOptions; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -// react -// play services - -@SuppressWarnings("WeakerAccess") -public class RNFirebaseModule extends ReactContextBaseJavaModule { - private static final String TAG = "RNFirebase"; - - public RNFirebaseModule(ReactApplicationContext reactContext) { - super(reactContext); - } - - @Override - public String getName() { - return TAG; - } - - - @ReactMethod - public void initializeApp(String appName, ReadableMap options, Callback callback) { - FirebaseOptions.Builder builder = new FirebaseOptions.Builder(); - - builder.setApiKey(options.getString("apiKey")); - builder.setApplicationId(options.getString("appId")); - builder.setProjectId(options.getString("projectId")); - builder.setDatabaseUrl(options.getString("databaseURL")); - builder.setStorageBucket(options.getString("storageBucket")); - builder.setGcmSenderId(options.getString("messagingSenderId")); - // todo firebase sdk has no client id setter - - FirebaseApp.initializeApp(getReactApplicationContext(), builder.build(), appName); - - WritableMap response = Arguments.createMap(); - response.putString("result", "success"); - callback.invoke(null, response); - } - - @ReactMethod - public void deleteApp(String appName, Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - - if (firebaseApp != null) { - firebaseApp.delete(); - } - - promise.resolve(null); - } - - @ReactMethod - public void getPlayServicesStatus(Promise promise) { - promise.resolve(getPlayServicesStatusMap()); - } - - /** - * @return - */ - private WritableMap getPlayServicesStatusMap() { - GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); - final int status = gapi.isGooglePlayServicesAvailable(getReactApplicationContext()); - WritableMap result = Arguments.createMap(); - result.putInt("status", status); - if (status == ConnectionResult.SUCCESS) { - result.putBoolean("isAvailable", true); - } else { - result.putBoolean("isAvailable", false); - result.putString("error", gapi.getErrorString(status)); - result.putBoolean("isUserResolvableError", gapi.isUserResolvableError(status)); - result.putBoolean("hasResolution", new ConnectionResult(status).hasResolution()); - } - return result; - } - - /** - * Prompt the device user to update play services - */ - @ReactMethod - public void promptForPlayServices() { - GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); - int status = gapi.isGooglePlayServicesAvailable(getReactApplicationContext()); - - if (status != ConnectionResult.SUCCESS && gapi.isUserResolvableError(status)) { - Activity activity = getCurrentActivity(); - if (activity != null) { - gapi - .getErrorDialog(activity, status, status) - .show(); - } - } - } - - /** - * Prompt the device user to update play services - */ - @ReactMethod - public void resolutionForPlayServices() { - int status = GoogleApiAvailability - .getInstance() - .isGooglePlayServicesAvailable(getReactApplicationContext()); - ConnectionResult connectionResult = new ConnectionResult(status); - - if (!connectionResult.isSuccess() && connectionResult.hasResolution()) { - Activity activity = getCurrentActivity(); - if (activity != null) { - try { - connectionResult.startResolutionForResult(activity, status); - } catch (IntentSender.SendIntentException error) { - Log.d(TAG, "resolutionForPlayServices", error); - } - } - } - } - - - /** - * Prompt the device user to update play services - */ - @ReactMethod - public void makePlayServicesAvailable() { - GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); - int status = gapi.isGooglePlayServicesAvailable(getReactApplicationContext()); - - if (status != ConnectionResult.SUCCESS) { - Activity activity = getCurrentActivity(); - if (activity != null) { - gapi.makeGooglePlayServicesAvailable(activity); - } - } - } - - - @Override - public Map getConstants() { - Map constants = new HashMap<>(); - List> appMapsList = new ArrayList<>(); - List firebaseAppList = FirebaseApp.getApps(getReactApplicationContext()); - - // TODO no way to get client id currently from app options - firebase sdk issue - for (FirebaseApp app : firebaseAppList) { - String appName = app.getName(); - FirebaseOptions appOptions = app.getOptions(); - Map appProps = new HashMap<>(); - - appProps.put("name", appName); - appProps.put("apiKey", appOptions.getApiKey()); - appProps.put("appId", appOptions.getApplicationId()); - appProps.put("projectId", appOptions.getProjectId()); - appProps.put("projectId", appOptions.getProjectId()); - appProps.put("databaseURL", appOptions.getDatabaseUrl()); - appProps.put("messagingSenderId", appOptions.getGcmSenderId()); - appProps.put("storageBucket", appOptions.getStorageBucket()); - - appMapsList.add(appProps); - } - - constants.put("apps", appMapsList); - constants.put("playServicesAvailability", getPlayServicesStatusMap()); - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java b/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java deleted file mode 100644 index 04d656f0..00000000 --- a/android/src/main/java/io/invertase/firebase/RNFirebasePackage.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.invertase.firebase; - -import android.content.Context; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebasePackage implements ReactPackage { - private Context mContext; - - public RNFirebasePackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseModule(reactContext)); - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/Utils.java b/android/src/main/java/io/invertase/firebase/Utils.java deleted file mode 100644 index 03eb1b0c..00000000 --- a/android/src/main/java/io/invertase/firebase/Utils.java +++ /dev/null @@ -1,193 +0,0 @@ -package io.invertase.firebase; - -import android.app.ActivityManager; -import android.content.Context; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.common.LifecycleState; -import com.facebook.react.modules.core.DeviceEventManagerModule; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -import javax.annotation.Nullable; - - -@SuppressWarnings("WeakerAccess") -public class Utils { - private static final String TAG = "Utils"; - - public static String timestampToUTC(long timestamp) { - Calendar calendar = Calendar.getInstance(); - Date date = new Date((timestamp + calendar.getTimeZone().getOffset(timestamp)) * 1000); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); - format.setTimeZone(TimeZone.getTimeZone("UTC")); - return format.format(date); - } - - /** - * send a JS event - **/ - public static void sendEvent(final ReactContext context, final String eventName, Object body) { - if (context != null) { - context - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(eventName, body); - } else { - Log.d(TAG, "Missing context - cannot send event!"); - } - } - - /** - * Takes a value and calls the appropriate setter for its type on the target map + key - * - * @param key String key to set on target map - * @param value Object value to set on target map - * @param map WritableMap target map to write the value to - */ - @SuppressWarnings("unchecked") - public static void mapPutValue(String key, @Nullable Object value, WritableMap map) { - if (value == null) { - map.putNull(key); - } else { - String type = value - .getClass() - .getName(); - switch (type) { - case "java.lang.Boolean": - map.putBoolean(key, (Boolean) value); - break; - case "java.lang.Long": - Long longVal = (Long) value; - map.putDouble(key, (double) longVal); - break; - case "java.lang.Float": - float floatVal = (float) value; - map.putDouble(key, (double) floatVal); - break; - case "java.lang.Double": - map.putDouble(key, (Double) value); - break; - case "java.lang.Integer": - map.putInt(key, (int) value); - break; - case "java.lang.String": - map.putString(key, (String) value); - break; - case "org.json.JSONObject$1": - map.putString(key, value.toString()); - break; - default: - if (List.class.isAssignableFrom(value.getClass())) { - map.putArray(key, Arguments.makeNativeArray((List) value)); - } else if (Map.class.isAssignableFrom(value.getClass())) { - WritableMap childMap = Arguments.createMap(); - Map valueMap = (Map) value; - - for (Map.Entry entry : valueMap.entrySet()) { - mapPutValue(entry.getKey(), entry.getValue(), childMap); - } - - map.putMap(key, childMap); - } else { - Log.d(TAG, "utils:mapPutValue:unknownType:" + type); - map.putNull(key); - } - } - } - } - - /** - * Convert a ReadableMap to a WritableMap for the purposes of re-sending back to JS - * TODO This is now a legacy util - internally uses RN functionality - * - * @param map ReadableMap - * @return WritableMap - */ - public static WritableMap readableMapToWritableMap(ReadableMap map) { - WritableMap writableMap = Arguments.createMap(); - // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/WritableNativeMap.java#L54 - writableMap.merge(map); - return writableMap; - } - - /** - * Convert a ReadableMap into a native Java Map - * TODO This is now a legacy util - internally uses RN functionality - * - * @param readableMap ReadableMap - * @return Map - */ - public static Map recursivelyDeconstructReadableMap(ReadableMap readableMap) { - // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java#L216 - return readableMap.toHashMap(); - } - - /** - * Convert a ReadableArray into a native Java Map - * TODO This is now a legacy util - internally uses RN functionality - * - * @param readableArray ReadableArray - * @return List - */ - public static List recursivelyDeconstructReadableArray(ReadableArray readableArray) { - // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java#L175 - return readableArray.toArrayList(); - } - - /** - * We need to check if app is in foreground otherwise the app will crash. - * http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not - * - * @param context Context - * @return boolean - */ - public static boolean isAppInForeground(Context context) { - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - if (activityManager == null) return false; - - List appProcesses = activityManager.getRunningAppProcesses(); - if (appProcesses == null) return false; - - final String packageName = context.getPackageName(); - for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { - if ( - appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND - && appProcess.processName.equals(packageName) - ) { - ReactContext reactContext; - - try { - reactContext = (ReactContext) context; - } catch (ClassCastException exception) { - // Not react context so default to true - return true; - } - - return reactContext.getLifecycleState() == LifecycleState.RESUMED; - } - } - - return false; - } - - public static int getResId(Context ctx, String resName) { - int resourceId = ctx - .getResources() - .getIdentifier(resName, "string", ctx.getPackageName()); - if (resourceId == 0) { - Log.e(TAG, "resource " + resName + " could not be found"); - } - return resourceId; - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMob.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMob.java deleted file mode 100644 index 87de1d20..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMob.java +++ /dev/null @@ -1,112 +0,0 @@ -package io.invertase.firebase.admob; - - -import android.app.Activity; -import android.util.Log; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.MobileAds; - -import java.util.HashMap; -import java.util.Map; - - -public class RNFirebaseAdMob extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseAdMob"; - private HashMap interstitials = new HashMap<>(); - private HashMap rewardedVideos = new HashMap<>(); - - RNFirebaseAdMob(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - ReactApplicationContext getContext() { - return getReactApplicationContext(); - } - - Activity getActivity() { - return getCurrentActivity(); - } - - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void initialize(String appId) { - MobileAds.initialize(this.getContext(), appId); - } - - @ReactMethod - public void openDebugMenu(String appId) { - MobileAds.openDebugMenu(getActivity(), appId); - } - - @ReactMethod - public void interstitialLoadAd(String adUnit, ReadableMap request) { - RNFirebaseAdmobInterstitial interstitial = getOrCreateInterstitial(adUnit); - interstitial.loadAd(RNFirebaseAdMobUtils - .buildRequest(request) - .build()); - } - - @ReactMethod - public void interstitialShowAd(String adUnit) { - RNFirebaseAdmobInterstitial interstitial = getOrCreateInterstitial(adUnit); - interstitial.show(); - } - - @ReactMethod - public void rewardedVideoLoadAd(String adUnit, ReadableMap request) { - RNFirebaseAdMobRewardedVideo rewardedVideo = getOrCreateRewardedVideo(adUnit); - rewardedVideo.loadAd(RNFirebaseAdMobUtils - .buildRequest(request) - .build()); - } - - @ReactMethod - public void rewardedVideoShowAd(String adUnit) { - RNFirebaseAdMobRewardedVideo rewardedVideo = getOrCreateRewardedVideo(adUnit); - rewardedVideo.show(); - } - - /** - * @param adUnit - * @return - */ - private RNFirebaseAdmobInterstitial getOrCreateInterstitial(String adUnit) { - if (interstitials.containsKey(adUnit)) { - return interstitials.get(adUnit); - } - RNFirebaseAdmobInterstitial interstitial = new RNFirebaseAdmobInterstitial(adUnit, this); - interstitials.put(adUnit, interstitial); - return interstitial; - } - - /** - * @param adUnit - * @return - */ - private RNFirebaseAdMobRewardedVideo getOrCreateRewardedVideo(String adUnit) { - if (rewardedVideos.containsKey(adUnit)) { - return rewardedVideos.get(adUnit); - } - RNFirebaseAdMobRewardedVideo rewardedVideo = new RNFirebaseAdMobRewardedVideo(adUnit, this); - rewardedVideos.put(adUnit, rewardedVideo); - return rewardedVideo; - } - - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - constants.put("DEVICE_ID_EMULATOR", AdRequest.DEVICE_ID_EMULATOR); - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobBanner.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobBanner.java deleted file mode 100644 index 24da8838..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobBanner.java +++ /dev/null @@ -1,257 +0,0 @@ -package io.invertase.firebase.admob; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.uimanager.PixelUtil; -import com.facebook.react.uimanager.SimpleViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.uimanager.events.RCTEventEmitter; -import com.facebook.react.views.view.ReactViewGroup; -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.AdView; - -import java.util.Map; - -import javax.annotation.Nullable; - -public class RNFirebaseAdMobBanner extends SimpleViewManager { - private static final String REACT_CLASS = "RNFirebaseAdMobBanner"; - private static final String BANNER_EVENT = "onBannerEvent"; - private ThemedReactContext context; - private ReactViewGroup viewGroup; - private RCTEventEmitter emitter; - private Boolean requested = false; - // Internal prop values - private AdRequest.Builder request; - private AdSize size; - private String unitId; - - @Override - public String getName() { - return REACT_CLASS; - } - - /** - * Create & return view instance - * - * @param themedReactContext - * @return - */ - @Override - public ReactViewGroup createViewInstance(ThemedReactContext themedReactContext) { - context = themedReactContext; - viewGroup = new ReactViewGroup(themedReactContext); - emitter = themedReactContext.getJSModule(RCTEventEmitter.class); - - AdView adView = new AdView(context); - viewGroup.addView(adView); - setAdListener(); - - return viewGroup; - } - - private AdView getAdView() { - return (AdView) viewGroup.getChildAt(0); - } - - /** - * Remove the inner AdView and set a new one - */ - private void resetAdView() { - AdView oldAdView = getAdView(); - AdView newAdView = new AdView(context); - - viewGroup.removeViewAt(0); - if (oldAdView != null) oldAdView.destroy(); - viewGroup.addView(newAdView); - setAdListener(); - } - - /** - * Declare custom events - * - * @return - */ - @Override - public Map getExportedCustomDirectEventTypeConstants() { - MapBuilder.Builder builder = MapBuilder.builder(); - builder.put(BANNER_EVENT, MapBuilder.of("registrationName", BANNER_EVENT)); - return builder.build(); - } - - /** - * Handle unitId prop - * - * @param view - * @param value - */ - @ReactProp(name = "unitId") - public void setUnitId(ReactViewGroup view, String value) { - unitId = value; - requestAd(); - } - - /** - * Handle request prop - * - * @param view - * @param value - */ - @ReactProp(name = "request") - public void setRequest(ReactViewGroup view, ReadableMap value) { - request = RNFirebaseAdMobUtils.buildRequest(value); - requestAd(); - } - - /** - * Handle size prop - * - * @param view - * @param value - */ - @ReactProp(name = "size") - public void setSize(ReactViewGroup view, String value) { - size = RNFirebaseAdMobUtils.stringToAdSize(value); - - // Send the width & height back to the JS - int width; - int height; - WritableMap payload = Arguments.createMap(); - - if (size == AdSize.SMART_BANNER) { - width = (int) PixelUtil.toDIPFromPixel(size.getWidthInPixels(context)); - height = (int) PixelUtil.toDIPFromPixel(size.getHeightInPixels(context)); - } else { - width = size.getWidth(); - height = size.getHeight(); - } - - payload.putDouble("width", width); - payload.putDouble("height", height); - - sendEvent(Events.EVENT_AD_SIZE_CHANGE.toString(), payload); - requestAd(); - } - - /** - * Loads a new ad into a viewGroup - */ - private void requestAd() { - // If the props have not yet been set - if (size == null || unitId == null || request == null) { - return; - } - - // If the banner has already been requested, reset it - if (requested) { - resetAdView(); - } - - AdView adView = getAdView(); - adView.setAdUnitId(unitId); - adView.setAdSize(size); - AdRequest adRequest = request.build(); - - requested = true; - adView.loadAd(adRequest); - } - - /** - * Listen to Ad events - */ - private void setAdListener() { - final AdView adView = getAdView(); - - adView.setAdListener(new AdListener() { - @Override - public void onAdLoaded() { - int left = adView.getLeft(); - int top = adView.getTop(); - - int width = adView - .getAdSize() - .getWidthInPixels(context); - int height = adView - .getAdSize() - .getHeightInPixels(context); - - adView.measure(width, height); - adView.layout(left, top, left + width, top + height); - - WritableMap payload = Arguments.createMap(); - - payload.putBoolean( - RNFirebaseAdMobNativeExpress.Events.EVENT_AD_VIDEO_CONTENT.toString(), - false - ); - payload.putInt("width", width); - payload.putInt("height", height); - - sendEvent(Events.EVENT_AD_LOADED.toString(), payload); - } - - @Override - public void onAdFailedToLoad(int errorCode) { - WritableMap payload = RNFirebaseAdMobUtils.errorCodeToMap(errorCode); - sendEvent(Events.EVENT_AD_FAILED_TO_LOAD.toString(), payload); - } - - @Override - public void onAdOpened() { - sendEvent(Events.EVENT_AD_OPENED.toString(), null); - } - - @Override - public void onAdClosed() { - sendEvent(Events.EVENT_AD_CLOSED.toString(), null); - } - - @Override - public void onAdLeftApplication() { - sendEvent(Events.EVENT_AD_LEFT_APPLICATION.toString(), null); - } - }); - } - - /** - * Sends an event back to the JS component to handle - * - * @param type - * @param payload - */ - private void sendEvent(String type, final @Nullable WritableMap payload) { - WritableMap event = Arguments.createMap(); - event.putString("type", type); - - if (payload != null) { - event.putMap("payload", payload); - } - - emitter.receiveEvent(viewGroup.getId(), BANNER_EVENT, event); - } - - public enum Events { - EVENT_AD_SIZE_CHANGE("onSizeChange"), - EVENT_AD_LOADED("onAdLoaded"), - EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"), - EVENT_AD_OPENED("onAdOpened"), - EVENT_AD_CLOSED("onAdClosed"), - EVENT_AD_LEFT_APPLICATION("onAdLeftApplication"); - - private final String event; - - Events(final String name) { - event = name; - } - - @Override - public String toString() { - return event; - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobNativeExpress.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobNativeExpress.java deleted file mode 100644 index 6d403260..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobNativeExpress.java +++ /dev/null @@ -1,302 +0,0 @@ -package io.invertase.firebase.admob; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.uimanager.PixelUtil; -import com.facebook.react.uimanager.SimpleViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.uimanager.events.RCTEventEmitter; -import com.facebook.react.views.view.ReactViewGroup; -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.NativeExpressAdView; -import com.google.android.gms.ads.VideoController; -import com.google.android.gms.ads.VideoOptions; - -import java.util.Map; - -import javax.annotation.Nullable; - -public class RNFirebaseAdMobNativeExpress extends SimpleViewManager { - - private static final String REACT_CLASS = "RNFirebaseAdMobNativeExpress"; - private static final String BANNER_EVENT = "onBannerEvent"; - private ThemedReactContext context; - private ReactViewGroup viewGroup; - private RCTEventEmitter emitter; - private Boolean requested = false; - // Internal prop values - private AdRequest.Builder request; - private VideoOptions.Builder videoOptions; - private AdSize size; - private String unitId; - - @Override - public String getName() { - return REACT_CLASS; - } - - /** - * Create & return view instance - * - * @param themedReactContext - * @return - */ - @Override - public ReactViewGroup createViewInstance(ThemedReactContext themedReactContext) { - context = themedReactContext; - viewGroup = new ReactViewGroup(themedReactContext); - emitter = themedReactContext.getJSModule(RCTEventEmitter.class); - - NativeExpressAdView adView = new NativeExpressAdView(context); - viewGroup.addView(adView); - setAdListener(); - - return viewGroup; - } - - private NativeExpressAdView getAdView() { - return (NativeExpressAdView) viewGroup.getChildAt(0); - } - - /** - * Remove the inner AdView and set a new one - */ - private void resetAdView() { - NativeExpressAdView oldAdView = getAdView(); - NativeExpressAdView newAdView = new NativeExpressAdView(context); - - viewGroup.removeViewAt(0); - if (oldAdView != null) oldAdView.destroy(); - viewGroup.addView(newAdView); - setAdListener(); - } - - /** - * Declare custom events - * - * @return - */ - @Override - public Map getExportedCustomDirectEventTypeConstants() { - MapBuilder.Builder builder = MapBuilder.builder(); - builder.put(BANNER_EVENT, MapBuilder.of("registrationName", BANNER_EVENT)); - return builder.build(); - } - - /** - * Handle unitId prop - * - * @param view - * @param value - */ - @ReactProp(name = "unitId") - public void setUnitId(ReactViewGroup view, String value) { - unitId = value; - requestAd(); - } - - /** - * Handle request prop - * - * @param view - * @param map - */ - @ReactProp(name = "request") - public void setRequest(ReactViewGroup view, ReadableMap map) { - request = RNFirebaseAdMobUtils.buildRequest(map); - requestAd(); - } - - /** - * Handle video prop - * - * @param view - * @param map - */ - @ReactProp(name = "video") - public void setVideoOptions(ReactViewGroup view, ReadableMap map) { - videoOptions = RNFirebaseAdMobUtils.buildVideoOptions(map); - requestAd(); - } - - /** - * Handle size prop - * - * @param view - * @param value - */ - @ReactProp(name = "size") - public void setSize(ReactViewGroup view, String value) { - size = RNFirebaseAdMobUtils.stringToAdSize(value); - - // Send the width & height back to the JS - int width; - int height; - WritableMap payload = Arguments.createMap(); - - if (size == AdSize.SMART_BANNER) { - width = (int) PixelUtil.toDIPFromPixel(size.getWidthInPixels(context)); - height = (int) PixelUtil.toDIPFromPixel(size.getHeightInPixels(context)); - } else { - width = size.getWidth(); - height = size.getHeight(); - } - - payload.putDouble("width", width); - payload.putDouble("height", height); - - sendEvent(Events.EVENT_AD_SIZE_CHANGE.toString(), payload); - requestAd(); - } - - /** - * Loads a new ad into a viewGroup - */ - private void requestAd() { - if (size == null || unitId == null || request == null || videoOptions == null) { - return; - } - - if (requested) { - resetAdView(); - } - - NativeExpressAdView adView = getAdView(); - adView.setAdUnitId(unitId); - adView.setAdSize(size); - adView.setVideoOptions(videoOptions.build()); - AdRequest adRequest = request.build(); - - requested = true; - adView.loadAd(adRequest); - } - - /** - * Listen to Ad events - */ - private void setAdListener() { - final NativeExpressAdView adView = getAdView(); - - adView.setAdListener(new AdListener() { - @Override - public void onAdLoaded() { - int left = adView.getLeft(); - int top = adView.getTop(); - - int width = adView - .getAdSize() - .getWidthInPixels(context); - int height = adView - .getAdSize() - .getHeightInPixels(context); - - adView.measure(width, height); - adView.layout(left, top, left + width, top + height); - - VideoController vc = adView.getVideoController(); - final WritableMap payload = Arguments.createMap(); - - payload.putBoolean(Events.EVENT_AD_VIDEO_CONTENT.toString(), vc.hasVideoContent()); - payload.putInt("width", width); - payload.putInt("height", height); - - sendEvent(Events.EVENT_AD_LOADED.toString(), payload); - - if (vc.hasVideoContent()) { - vc.setVideoLifecycleCallbacks(new VideoController.VideoLifecycleCallbacks() { - public void onVideoEnd() { - sendEvent(Events.EVENT_AD_VIDEO_END.toString(), null); - } - - public void onVideoMute(boolean isMuted) { - WritableMap videoMutePayload = Arguments.createMap(); - videoMutePayload.putBoolean("isMuted", isMuted); - sendEvent(Events.EVENT_AD_VIDEO_MUTE.toString(), videoMutePayload); - } - - public void onVideoPause() { - sendEvent(Events.EVENT_AD_VIDEO_PAUSE.toString(), null); - } - - public void onVideoPlay() { - sendEvent(Events.EVENT_AD_VIDEO_PLAY.toString(), null); - } - - public void onVideoStart() { - sendEvent(Events.EVENT_AD_VIDEO_START.toString(), null); - } - }); - } - } - - @Override - public void onAdFailedToLoad(int errorCode) { - WritableMap payload = RNFirebaseAdMobUtils.errorCodeToMap(errorCode); - sendEvent(Events.EVENT_AD_FAILED_TO_LOAD.toString(), payload); - } - - @Override - public void onAdOpened() { - sendEvent(Events.EVENT_AD_OPENED.toString(), null); - } - - @Override - public void onAdClosed() { - sendEvent(Events.EVENT_AD_CLOSED.toString(), null); - } - - @Override - public void onAdLeftApplication() { - sendEvent(Events.EVENT_AD_LEFT_APPLICATION.toString(), null); - } - }); - } - - /** - * Sends an event back to the JS component to handle - * - * @param type - * @param payload - */ - private void sendEvent(String type, final @Nullable WritableMap payload) { - WritableMap event = Arguments.createMap(); - event.putString("type", type); - - if (payload != null) { - event.putMap("payload", payload); - } - - emitter.receiveEvent(viewGroup.getId(), BANNER_EVENT, event); - } - - public enum Events { - EVENT_AD_SIZE_CHANGE("onSizeChange"), - EVENT_AD_LOADED("onAdLoaded"), - EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"), - EVENT_AD_OPENED("onAdOpened"), - EVENT_AD_CLOSED("onAdClosed"), - EVENT_AD_LEFT_APPLICATION("onAdLeftApplication"), - EVENT_AD_VIDEO_END("onVideoEnd"), - EVENT_AD_VIDEO_MUTE("onVideoMute"), - EVENT_AD_VIDEO_PAUSE("onVideoPause"), - EVENT_AD_VIDEO_PLAY("onVideoPlay"), - EVENT_AD_VIDEO_START("onVideoStart"), - EVENT_AD_VIDEO_CONTENT("hasVideoContent"); - - private final String event; - - Events(final String name) { - event = name; - } - - @Override - public String toString() { - return event; - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobPackage.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobPackage.java deleted file mode 100644 index 841591d7..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobPackage.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.invertase.firebase.admob; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseAdMobPackage implements ReactPackage { - public RNFirebaseAdMobPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseAdMob(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Arrays.asList( - new RNFirebaseAdMobBanner(), - new RNFirebaseAdMobNativeExpress() - ); - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobRewardedVideo.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobRewardedVideo.java deleted file mode 100644 index 2649d2f0..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobRewardedVideo.java +++ /dev/null @@ -1,140 +0,0 @@ -package io.invertase.firebase.admob; - - -import android.app.Activity; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.MobileAds; -import com.google.android.gms.ads.reward.RewardItem; -import com.google.android.gms.ads.reward.RewardedVideoAd; -import com.google.android.gms.ads.reward.RewardedVideoAdListener; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -public class RNFirebaseAdMobRewardedVideo implements RewardedVideoAdListener { - - private String adUnit; - private RNFirebaseAdMob adMob; - private RewardedVideoAd rewardedVideo; - - RNFirebaseAdMobRewardedVideo(final String adUnitString, final RNFirebaseAdMob adMobInstance) { - adUnit = adUnitString; - adMob = adMobInstance; - - rewardedVideo = MobileAds.getRewardedVideoAdInstance(adMob.getContext()); - - Activity activity = adMob.getActivity(); - final RNFirebaseAdMobRewardedVideo _this = this; - - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - rewardedVideo.setRewardedVideoAdListener(_this); - } - }); - } - } - - /** - * Load an Ad with a AdRequest instance - * - * @param adRequest - */ - void loadAd(final AdRequest adRequest) { - Activity activity = adMob.getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - rewardedVideo.loadAd(adUnit, adRequest); - } - }); - } - } - - /** - * Show the loaded interstitial, if it's loaded - */ - void show() { - Activity activity = adMob.getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (rewardedVideo.isLoaded()) { - rewardedVideo.show(); - } - } - }); - } - } - - @Override - public void onRewarded(RewardItem reward) { - WritableMap payload = Arguments.createMap(); - payload.putInt("amount", reward.getAmount()); - payload.putString("type", reward.getType()); - sendEvent("onRewarded", payload); - } - - @Override - public void onRewardedVideoAdLeftApplication() { - sendEvent("onAdLeftApplication", null); - } - - @Override - public void onRewardedVideoAdClosed() { - sendEvent("onAdClosed", null); - } - - @Override - public void onRewardedVideoCompleted() { - sendEvent("onAdCompleted", null); - } - - @Override - public void onRewardedVideoAdFailedToLoad(int errorCode) { - WritableMap payload = RNFirebaseAdMobUtils.errorCodeToMap(errorCode); - sendEvent("onAdFailedToLoad", payload); - } - - @Override - public void onRewardedVideoAdLoaded() { - sendEvent("onAdLoaded", null); - } - - @Override - public void onRewardedVideoAdOpened() { - sendEvent("onAdOpened", null); - } - - @Override - public void onRewardedVideoStarted() { - sendEvent("onRewardedVideoStarted", null); - } - - // TODO onResume etc??? https://developers.google.com/admob/android/rewarded-video - - /** - * Send a native event over the bridge with a type and optional payload - * - * @param type - * @param payload - */ - private void sendEvent(String type, final @Nullable WritableMap payload) { - WritableMap map = Arguments.createMap(); - map.putString("type", type); - map.putString("adUnit", adUnit); - - if (payload != null) { - map.putMap("payload", payload); - } - - Utils.sendEvent(adMob.getContext(), "rewarded_video_event", map); - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobUtils.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobUtils.java deleted file mode 100644 index d2871ec0..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdMobUtils.java +++ /dev/null @@ -1,160 +0,0 @@ -package io.invertase.firebase.admob; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.VideoOptions; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import io.invertase.firebase.Utils; - -class RNFirebaseAdMobUtils { - - /** - * Convert common AdMob errors into a standard format - * - * @param errorCode - * @return - */ - static WritableMap errorCodeToMap(int errorCode) { - WritableMap map = Arguments.createMap(); - - switch (errorCode) { - case AdRequest.ERROR_CODE_INTERNAL_ERROR: - map.putString("code", "admob/error-code-internal-error"); - map.putString( - "message", - "Something happened internally; for instance, an invalid response was received from the ad server." - ); - break; - case AdRequest.ERROR_CODE_INVALID_REQUEST: - map.putString("code", "admob/error-code-invalid-request"); - map.putString( - "message", - "The ad request was invalid; for instance, the ad unit ID was incorrect." - ); - break; - case AdRequest.ERROR_CODE_NETWORK_ERROR: - map.putString("code", "admob/error-code-network-error"); - map.putString("message", "The ad request was unsuccessful due to network connectivity."); - break; - case AdRequest.ERROR_CODE_NO_FILL: - map.putString("code", "admob/error-code-no-fill"); - map.putString( - "message", - "The ad request was successful, but no ad was returned due to lack of ad inventory." - ); - break; - } - - return map; - } - - static AdRequest.Builder buildRequest(ReadableMap request) { - AdRequest.Builder requestBuilder = new AdRequest.Builder(); - - if (request.hasKey("isDesignedForFamilies")) { - requestBuilder.setIsDesignedForFamilies(request.getBoolean("isDesignedForFamilies")); - } - - if (request.hasKey("tagForChildDirectedTreatment")) { - requestBuilder.tagForChildDirectedTreatment(request.getBoolean("tagForChildDirectedTreatment")); - } - - if (request.hasKey("contentUrl")) { - requestBuilder.setContentUrl(request.getString("contentUrl")); - } - - if (request.hasKey("requestAgent")) { - requestBuilder.setRequestAgent(request.getString("requestAgent")); - } - - if (request.hasKey("gender")) { - String gender = request.getString("gender"); - switch (gender) { - case "male": - requestBuilder.setGender(AdRequest.GENDER_MALE); - break; - case "female": - requestBuilder.setGender(AdRequest.GENDER_FEMALE); - break; - case "unknown": - requestBuilder.setGender(AdRequest.GENDER_UNKNOWN); - break; - } - } - - // Handle testDevices array - ReadableArray testDevices = request.getArray("testDevices"); - List testDevicesList = Utils.recursivelyDeconstructReadableArray(testDevices); - - for (Object deviceId : testDevicesList) { - if (deviceId == "DEVICE_ID_EMULATOR") { - requestBuilder.addTestDevice(AdRequest.DEVICE_ID_EMULATOR); - } else { - requestBuilder.addTestDevice((String) deviceId); - } - } - - // Handle keywords array - ReadableArray keywords = request.getArray("keywords"); - List keywordsList = Utils.recursivelyDeconstructReadableArray(keywords); - - for (Object word : keywordsList) { - requestBuilder.addKeyword((String) word); - } - - return requestBuilder; - } - - static VideoOptions.Builder buildVideoOptions(ReadableMap options) { - VideoOptions.Builder optionsBuilder = new VideoOptions.Builder(); - - // Default true - optionsBuilder.setStartMuted(options.getBoolean("startMuted")); - - return optionsBuilder; - } - - /** - * Map the size prop to the AdSize - * - * @param value - * @return - */ - static AdSize stringToAdSize(String value) { - Pattern pattern = Pattern.compile("([0-9]+)x([0-9]+)"); - Matcher matcher = pattern.matcher(value); - - // If size is "valXval" - if (matcher.find()) { - int width = Integer.parseInt(matcher.group(1)); - int height = Integer.parseInt(matcher.group(2)); - return new AdSize(width, height); - } - - switch (value.toUpperCase()) { - default: - case "BANNER": - return AdSize.BANNER; - case "LARGE_BANNER": - return AdSize.LARGE_BANNER; - case "MEDIUM_RECTANGLE": - return AdSize.MEDIUM_RECTANGLE; - case "FULL_BANNER": - return AdSize.FULL_BANNER; - case "LEADERBOARD": - return AdSize.LEADERBOARD; - case "SMART_BANNER": - return AdSize.SMART_BANNER; - case "SMART_BANNER_LANDSCAPE": - return AdSize.SMART_BANNER; - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdmobInterstitial.java b/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdmobInterstitial.java deleted file mode 100644 index 0dba8b37..00000000 --- a/android/src/main/java/io/invertase/firebase/admob/RNFirebaseAdmobInterstitial.java +++ /dev/null @@ -1,110 +0,0 @@ -package io.invertase.firebase.admob; - - -import android.app.Activity; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.InterstitialAd; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -class RNFirebaseAdmobInterstitial { - - private InterstitialAd interstitialAd; - private RNFirebaseAdMob adMob; - private String adUnit; - - RNFirebaseAdmobInterstitial(final String adUnitString, final RNFirebaseAdMob adMobInstance) { - adUnit = adUnitString; - adMob = adMobInstance; - interstitialAd = new InterstitialAd(adMob.getContext()); - interstitialAd.setAdUnitId(adUnit); - - AdListener adListener = new AdListener() { - @Override - public void onAdLoaded() { - sendEvent("onAdLoaded", null); - } - - @Override - public void onAdOpened() { - sendEvent("onAdOpened", null); - } - - @Override - public void onAdLeftApplication() { - sendEvent("onAdLeftApplication", null); - } - - @Override - public void onAdClosed() { - sendEvent("onAdClosed", null); - } - - @Override - public void onAdFailedToLoad(int errorCode) { - WritableMap payload = RNFirebaseAdMobUtils.errorCodeToMap(errorCode); - sendEvent("onAdFailedToLoad", payload); - } - }; - - interstitialAd.setAdListener(adListener); - } - - /** - * Load an Ad with a AdRequest instance - * - * @param adRequest - */ - void loadAd(final AdRequest adRequest) { - Activity activity = adMob.getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - interstitialAd.loadAd(adRequest); - } - }); - } - } - - /** - * Show the loaded interstitial, if it's loaded - */ - void show() { - Activity activity = adMob.getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (interstitialAd.isLoaded()) { - interstitialAd.show(); - } - } - }); - } - } - - /** - * Send a native event over the bridge with a type and optional payload - * - * @param type - * @param payload - */ - private void sendEvent(String type, final @Nullable WritableMap payload) { - WritableMap map = Arguments.createMap(); - map.putString("type", type); - map.putString("adUnit", adUnit); - - if (payload != null) { - map.putMap("payload", payload); - } - - Utils.sendEvent(adMob.getContext(), "interstitial_event", map); - } -} diff --git a/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalytics.java b/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalytics.java deleted file mode 100644 index 40021409..00000000 --- a/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalytics.java +++ /dev/null @@ -1,111 +0,0 @@ -package io.invertase.firebase.analytics; - -import android.app.Activity; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.google.firebase.analytics.FirebaseAnalytics; - -import javax.annotation.Nullable; - - -public class RNFirebaseAnalytics extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseAnalytics"; - - RNFirebaseAnalytics(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - /** - * @return - */ - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void logEvent(final String name, @Nullable final ReadableMap params) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .logEvent(name, Arguments.toBundle(params)); - } - - /** - * @param enabled - */ - @ReactMethod - public void setAnalyticsCollectionEnabled(final Boolean enabled) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setAnalyticsCollectionEnabled(enabled); - } - - /** - * @param screenName - * @param screenClassOverride - */ - @ReactMethod - public void setCurrentScreen(final String screenName, final String screenClassOverride) { - final Activity activity = getCurrentActivity(); - if (activity != null) { - // needs to be run on main thread - Log.d(TAG, "setCurrentScreen " + screenName + " - " + screenClassOverride); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setCurrentScreen(activity, screenName, screenClassOverride); - } - }); - } - } - - /** - * @param milliseconds - */ - @ReactMethod - public void setMinimumSessionDuration(final double milliseconds) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setMinimumSessionDuration((long) milliseconds); - } - - /** - * @param milliseconds - */ - @ReactMethod - public void setSessionTimeoutDuration(final double milliseconds) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setSessionTimeoutDuration((long) milliseconds); - } - - /** - * @param id - */ - @ReactMethod - public void setUserId(final String id) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setUserId(id); - } - - /** - * @param name - * @param value - */ - @ReactMethod - public void setUserProperty(final String name, final String value) { - FirebaseAnalytics - .getInstance(getReactApplicationContext()) - .setUserProperty(name, value); - } -} diff --git a/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalyticsPackage.java b/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalyticsPackage.java deleted file mode 100644 index c1726167..00000000 --- a/android/src/main/java/io/invertase/firebase/analytics/RNFirebaseAnalyticsPackage.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.invertase.firebase.analytics; - -import android.support.annotation.RequiresPermission; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseAnalyticsPackage implements ReactPackage { - @RequiresPermission( - allOf = {"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE", "android.permission.WAKE_LOCK"} - ) - public RNFirebaseAnalyticsPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseAnalytics(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java deleted file mode 100644 index dd14ca42..00000000 --- a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java +++ /dev/null @@ -1,2072 +0,0 @@ -package io.invertase.firebase.auth; - -import android.app.Activity; -import android.net.Uri; -import android.os.Parcel; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseException; -import com.google.firebase.auth.ActionCodeResult; -import com.google.firebase.auth.ActionCodeSettings; -import com.google.firebase.auth.AuthCredential; -import com.google.firebase.auth.AuthResult; -import com.google.firebase.auth.EmailAuthProvider; -import com.google.firebase.auth.FacebookAuthProvider; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.auth.FirebaseAuthException; -import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException; -import com.google.firebase.auth.FirebaseAuthProvider; -import com.google.firebase.auth.FirebaseAuthSettings; -import com.google.firebase.auth.FirebaseUser; -import com.google.firebase.auth.FirebaseUserMetadata; -import com.google.firebase.auth.GetTokenResult; -import com.google.firebase.auth.GithubAuthProvider; -import com.google.firebase.auth.GoogleAuthProvider; -import com.google.firebase.auth.OAuthProvider; -import com.google.firebase.auth.PhoneAuthCredential; -import com.google.firebase.auth.PhoneAuthProvider; -import com.google.firebase.auth.SignInMethodQueryResult; -import com.google.firebase.auth.TwitterAuthProvider; -import com.google.firebase.auth.UserInfo; -import com.google.firebase.auth.UserProfileChangeRequest; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "JavaDoc"}) -class RNFirebaseAuth extends ReactContextBaseJavaModule { - private static final String TAG = "RNFirebaseAuth"; - private String mVerificationId; - private String mLastPhoneNumber; - private PhoneAuthProvider.ForceResendingToken mForceResendingToken; - private PhoneAuthCredential mCredential; - private ReactContext mReactContext; - private static HashMap mAuthListeners = new HashMap<>(); - private static HashMap mIdTokenListeners = new HashMap<>(); - - - RNFirebaseAuth(ReactApplicationContext reactContext) { - super(reactContext); - mReactContext = reactContext; - Log.d(TAG, "instance-created"); - } - - @Override - public String getName() { - return TAG; - } - - @Override - public void initialize() { - super.initialize(); - Log.d(TAG, "instance-initialized"); - } - - @Override - public void onCatalystInstanceDestroy() { - super.onCatalystInstanceDestroy(); - Log.d(TAG, "instance-destroyed"); - - Iterator authListenerIterator = mAuthListeners - .entrySet() - .iterator(); - - while (authListenerIterator.hasNext()) { - Map.Entry pair = (Map.Entry) authListenerIterator.next(); - String appName = (String) pair.getKey(); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseAuth.AuthStateListener mAuthListener = (FirebaseAuth.AuthStateListener) pair.getValue(); - firebaseAuth.removeAuthStateListener(mAuthListener); - authListenerIterator.remove(); - } - - Iterator idTokenListenerIterator = mIdTokenListeners - .entrySet() - .iterator(); - - while (idTokenListenerIterator.hasNext()) { - Map.Entry pair = (Map.Entry) idTokenListenerIterator.next(); - String appName = (String) pair.getKey(); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseAuth.IdTokenListener mAuthListener = (FirebaseAuth.IdTokenListener) pair.getValue(); - firebaseAuth.removeIdTokenListener(mAuthListener); - idTokenListenerIterator.remove(); - } - } - - /** - * Add a new auth state listener - if one doesn't exist already - */ - @ReactMethod - public void addAuthStateListener(final String appName) { - Log.d(TAG, "addAuthStateListener"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseAuth.AuthStateListener mAuthListener = mAuthListeners.get(appName); - if (mAuthListener == null) { - FirebaseAuth.AuthStateListener newAuthListener = new FirebaseAuth.AuthStateListener() { - @Override - public void onAuthStateChanged(@Nonnull FirebaseAuth firebaseAuth) { - FirebaseUser user = firebaseAuth.getCurrentUser(); - WritableMap msgMap = Arguments.createMap(); - if (user != null) { - msgMap.putString("appName", appName); // for js side distribution - msgMap.putMap("user", firebaseUserToMap(user)); - Utils.sendEvent(mReactContext, "auth_state_changed", msgMap); - } else { - msgMap.putString("appName", appName); // for js side distribution - Utils.sendEvent(mReactContext, "auth_state_changed", msgMap); - } - } - }; - - firebaseAuth.addAuthStateListener(newAuthListener); - mAuthListeners.put(appName, newAuthListener); - } - } - - /** - * Removes the current auth state listener - */ - @ReactMethod - public void removeAuthStateListener(String appName) { - Log.d(TAG, "removeAuthStateListener"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseAuth.AuthStateListener mAuthListener = mAuthListeners.get(appName); - - if (mAuthListener != null) { - firebaseAuth.removeAuthStateListener(mAuthListener); - mAuthListeners.remove(appName); - } - } - - /** - * Add a new id token listener - if one doesn't exist already - */ - @ReactMethod - public void addIdTokenListener(final String appName) { - Log.d(TAG, "addIdTokenListener"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - if (!mIdTokenListeners.containsKey(appName)) { - FirebaseAuth.IdTokenListener newIdTokenListener = new FirebaseAuth.IdTokenListener() { - @Override - public void onIdTokenChanged(@Nonnull FirebaseAuth firebaseAuth) { - FirebaseUser user = firebaseAuth.getCurrentUser(); - WritableMap msgMap = Arguments.createMap(); - if (user != null) { - msgMap.putBoolean("authenticated", true); - msgMap.putString("appName", appName); // for js side distribution - msgMap.putMap("user", firebaseUserToMap(user)); - Utils.sendEvent(mReactContext, "auth_id_token_changed", msgMap); - } else { - msgMap.putString("appName", appName); // for js side distribution - msgMap.putBoolean("authenticated", false); - Utils.sendEvent(mReactContext, "auth_id_token_changed", msgMap); - } - } - }; - - firebaseAuth.addIdTokenListener(newIdTokenListener); - mIdTokenListeners.put(appName, newIdTokenListener); - } - } - - /** - * Removes the current id token listener - */ - @ReactMethod - public void removeIdTokenListener(String appName) { - Log.d(TAG, "removeIdTokenListener"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseAuth.IdTokenListener mIdTokenListener = mIdTokenListeners.get(appName); - - if (mIdTokenListener != null) { - firebaseAuth.removeIdTokenListener(mIdTokenListener); - mIdTokenListeners.remove(appName); - } - } - - /** - * The phone number and SMS code here must have been configured in the - * Firebase Console (Authentication > Sign In Method > Phone). - *

- * Calling this method a second time will overwrite the previously passed parameters. - * Only one number can be configured at a given time. - * - * @param appName - * @param phoneNumber - * @param smsCode - * @param promise - */ - @ReactMethod - public void setAutoRetrievedSmsCodeForPhoneNumber( - String appName, - String phoneNumber, - String smsCode, - Promise promise - ) { - Log.d(TAG, "setAutoRetrievedSmsCodeForPhoneNumber"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings(); - firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode); - promise.resolve(null); - } - - @ReactMethod - public void signOut(String appName, Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - Log.d(TAG, "signOut"); - if (firebaseAuth == null || firebaseAuth.getCurrentUser() == null) { - promiseNoUser(promise, true); - } else { - firebaseAuth.signOut(); - promiseNoUser(promise, false); - } - } - - @ReactMethod - private void signInAnonymously(String appName, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - Log.d(TAG, "signInAnonymously"); - firebaseAuth - .signInAnonymously() - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(AuthResult authResult) { - Log.d(TAG, "signInAnonymously:onComplete:success"); - promiseWithAuthResult(authResult, promise); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "signInAnonymously:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - }); - } - - /** - * createUserWithEmailAndPassword - * - * @param email - * @param password - * @param promise - */ - @ReactMethod - private void createUserWithEmailAndPassword( - String appName, - final String email, - final String password, - final Promise promise - ) { - Log.d(TAG, "createUserWithEmailAndPassword"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .createUserWithEmailAndPassword(email, password) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(AuthResult authResult) { - Log.d(TAG, "createUserWithEmailAndPassword:onComplete:success"); - promiseWithAuthResult(authResult, promise); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "createUserWithEmailAndPassword:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - }); - } - - /** - * signInWithEmailAndPassword - * - * @param email - * @param password - * @param promise - */ - @ReactMethod - private void signInWithEmailAndPassword( - String appName, - final String email, - final String password, - final Promise promise - ) { - Log.d(TAG, "signInWithEmailAndPassword"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .signInWithEmailAndPassword(email, password) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(AuthResult authResult) { - Log.d(TAG, "signInWithEmailAndPassword:onComplete:success"); - promiseWithAuthResult(authResult, promise); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "signInWithEmailAndPassword:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - }); - } - - /** - * Signs in using an email and sign-in email link. - * - * @param appName - * @param email - * @param emailLink - * @param promise - */ - @ReactMethod - private void signInWithEmailLink( - String appName, - final String email, - final String emailLink, - final Promise promise - ) { - Log.d(TAG, "signInWithEmailLink"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .signInWithEmailLink(email, emailLink) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(AuthResult authResult) { - Log.d(TAG, "signInWithEmailLink:onComplete:success"); - promiseWithAuthResult(authResult, promise); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "signInWithEmailLink:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - }); - } - - @ReactMethod - private void signInWithCustomToken( - String appName, - final String token, - final Promise promise - ) { - Log.d(TAG, "signInWithCustomToken"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .signInWithCustomToken(token) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(AuthResult authResult) { - Log.d(TAG, "signInWithCustomToken:onComplete:success"); - promiseWithAuthResult(authResult, promise); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "signInWithCustomToken:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - }); - } - - /** - * sendPasswordResetEmail - * - * @param email - * @param promise - */ - @ReactMethod - public void sendPasswordResetEmail( - String appName, - final String email, - ReadableMap actionCodeSettings, - final Promise promise - ) { - Log.d(TAG, "sendPasswordResetEmail"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - OnCompleteListener listener = new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "sendPasswordResetEmail:onComplete:success"); - promiseNoUser(promise, false); - } else { - Exception exception = task.getException(); - Log.e(TAG, "sendPasswordResetEmail:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }; - - if (actionCodeSettings == null) { - firebaseAuth - .sendPasswordResetEmail(email) - .addOnCompleteListener(listener); - } else { - ActionCodeSettings settings = buildActionCodeSettings(actionCodeSettings); - firebaseAuth - .sendPasswordResetEmail(email, settings) - .addOnCompleteListener(listener); - } - } - - /** - * sendSignInLinkToEmail - * - * @param email - * @param promise - */ - @ReactMethod - public void sendSignInLinkToEmail( - String appName, - String email, - ReadableMap actionCodeSettings, - final Promise promise - ) { - Log.d(TAG, "sendSignInLinkToEmail"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - OnCompleteListener listener = new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "sendSignInLinkToEmail:onComplete:success"); - promiseNoUser(promise, false); - } else { - Exception exception = task.getException(); - Log.e(TAG, "sendSignInLinkToEmail:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }; - - - ActionCodeSettings settings = buildActionCodeSettings(actionCodeSettings); - firebaseAuth - .sendSignInLinkToEmail(email, settings) - .addOnCompleteListener(listener); - } - - - - /* ---------------------- - * .currentUser methods - * ---------------------- */ - - /** - * delete - * - * @param promise Promise - */ - @ReactMethod - public void delete(String appName, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "delete"); - if (user != null) { - user - .delete() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "delete:onComplete:success"); - promiseNoUser(promise, false); - } else { - Exception exception = task.getException(); - Log.e(TAG, "delete:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } else { - Log.e(TAG, "delete:failure:noCurrentUser"); - promiseNoUser(promise, true); - } - } - - /** - * reload - * - * @param promise - */ - @ReactMethod - public void reload(String appName, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "reload"); - - if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "reload:failure:noCurrentUser"); - } else { - user - .reload() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "reload:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "reload:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - /** - * sendEmailVerification - * - * @param promise - */ - @ReactMethod - public void sendEmailVerification( - String appName, - ReadableMap actionCodeSettings, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "sendEmailVerification"); - - if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "sendEmailVerification:failure:noCurrentUser"); - } else { - OnCompleteListener listener = new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "sendEmailVerification:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "sendEmailVerification:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }; - - if (actionCodeSettings == null) { - user - .sendEmailVerification() - .addOnCompleteListener(listener); - } else { - ActionCodeSettings settings = buildActionCodeSettings(actionCodeSettings); - user - .sendEmailVerification(settings) - .addOnCompleteListener(listener); - } - } - } - - /** - * updateEmail - * - * @param email - * @param promise - */ - @ReactMethod - public void updateEmail(String appName, final String email, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "updateEmail"); - - if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "updateEmail:failure:noCurrentUser"); - } else { - user - .updateEmail(email) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "updateEmail:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "updateEmail:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - /** - * updatePassword - * - * @param password - * @param promise - */ - @ReactMethod - public void updatePassword(String appName, final String password, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "updatePassword"); - - if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "updatePassword:failure:noCurrentUser"); - } else { - user - .updatePassword(password) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "updatePassword:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "updatePassword:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - /** - * updatePhoneNumber - * - * @param provider - * @param authToken - * @param authSecret - * @param promise - */ - @ReactMethod - private void updatePhoneNumber( - String appName, - String provider, - String authToken, - String authSecret, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseUser user = firebaseAuth.getCurrentUser(); - - if (!provider.equals("phone")) { - promise.reject( - "auth/invalid-credential", - "The supplied auth credential does not have a phone provider." - ); - } - - PhoneAuthCredential credential = getPhoneAuthCredential(authToken, authSecret); - - if (credential == null) { - promise.reject( - "auth/invalid-credential", - "The supplied auth credential is malformed, has expired or is not currently supported." - ); - } else if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "updatePhoneNumber:failure:noCurrentUser"); - } else { - Log.d(TAG, "updatePhoneNumber"); - user - .updatePhoneNumber(credential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "updatePhoneNumber:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "updatePhoneNumber:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - /** - * updateProfile - * - * @param props - * @param promise - */ - @ReactMethod - public void updateProfile(String appName, ReadableMap props, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "updateProfile"); - - if (user == null) { - promiseNoUser(promise, false); - Log.e(TAG, "updateProfile:failure:noCurrentUser"); - } else { - UserProfileChangeRequest.Builder profileBuilder = new UserProfileChangeRequest.Builder(); - - if (props.hasKey("displayName")) { - String displayName = props.getString("displayName"); - profileBuilder.setDisplayName(displayName); - } - - if (props.hasKey("photoURL")) { - String photoURLStr = props.getString("photoURL"); - profileBuilder.setPhotoUri(photoURLStr == null ? null : Uri.parse(photoURLStr)); - } - - UserProfileChangeRequest profileUpdates = profileBuilder.build(); - - user - .updateProfile(profileUpdates) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "updateProfile:onComplete:success"); - promiseWithUser(firebaseAuth.getCurrentUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "updateProfile:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - @ReactMethod - private void signInWithCredential( - String appName, - String provider, - String authToken, - String authSecret, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - AuthCredential credential = getCredentialForProvider(provider, authToken, authSecret); - - if (credential == null) { - promise.reject( - "auth/invalid-credential", - "The supplied auth credential is malformed, has expired or is not currently supported." - ); - } else { - Log.d(TAG, "signInWithCredential"); - firebaseAuth - .signInWithCredential(credential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "signInWithCredential:onComplete:success"); - promiseWithAuthResult(task.getResult(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "signInWithCredential:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - } - - /** - * signInWithPhoneNumber - * - * @param appName - * @param phoneNumber - */ - @ReactMethod - public void signInWithPhoneNumber( - String appName, - final String phoneNumber, - final boolean forceResend, - final Promise promise - ) { - Log.d(TAG, "signInWithPhoneNumber"); - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - Activity activity = mReactContext.getCurrentActivity(); - - // reset force resending token if phone number changes - if (!phoneNumber.equals(mLastPhoneNumber)) { - mForceResendingToken = null; - mLastPhoneNumber = phoneNumber; - } - - // Reset the verification Id - mVerificationId = null; - - PhoneAuthProvider.OnVerificationStateChangedCallbacks callbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { - private boolean promiseResolved = false; - - @Override - public void onVerificationCompleted(final PhoneAuthCredential phoneAuthCredential) { - // User has been automatically verified, log them in - firebaseAuth - .signInWithCredential(phoneAuthCredential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - // onAuthStateChanged will pick up the user change - Log.d( - TAG, - "signInWithPhoneNumber:autoVerified:signInWithCredential:onComplete:success" - ); - // To ensure that there is no hanging promise, we resolve it with a null verificationId - // as calling ConfirmationResult.confirm(code) is invalid in this case anyway - if (!promiseResolved) { - WritableMap verificationMap = Arguments.createMap(); - - Parcel parcel = Parcel.obtain(); - phoneAuthCredential.writeToParcel(parcel, 0); - parcel.setDataPosition(16); // verificationId - String verificationId = parcel.readString(); - mVerificationId = verificationId; - parcel.recycle(); - - verificationMap.putString("verificationId", verificationId); - promise.resolve(verificationMap); - } - } else { - // With phone auth, the credential will only every be rejected if the user - // account linked to the phone number has been disabled - Exception exception = task.getException(); - Log.e( - TAG, - "signInWithPhoneNumber:autoVerified:signInWithCredential:onComplete:failure", - exception - ); - // In the scenario where an SMS code has been sent, we have no way to report - // back to the front-end that as the promise has already been used - if (!promiseResolved) { - promiseRejectAuthException(promise, exception); - } - } - } - }); - } - - @Override - public void onVerificationFailed(FirebaseException e) { - // This callback is invoked in an invalid request for verification is made, - // e.g. phone number format is incorrect, or the SMS quota for the project - // has been exceeded - Log.d(TAG, "signInWithPhoneNumber:verification:failed"); - promiseRejectAuthException(promise, e); - } - - @Override - public void onCodeSent( - String verificationId, - PhoneAuthProvider.ForceResendingToken forceResendingToken - ) { - // TODO: This isn't being saved anywhere if the activity gets restarted when going to the SMS app - mVerificationId = verificationId; - mForceResendingToken = forceResendingToken; - WritableMap verificationMap = Arguments.createMap(); - verificationMap.putString("verificationId", verificationId); - promise.resolve(verificationMap); - promiseResolved = true; - } - - @Override - public void onCodeAutoRetrievalTimeOut(String verificationId) { - super.onCodeAutoRetrievalTimeOut(verificationId); - // Purposefully not doing anything with this at the moment - } - }; - - if (activity != null) { - if (forceResend && mForceResendingToken != null) { - PhoneAuthProvider - .getInstance(firebaseAuth) - .verifyPhoneNumber( - phoneNumber, - 60, - TimeUnit.SECONDS, - activity, - callbacks, - mForceResendingToken - ); - } else { - PhoneAuthProvider - .getInstance(firebaseAuth) - .verifyPhoneNumber( - phoneNumber, - 60, - TimeUnit.SECONDS, - activity, - callbacks - ); - } - } - } - - @ReactMethod - public void _confirmVerificationCode( - String appName, - final String verificationCode, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - PhoneAuthCredential credential = PhoneAuthProvider.getCredential( - mVerificationId, - verificationCode - ); - - firebaseAuth - .signInWithCredential(credential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d( - TAG, - "_confirmVerificationCode:signInWithCredential:onComplete:success" - ); - promiseWithUser( - task - .getResult() - .getUser(), - promise - ); - } else { - Exception exception = task.getException(); - Log.e( - TAG, - "_confirmVerificationCode:signInWithCredential:onComplete:failure", - exception - ); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * verifyPhoneNumber - * - * @param appName - * @param phoneNumber - * @param timeout - */ - @ReactMethod - public void verifyPhoneNumber( - final String appName, - final String phoneNumber, - final String requestKey, - final int timeout, - final boolean forceResend - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - final Activity activity = mReactContext.getCurrentActivity(); - - Log.d(TAG, "verifyPhoneNumber:" + phoneNumber); - - // reset force resending token if phone number changes - if (!phoneNumber.equals(mLastPhoneNumber)) { - mForceResendingToken = null; - mLastPhoneNumber = phoneNumber; - } - - // Reset the credential - mCredential = null; - - PhoneAuthProvider.OnVerificationStateChangedCallbacks callbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { - - @Override - public void onVerificationCompleted(final PhoneAuthCredential phoneAuthCredential) { - // Cache the credential to protect against null verificationId - mCredential = phoneAuthCredential; - - Log.d(TAG, "verifyPhoneNumber:verification:onVerificationCompleted"); - WritableMap state = Arguments.createMap(); - - Parcel parcel = Parcel.obtain(); - phoneAuthCredential.writeToParcel(parcel, 0); - - // verificationId - parcel.setDataPosition(16); - String verificationId = parcel.readString(); - - // sms Code - parcel.setDataPosition(parcel.dataPosition() + 8); - String code = parcel.readString(); - - state.putString("code", code); - state.putString("verificationId", verificationId); - parcel.recycle(); - sendPhoneStateEvent(appName, requestKey, "onVerificationComplete", state); - } - - @Override - public void onVerificationFailed(FirebaseException e) { - // This callback is invoked in an invalid request for verification is made, - // e.g. phone number format is incorrect, or the SMS quota for the project - // has been exceeded - Log.d(TAG, "verifyPhoneNumber:verification:onVerificationFailed"); - WritableMap state = Arguments.createMap(); - state.putMap("error", getJSError(e)); - sendPhoneStateEvent(appName, requestKey, "onVerificationFailed", state); - } - - @Override - public void onCodeSent( - String verificationId, - PhoneAuthProvider.ForceResendingToken forceResendingToken - ) { - Log.d(TAG, "verifyPhoneNumber:verification:onCodeSent"); - mForceResendingToken = forceResendingToken; - WritableMap state = Arguments.createMap(); - state.putString("verificationId", verificationId); - - - // todo forceResendingToken - it's actually just an empty class ... no actual token >.> - // Parcel parcel = Parcel.obtain(); - // forceResendingToken.writeToParcel(parcel, 0); - // - // // verificationId - // parcel.setDataPosition(0); - // int int1 = parcel.readInt(); - // String token = parcel.readString(); - // - // state.putString("refreshToken", token); - // parcel.recycle(); - - state.putString("verificationId", verificationId); - sendPhoneStateEvent(appName, requestKey, "onCodeSent", state); - } - - @Override - public void onCodeAutoRetrievalTimeOut(String verificationId) { - super.onCodeAutoRetrievalTimeOut(verificationId); - Log.d(TAG, "verifyPhoneNumber:verification:onCodeAutoRetrievalTimeOut"); - WritableMap state = Arguments.createMap(); - state.putString("verificationId", verificationId); - sendPhoneStateEvent(appName, requestKey, "onCodeAutoRetrievalTimeout", state); - } - }; - - if (activity != null) { - if (forceResend && mForceResendingToken != null) { - PhoneAuthProvider - .getInstance(firebaseAuth) - .verifyPhoneNumber( - phoneNumber, - timeout, - TimeUnit.SECONDS, - activity, - callbacks, - mForceResendingToken - ); - } else { - PhoneAuthProvider - .getInstance(firebaseAuth) - .verifyPhoneNumber( - phoneNumber, - timeout, - TimeUnit.SECONDS, - activity, - callbacks - ); - } - } - } - - /** - * confirmPasswordReset - * - * @param code - * @param newPassword - * @param promise - */ - @ReactMethod - public void confirmPasswordReset( - String appName, - String code, - String newPassword, - final Promise promise - ) { - Log.d(TAG, "confirmPasswordReset"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .confirmPasswordReset(code, newPassword) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "confirmPasswordReset:onComplete:success"); - promiseNoUser(promise, false); - } else { - Exception exception = task.getException(); - Log.e(TAG, "confirmPasswordReset:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * applyActionCode - * - * @param code - * @param promise - */ - @ReactMethod - public void applyActionCode(String appName, String code, final Promise promise) { - Log.d(TAG, "applyActionCode"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .applyActionCode(code) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "applyActionCode:onComplete:success"); - promiseNoUser(promise, false); - } else { - Exception exception = task.getException(); - Log.e(TAG, "applyActionCode:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * @param code - * @param promise - */ - @ReactMethod - public void checkActionCode(String appName, String code, final Promise promise) { - Log.d(TAG, "checkActionCode"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .checkActionCode(code) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "checkActionCode:onComplete:success"); - ActionCodeResult result = task.getResult(); - - WritableMap writableMap = Arguments.createMap(); - WritableMap dataMap = Arguments.createMap(); - - dataMap.putString("email", result.getData(ActionCodeResult.EMAIL)); - dataMap.putString("fromEmail", result.getData(ActionCodeResult.FROM_EMAIL)); - - writableMap.putMap("data", dataMap); - - String actionType = "UNKNOWN"; - - switch (result.getOperation()) { - case ActionCodeResult.ERROR: - actionType = "ERROR"; - break; - case ActionCodeResult.VERIFY_EMAIL: - actionType = "VERIFY_EMAIL"; - break; - case ActionCodeResult.RECOVER_EMAIL: - actionType = "RECOVER_EMAIL"; - break; - case ActionCodeResult.PASSWORD_RESET: - actionType = "PASSWORD_RESET"; - break; - case ActionCodeResult.SIGN_IN_WITH_EMAIL_LINK: - actionType = "EMAIL_SIGNIN"; - break; - } - - writableMap.putString("operation", actionType); - - promise.resolve(writableMap); - } else { - Exception exception = task.getException(); - Log.e(TAG, "checkActionCode:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * linkWithCredential - * - * @param provider - * @param authToken - * @param authSecret - * @param promise - */ - @ReactMethod - private void linkWithCredential( - String appName, - String provider, - String authToken, - String authSecret, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - AuthCredential credential = getCredentialForProvider(provider, authToken, authSecret); - - if (credential == null) { - promise.reject( - "auth/invalid-credential", - "The supplied auth credential is malformed, has expired or is not currently supported." - ); - } else { - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "link"); - - if (user != null) { - user - .linkWithCredential(credential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "link:onComplete:success"); - promiseWithAuthResult(task.getResult(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "link:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } else { - promiseNoUser(promise, true); - } - } - } - - @ReactMethod - public void unlink(final String appName, final String providerId, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "unlink"); - - if (user != null) { - user - .unlink(providerId) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "unlink:onComplete:success"); - promiseWithUser(task - .getResult() - .getUser(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "unlink:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } else { - promiseNoUser(promise, true); - } - } - - @ReactMethod - private void reauthenticateWithCredential( - String appName, - String provider, - String authToken, - String authSecret, - final Promise promise - ) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - AuthCredential credential = getCredentialForProvider(provider, authToken, authSecret); - - if (credential == null) { - promise.reject( - "auth/invalid-credential", - "The supplied auth credential is malformed, has expired or is not currently supported." - ); - } else { - FirebaseUser user = firebaseAuth.getCurrentUser(); - Log.d(TAG, "reauthenticate"); - - if (user != null) { - user - .reauthenticateAndRetrieveData(credential) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "reauthenticate:onComplete:success"); - promiseWithAuthResult(task.getResult(), promise); - } else { - Exception exception = task.getException(); - Log.e(TAG, "reauthenticate:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } else { - promiseNoUser(promise, true); - } - } - } - - /** - * Returns an instance of AuthCredential for the specified provider - */ - private AuthCredential getCredentialForProvider( - String provider, - String authToken, - String authSecret - ) { - switch (provider) { - case "facebook.com": - return FacebookAuthProvider.getCredential(authToken); - case "google.com": - return GoogleAuthProvider.getCredential(authToken, authSecret); - case "twitter.com": - return TwitterAuthProvider.getCredential(authToken, authSecret); - case "github.com": - return GithubAuthProvider.getCredential(authToken); - case "oauth": - return OAuthProvider.getCredential(provider, authToken, authSecret); - case "phone": - return getPhoneAuthCredential(authToken, authSecret); - case "password": - // authToken = email - // authSecret = password - return EmailAuthProvider.getCredential(authToken, authSecret); - case "emailLink": - // authToken = email - // authSecret = link - return EmailAuthProvider.getCredentialWithLink(authToken, authSecret); - default: - return null; - } - } - - /** - * Returns an instance of PhoneAuthCredential, potentially cached - */ - private PhoneAuthCredential getPhoneAuthCredential( - String authToken, - String authSecret - ) { - // If the phone number is auto-verified quickly, then the verificationId can be null - // We cached the credential as part of the verifyPhoneNumber request to be re-used here - // if possible - if (authToken == null && mCredential != null) { - PhoneAuthCredential credential = mCredential; - // Reset the cached credential - mCredential = null; - return credential; - } - - if (authToken != null) { - return PhoneAuthProvider.getCredential(authToken, authSecret); - } - - return null; - } - - /** - * getIdToken - * - * @param appName - * @param forceRefresh - * @param promise - */ - @ReactMethod - public void getIdToken(String appName, Boolean forceRefresh, final Promise promise) { - Log.d(TAG, "getIdToken"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseUser user = firebaseAuth.getCurrentUser(); - - if (user == null) { - promiseNoUser(promise, true); - return; - } - - user - .getIdToken(forceRefresh) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "getIdToken:onComplete:success"); - GetTokenResult tokenResult = task.getResult(); - promise.resolve(tokenResult.getToken()); - } else { - Exception exception = task.getException(); - Log.e(TAG, "getIdToken:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * getIdTokenResult - * - * @param appName - * @param forceRefresh - * @param promise - */ - @ReactMethod - public void getIdTokenResult(String appName, Boolean forceRefresh, final Promise promise) { - Log.d(TAG, "getIdTokenResult"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - FirebaseUser user = firebaseAuth.getCurrentUser(); - - if (user == null) { - promiseNoUser(promise, true); - return; - } - - user - .getIdToken(forceRefresh) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "getIdTokenResult:onComplete:success"); - GetTokenResult tokenResult = task.getResult(); - WritableMap tokenResultMap = Arguments.createMap(); - - Utils.mapPutValue( - "authTime", - Utils.timestampToUTC(tokenResult.getAuthTimestamp()), - tokenResultMap - ); - - Utils.mapPutValue( - "expirationTime", - Utils.timestampToUTC(tokenResult.getExpirationTimestamp()), - tokenResultMap - ); - - Utils.mapPutValue( - "issuedAtTime", - Utils.timestampToUTC(tokenResult.getIssuedAtTimestamp()), - tokenResultMap - ); - - Utils.mapPutValue( - "claims", - tokenResult.getClaims(), - tokenResultMap - ); - - Utils.mapPutValue( - "signInProvider", - tokenResult.getSignInProvider(), - tokenResultMap - ); - - Utils.mapPutValue( - "token", - tokenResult.getToken(), - tokenResultMap - ); - - promise.resolve(tokenResultMap); - } else { - Exception exception = task.getException(); - Log.e(TAG, "getIdTokenResult:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - - /** - * fetchSignInMethodsForEmail - * - * @param appName - * @param email - * @param promise - */ - @ReactMethod - public void fetchSignInMethodsForEmail(String appName, String email, final Promise promise) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - Log.d(TAG, "fetchProvidersForEmail"); - - firebaseAuth - .fetchSignInMethodsForEmail(email) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "fetchProvidersForEmail:onComplete:success"); - List providers = task - .getResult() - .getSignInMethods(); - WritableArray array = Arguments.createArray(); - - if (providers != null) { - for (String provider : providers) { - array.pushString(provider); - } - } - - promise.resolve(array); - } else { - Exception exception = task.getException(); - Log.d(TAG, "fetchProvidersForEmail:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /** - * setLanguageCode - * - * @param appName - * @param code - */ - @ReactMethod - public void setLanguageCode(String appName, String code) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth.setLanguageCode(code); - } - - /** - * useDeviceLanguage - * - * @param appName - */ - @ReactMethod - public void useDeviceLanguage(String appName) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth.useAppLanguage(); - } - - @ReactMethod - public void verifyPasswordResetCode(String appName, String code, final Promise promise) { - Log.d(TAG, "verifyPasswordResetCode"); - - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp); - - firebaseAuth - .verifyPasswordResetCode(code) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "verifyPasswordResetCode:onComplete:success"); - promise.resolve(task.getResult()); - } else { - Exception exception = task.getException(); - Log.e(TAG, "verifyPasswordResetCode:onComplete:failure", exception); - promiseRejectAuthException(promise, exception); - } - } - }); - } - - /* ------------------ - * INTERNAL HELPERS - * ---------------- */ - - /** - * Resolves or rejects an auth method promise without a user (user was missing) - * - * @param promise - * @param isError - */ - private void promiseNoUser(Promise promise, Boolean isError) { - if (isError) { - promise.reject("auth/no-current-user", "No user currently signed in."); - } else { - promise.resolve(null); - } - } - - /** - * promiseWithUser - * - * @param user - * @param promise - */ - private void promiseWithUser(final FirebaseUser user, final Promise promise) { - if (user != null) { - WritableMap userMap = firebaseUserToMap(user); - promise.resolve(userMap); - } else { - promiseNoUser(promise, true); - } - } - - /** - * promiseWithAuthResult - * - * @param authResult - * @param promise - */ - private void promiseWithAuthResult(AuthResult authResult, Promise promise) { - if (authResult != null && authResult.getUser() != null) { - WritableMap authResultMap = Arguments.createMap(); - WritableMap userMap = firebaseUserToMap(authResult.getUser()); - - if (authResult.getAdditionalUserInfo() != null) { - WritableMap additionalUserInfoMap = Arguments.createMap(); - - additionalUserInfoMap.putBoolean( - "isNewUser", - authResult - .getAdditionalUserInfo() - .isNewUser() - ); - - if (authResult - .getAdditionalUserInfo() - .getProfile() != null) { - Utils.mapPutValue( - "profile", - authResult - .getAdditionalUserInfo() - .getProfile(), - additionalUserInfoMap - ); - } - - if (authResult - .getAdditionalUserInfo() - .getProviderId() != null) { - additionalUserInfoMap.putString( - "providerId", - authResult - .getAdditionalUserInfo() - .getProviderId() - ); - } - - if (authResult - .getAdditionalUserInfo() - .getUsername() != null) { - additionalUserInfoMap.putString( - "username", - authResult - .getAdditionalUserInfo() - .getUsername() - ); - } - - authResultMap.putMap("additionalUserInfo", additionalUserInfoMap); - } - authResultMap.putMap("user", userMap); - promise.resolve(authResultMap); - } else { - promiseNoUser(promise, true); - } - } - - /** - * promiseRejectAuthException - * - * @param promise - * @param exception - */ - private void promiseRejectAuthException(Promise promise, Exception exception) { - WritableMap error = getJSError(exception); - promise.reject(error.getString("code"), error.getString("message"), exception); - } - - /** - * getJSError - * - * @param exception - */ - private WritableMap getJSError(Exception exception) { - WritableMap error = Arguments.createMap(); - String code = "UNKNOWN"; - String message = exception.getMessage(); - String invalidEmail = "The email address is badly formatted."; - - try { - FirebaseAuthException authException = (FirebaseAuthException) exception; - code = authException.getErrorCode(); - error.putString("nativeErrorCode", code); - message = authException.getMessage(); - } catch (Exception e) { - Matcher matcher = Pattern - .compile("([A-Z]*_[A-Z]*)") - .matcher(message); - if (matcher.find()) { - code = matcher - .group(1) - .trim(); - switch (code) { - case "INVALID_CUSTOM_TOKEN": - message = "The custom token format is incorrect. Please check the documentation."; - break; - case "CUSTOM_TOKEN_MISMATCH": - message = "The custom token corresponds to a different audience."; - break; - case "INVALID_CREDENTIAL": - message = "The supplied auth credential is malformed or has expired."; - break; - case "INVALID_EMAIL": - message = invalidEmail; - break; - case "WRONG_PASSWORD": - message = "The password is invalid or the user does not have a password."; - break; - case "USER_MISMATCH": - message = "The supplied credentials do not correspond to the previously signed in user."; - break; - case "REQUIRES_RECENT_LOGIN": - message = "This operation is sensitive and requires recent authentication. Log in again before retrying this request."; - break; - case "ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL": - message = "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address."; - break; - case "EMAIL_ALREADY_IN_USE": - message = "The email address is already in use by another account."; - break; - case "CREDENTIAL_ALREADY_IN_USE": - message = "This credential is already associated with a different user account."; - break; - case "USER_DISABLED": - message = "The user account has been disabled by an administrator."; - break; - case "USER_TOKEN_EXPIRED": - message = "The user\'s credential is no longer valid. The user must sign in again."; - break; - case "USER_NOT_FOUND": - message = "There is no user record corresponding to this identifier. The user may have been deleted."; - break; - case "INVALID_USER_TOKEN": - message = "The user\'s credential is no longer valid. The user must sign in again."; - break; - case "WEAK_PASSWORD": - message = "The given password is invalid."; - break; - case "OPERATION_NOT_ALLOWED": - message = "This operation is not allowed. You must enable this service in the console."; - break; - case "INVALID_IDENTIFIER": - code = "INVALID_EMAIL"; - message = invalidEmail; - break; - } - } - } - - if (code.equals("UNKNOWN") && exception instanceof FirebaseAuthInvalidCredentialsException) { - code = "INVALID_EMAIL"; - message = invalidEmail; - } - - code = "auth/" + code - .toLowerCase() - .replace("error_", "") - .replace('_', '-'); - error.putString("code", code); - error.putString("message", message); - error.putString("nativeErrorMessage", exception.getMessage()); - return error; - } - - - /** - * Converts a List of UserInfo instances into the correct format to match the web sdk - * - * @param providerData List user.getProviderData() - * @return WritableArray array - */ - private WritableArray convertProviderData( - List providerData, - FirebaseUser user - ) { - WritableArray output = Arguments.createArray(); - for (UserInfo userInfo : providerData) { - // remove 'firebase' provider data - android fb sdk - // should not be returning this as the ios/web ones don't - if (!FirebaseAuthProvider.PROVIDER_ID.equals(userInfo.getProviderId())) { - WritableMap userInfoMap = Arguments.createMap(); - userInfoMap.putString("providerId", userInfo.getProviderId()); - userInfoMap.putString("uid", userInfo.getUid()); - userInfoMap.putString("displayName", userInfo.getDisplayName()); - - final Uri photoUrl = userInfo.getPhotoUrl(); - - if (photoUrl != null && !"".equals(photoUrl.toString())) { - userInfoMap.putString("photoURL", photoUrl.toString()); - } else { - userInfoMap.putNull("photoURL"); - } - - final String phoneNumber = userInfo.getPhoneNumber(); - // The Android SDK is missing the phone number property for the phone provider when the - // user first signs up using their phone number. Use the phone number from the user - // object instead - if (PhoneAuthProvider.PROVIDER_ID.equals(userInfo.getProviderId()) - && (userInfo.getPhoneNumber() == null || "".equals(userInfo.getPhoneNumber()))) { - userInfoMap.putString("phoneNumber", user.getPhoneNumber()); - } else if (phoneNumber != null && !"".equals(phoneNumber)) { - userInfoMap.putString("phoneNumber", phoneNumber); - } else { - userInfoMap.putNull("phoneNumber"); - } - - // The Android SDK is missing the email property for the email provider, so we use UID instead - if (EmailAuthProvider.PROVIDER_ID.equals(userInfo.getProviderId()) - && (userInfo.getEmail() == null || "".equals(userInfo.getEmail()))) { - userInfoMap.putString("email", userInfo.getUid()); - } else if (userInfo.getEmail() != null && !"".equals(userInfo.getEmail())) { - userInfoMap.putString("email", userInfo.getEmail()); - } else { - userInfoMap.putNull("email"); - } - - output.pushMap(userInfoMap); - } - } - - return output; - } - - /** - * firebaseUserToMap - * - * @param user - * @return - */ - private WritableMap firebaseUserToMap(FirebaseUser user) { - WritableMap userMap = Arguments.createMap(); - - final String uid = user.getUid(); - final String email = user.getEmail(); - final Uri photoUrl = user.getPhotoUrl(); - final String name = user.getDisplayName(); - final String provider = user.getProviderId(); - final Boolean verified = user.isEmailVerified(); - final String phoneNumber = user.getPhoneNumber(); - - userMap.putString("uid", uid); - userMap.putString("providerId", provider); - userMap.putBoolean("emailVerified", verified); - userMap.putBoolean("isAnonymous", user.isAnonymous()); - - if (email != null && !"".equals(email)) { - userMap.putString("email", email); - } else { - userMap.putNull("email"); - } - - if (name != null && !"".equals(name)) { - userMap.putString("displayName", name); - } else { - userMap.putNull("displayName"); - } - - if (photoUrl != null && !"".equals(photoUrl.toString())) { - userMap.putString("photoURL", photoUrl.toString()); - } else { - userMap.putNull("photoURL"); - } - - if (phoneNumber != null && !"".equals(phoneNumber)) { - userMap.putString("phoneNumber", phoneNumber); - } else { - userMap.putNull("phoneNumber"); - } - - userMap.putArray("providerData", convertProviderData(user.getProviderData(), user)); - - WritableMap metadataMap = Arguments.createMap(); - FirebaseUserMetadata metadata = user.getMetadata(); - if (metadata != null) { - metadataMap.putDouble("creationTime", metadata.getCreationTimestamp()); - metadataMap.putDouble("lastSignInTime", metadata.getLastSignInTimestamp()); - } - userMap.putMap("metadata", metadataMap); - - return userMap; - } - - private ActionCodeSettings buildActionCodeSettings(ReadableMap actionCodeSettings) { - ActionCodeSettings.Builder builder = ActionCodeSettings.newBuilder(); - ReadableMap android = actionCodeSettings.getMap("android"); - ReadableMap ios = actionCodeSettings.getMap("iOS"); - String url = actionCodeSettings.getString("url"); - if (android != null) { - boolean installApp = android.hasKey("installApp") && android.getBoolean("installApp"); - String minimumVersion = android.hasKey("minimumVersion") ? android.getString("minimumVersion") : null; - String packageName = android.getString("packageName"); - builder = builder.setAndroidPackageName(packageName, installApp, minimumVersion); - } - if (actionCodeSettings.hasKey("handleCodeInApp")) { - builder = builder.setHandleCodeInApp(actionCodeSettings.getBoolean("handleCodeInApp")); - } - if (ios != null && ios.hasKey("bundleId")) { - builder = builder.setIOSBundleId(ios.getString("bundleId")); - } - if (url != null) { - builder = builder.setUrl(url); - } - - return builder.build(); - } - - /** - * @param appName - * @param requestKey - * @param type - * @param state - */ - private void sendPhoneStateEvent( - String appName, - String requestKey, - String type, - WritableMap state - ) { - WritableMap eventMap = Arguments.createMap(); - eventMap.putString("appName", appName); - eventMap.putString("requestKey", requestKey); - eventMap.putString("type", type); - eventMap.putMap("state", state); - Utils.sendEvent(mReactContext, "phone_auth_state_changed", eventMap); - } - - /** - * Constants bootstrapped on react native app boot - * - * @return - */ - @Override - public Map getConstants() { - Map constants = new HashMap<>(); - - List firebaseAppList = FirebaseApp.getApps(getReactApplicationContext()); - final Map appLanguage = new HashMap<>(); - final Map appUser = new HashMap<>(); - - for (FirebaseApp app : firebaseAppList) { - String appName = app.getName(); - - FirebaseApp instance = FirebaseApp.getInstance(appName); - FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(instance); - FirebaseUser user = firebaseAuth.getCurrentUser(); - - appLanguage.put(appName, firebaseAuth.getLanguageCode()); - - if (user != null) { - appUser.put(appName, firebaseUserToMap(user)); - } - } - - constants.put("APP_LANGUAGE", appLanguage); - constants.put("APP_USER", appUser); - - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuthPackage.java b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuthPackage.java deleted file mode 100644 index 1ed3c621..00000000 --- a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuthPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.auth; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseAuthPackage implements ReactPackage { - public RNFirebaseAuthPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseAuth(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfig.java b/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfig.java deleted file mode 100644 index 4bdec4a3..00000000 --- a/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfig.java +++ /dev/null @@ -1,209 +0,0 @@ -package io.invertase.firebase.config; - -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.remoteconfig.FirebaseRemoteConfig; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseRemoteConfig"; - - private static final String STRING_VALUE = "stringValue"; - private static final String DATA_VALUE = "dataValue"; - private static final String BOOL_VALUE = "boolValue"; - private static final String NUMBER_VALUE = "numberValue"; - private static final String SOURCE = "source"; - - RNFirebaseRemoteConfig(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - /** - * @return - */ - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void enableDeveloperMode() { - FirebaseRemoteConfigSettings.Builder settings = new FirebaseRemoteConfigSettings.Builder(); - settings.setDeveloperModeEnabled(true); - - FirebaseRemoteConfig - .getInstance() - .setConfigSettings(settings.build()); - } - - @ReactMethod - public void fetch(final Promise promise) { - fetchInternal(promise, false, 0); - } - - @ReactMethod - public void fetchWithExpirationDuration(double expirationDuration, final Promise promise) { - fetchInternal(promise, true, (long) expirationDuration); - } - - @ReactMethod - public void activateFetched(final Promise promise) { - Boolean status = FirebaseRemoteConfig - .getInstance() - .activateFetched(); - - promise.resolve(status); - } - - @ReactMethod - public void getValue(String key, final Promise promise) { - FirebaseRemoteConfigValue value = FirebaseRemoteConfig - .getInstance() - .getValue(key); - - promise.resolve(convertRemoteConfigValue(value)); - } - - @ReactMethod - public void getValues(ReadableArray keys, final Promise promise) { - WritableArray array = Arguments.createArray(); - List keysList = Utils.recursivelyDeconstructReadableArray(keys); - - for (Object key : keysList) { - FirebaseRemoteConfigValue value = FirebaseRemoteConfig - .getInstance() - .getValue((String) key); - - array.pushMap(convertRemoteConfigValue(value)); - } - - promise.resolve(array); - } - - @ReactMethod - public void getKeysByPrefix(String prefix, final Promise promise) { - Set keys = FirebaseRemoteConfig - .getInstance() - .getKeysByPrefix(prefix); - - WritableArray array = Arguments.createArray(); - - for (String key : keys) { - array.pushString(key); - } - - promise.resolve(array); - } - - @ReactMethod - public void setDefaults(ReadableMap map) { - Map convertedMap = Utils.recursivelyDeconstructReadableMap(map); - FirebaseRemoteConfig - .getInstance() - .setDefaults(convertedMap); - } - - @ReactMethod - public void setDefaultsFromResource(int resourceId) { - FirebaseRemoteConfig - .getInstance() - .setDefaults(resourceId); - } - - private void fetchInternal( - final Promise promise, - Boolean withExpiration, - long expirationDuration - ) { - FirebaseRemoteConfig - .getInstance() - .fetch(withExpiration ? expirationDuration : 43200) // 12 hours default - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - promise.resolve(null); - } else { - if (task.getException() instanceof FirebaseRemoteConfigFetchThrottledException) { - promise.reject( - "config/throttled", - "fetch() operation cannot be completed successfully, due to throttling.", - task.getException() - ); - } else { - promise.reject( - "config/failure", - "fetch() operation cannot be completed successfully.", - task.getException() - ); - } - } - } - }); - } - - private WritableMap convertRemoteConfigValue(FirebaseRemoteConfigValue value) { - WritableMap map = Arguments.createMap(); - - map.putString(STRING_VALUE, value.asString()); - - try { - map.putString(DATA_VALUE, new String(value.asByteArray())); - } catch (Exception e) { - map.putNull(DATA_VALUE); - } - - Boolean booleanValue; - try { - booleanValue = value.asBoolean(); - map.putBoolean(BOOL_VALUE, booleanValue); - } catch (Exception e) { - map.putNull(BOOL_VALUE); - } - - Double numberValue; - try { - numberValue = value.asDouble(); - map.putDouble(NUMBER_VALUE, numberValue); - } catch (Exception e) { - map.putNull(NUMBER_VALUE); - } - - switch (value.getSource()) { - case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: - map.putString(SOURCE, "default"); - break; - case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: - map.putString(SOURCE, "remote"); - break; - default: - map.putString(SOURCE, "static"); - } - - return map; - } - -} diff --git a/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfigPackage.java b/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfigPackage.java deleted file mode 100644 index 22cb28fe..00000000 --- a/android/src/main/java/io/invertase/firebase/config/RNFirebaseRemoteConfigPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.config; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseRemoteConfigPackage implements ReactPackage { - public RNFirebaseRemoteConfigPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseRemoteConfig(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabase.java b/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabase.java deleted file mode 100644 index 727c906e..00000000 --- a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabase.java +++ /dev/null @@ -1,876 +0,0 @@ -package io.invertase.firebase.database; - -import android.os.AsyncTask; -import android.util.Log; -import android.util.SparseArray; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.FirebaseApp; -import com.google.firebase.database.DataSnapshot; -import com.google.firebase.database.DatabaseError; -import com.google.firebase.database.DatabaseException; -import com.google.firebase.database.DatabaseReference; -import com.google.firebase.database.FirebaseDatabase; -import com.google.firebase.database.Logger; -import com.google.firebase.database.MutableData; -import com.google.firebase.database.OnDisconnect; -import com.google.firebase.database.ServerValue; -import com.google.firebase.database.Transaction; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.ErrorUtils; -import io.invertase.firebase.Utils; - -public class RNFirebaseDatabase extends ReactContextBaseJavaModule { - private static final String TAG = "RNFirebaseDatabase"; - private static boolean enableLogging = false; - private static ReactApplicationContext reactApplicationContext = null; - private static HashMap loggingLevelSet = new HashMap<>(); - private static HashMap references = new HashMap<>(); - private static SparseArray transactionHandlers = new SparseArray<>(); - - RNFirebaseDatabase(ReactApplicationContext reactContext) { - super(reactContext); - } - - static ReactApplicationContext getReactApplicationContextInstance() { - return reactApplicationContext; - } - - /** - * Resolve null or reject with a js like error if databaseError exists - * - * @param promise - * @param databaseError - */ - static void handlePromise(Promise promise, DatabaseError databaseError) { - if (databaseError != null) { - WritableMap jsError = getJSError(databaseError); - promise.reject( - jsError.getString("code"), - jsError.getString("message"), - databaseError.toException() - ); - } else { - promise.resolve(null); - } - } - - - /* - * REACT NATIVE METHODS - */ - - /** - * Get a database instance for a specific firebase app instance - * - * @param appName - * @param dbURL - * @return - */ - static FirebaseDatabase getDatabaseForApp(String appName, String dbURL) { - FirebaseDatabase firebaseDatabase; - if (dbURL != null && dbURL.length() > 0) { - if (appName != null && appName.length() > 0) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp, dbURL); - } else { - firebaseDatabase = FirebaseDatabase.getInstance(dbURL); - } - } else { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp); - } - - Boolean logLevel = loggingLevelSet.get(firebaseDatabase - .getApp() - .getName()); - - if (enableLogging && (logLevel == null || !logLevel)) { - try { - loggingLevelSet.put(firebaseDatabase - .getApp() - .getName(), enableLogging); - firebaseDatabase.setLogLevel(Logger.Level.DEBUG); - } catch (DatabaseException dex) { - // do nothing - to catch 'calls to setLogLevel must be made for use of database' errors - // only occurs in dev after reloading or if user has actually incorrectly called it. - Log.w( - TAG, - "WARNING: enableLogging(bool) must be called before any other use of database(). \n" + - "If you are sure you've done this then this message can be ignored during development as \n" + - "RN reloads can cause false positives. APP: " + firebaseDatabase - .getApp() - .getName() - ); - } - } else if (!enableLogging && (logLevel != null && logLevel)) { - try { - loggingLevelSet.put(firebaseDatabase - .getApp() - .getName(), enableLogging); - firebaseDatabase.setLogLevel(Logger.Level.WARN); - } catch (DatabaseException dex) { - // do nothing - to catch 'calls to setLogLevel must be made for use of database' errors - // only occurs in dev after reloading or if user has actually incorrectly called it. - Log.w( - TAG, - "WARNING: enableLogging(bool) must be called before any other use of database(). \n" + - "If you are sure you've done this then this message can be ignored during development as \n" + - "RN reloads can cause false positives. APP: " + firebaseDatabase - .getApp() - .getName() - ); - } - } - - return firebaseDatabase; - } - - /** - * Convert as firebase DatabaseError instance into a writable map - * with the correct web-like error codes. - * - * @param nativeError - * @return - */ - static WritableMap getJSError(DatabaseError nativeError) { - WritableMap errorMap = Arguments.createMap(); - errorMap.putInt("nativeErrorCode", nativeError.getCode()); - errorMap.putString("nativeErrorMessage", nativeError.getMessage()); - - String code; - String message; - String service = "Database"; - - switch (nativeError.getCode()) { - case DatabaseError.DATA_STALE: - code = ErrorUtils.getCodeWithService(service, "data-stale"); - message = ErrorUtils.getMessageWithService( - "The transaction needs to be run again with current data.", - service, - code - ); - break; - case DatabaseError.OPERATION_FAILED: - code = ErrorUtils.getCodeWithService(service, "failure"); - message = ErrorUtils.getMessageWithService( - "The server indicated that this operation failed.", - service, - code - ); - break; - case DatabaseError.PERMISSION_DENIED: - code = ErrorUtils.getCodeWithService(service, "permission-denied"); - message = ErrorUtils.getMessageWithService( - "Client doesn't have permission to access the desired data.", - service, - code - ); - break; - case DatabaseError.DISCONNECTED: - code = ErrorUtils.getCodeWithService(service, "disconnected"); - message = ErrorUtils.getMessageWithService( - "The operation had to be aborted due to a network disconnect.", - service, - code - ); - break; - case DatabaseError.EXPIRED_TOKEN: - code = ErrorUtils.getCodeWithService(service, "expired-token"); - message = ErrorUtils.getMessageWithService( - "The supplied auth token has expired.", - service, - code - ); - break; - case DatabaseError.INVALID_TOKEN: - code = ErrorUtils.getCodeWithService(service, "invalid-token"); - message = ErrorUtils.getMessageWithService( - "The supplied auth token was invalid.", - service, - code - ); - break; - case DatabaseError.MAX_RETRIES: - code = ErrorUtils.getCodeWithService(service, "max-retries"); - message = ErrorUtils.getMessageWithService( - "The transaction had too many retries.", - service, - code - ); - break; - case DatabaseError.OVERRIDDEN_BY_SET: - code = ErrorUtils.getCodeWithService(service, "overridden-by-set"); - message = ErrorUtils.getMessageWithService( - "The transaction was overridden by a subsequent set.", - service, - code - ); - break; - case DatabaseError.UNAVAILABLE: - code = ErrorUtils.getCodeWithService(service, "unavailable"); - message = ErrorUtils.getMessageWithService("The service is unavailable.", service, code); - break; - case DatabaseError.USER_CODE_EXCEPTION: - code = ErrorUtils.getCodeWithService(service, "user-code-exception"); - message = ErrorUtils.getMessageWithService( - "User code called from the Firebase Database runloop threw an exception.", - service, - code - ); - break; - case DatabaseError.NETWORK_ERROR: - code = ErrorUtils.getCodeWithService(service, "network-error"); - message = ErrorUtils.getMessageWithService( - "The operation could not be performed due to a network error.", - service, - code - ); - break; - case DatabaseError.WRITE_CANCELED: - code = ErrorUtils.getCodeWithService(service, "write-cancelled"); - message = ErrorUtils.getMessageWithService( - "The write was canceled by the user.", - service, - code - ); - break; - default: - code = ErrorUtils.getCodeWithService(service, "unknown"); - message = ErrorUtils.getMessageWithService("An unknown error occurred.", service, code); - } - - errorMap.putString("code", code); - errorMap.putString("message", message); - return errorMap; - } - - @Override - public void initialize() { - super.initialize(); - Log.d(TAG, "RNFirebaseDatabase:initialized"); - reactApplicationContext = getReactApplicationContext(); - } - - @Override - public void onCatalystInstanceDestroy() { - super.onCatalystInstanceDestroy(); - - Iterator refIterator = references.entrySet().iterator(); - while (refIterator.hasNext()) { - Map.Entry pair = (Map.Entry) refIterator.next(); - RNFirebaseDatabaseReference nativeRef = (RNFirebaseDatabaseReference) pair.getValue(); - nativeRef.removeAllEventListeners(); - refIterator.remove(); // avoids a ConcurrentModificationException - } - } - - /** - * @param appName - */ - @ReactMethod - public void goOnline(String appName, String dbURL) { - getDatabaseForApp(appName, dbURL).goOnline(); - } - - /** - * @param appName - */ - @ReactMethod - public void goOffline(String appName, String dbURL) { - getDatabaseForApp(appName, dbURL).goOffline(); - } - - /** - * @param appName - * @param state - */ - @ReactMethod - public void setPersistence(String appName, String dbURL, Boolean state) { - getDatabaseForApp(appName, dbURL).setPersistenceEnabled(state); - } - - - /* - * TRANSACTIONS - */ - - /** - * @param appName - * @param size - */ - @ReactMethod - public void setPersistenceCacheSizeBytes(String appName, String dbURL, int size) { - getDatabaseForApp(appName, dbURL).setPersistenceCacheSizeBytes((long) size); - } - - /** - * @param enabled - */ - @ReactMethod - public void enableLogging(Boolean enabled) { - enableLogging = enabled; - List firebaseAppList = FirebaseApp.getApps(getReactApplicationContext()); - for (FirebaseApp app : firebaseAppList) { - loggingLevelSet.put(app.getName(), enabled); - try { - if (enableLogging) { - FirebaseDatabase - .getInstance(app) - .setLogLevel(Logger.Level.DEBUG); - } else { - FirebaseDatabase - .getInstance(app) - .setLogLevel(Logger.Level.WARN); - } - } catch (DatabaseException dex) { - // do nothing - to catch 'calls to setLogLevel must be made for use of database' errors - // only occurs in dev after reloading or if user has actually incorrectly called it. - Log.w( - TAG, - "WARNING: enableLogging(bool) must be called before any other use of database(). \n" + - "If you are sure you've done this then this message can be ignored during development as \n" + - "RN reloads can cause false positives. APP: " + app.getName() - ); - } - } - } - - - /* - * ON DISCONNECT - */ - - /** - * @param appName - * @param path - * @param state - */ - @ReactMethod - public void keepSynced( - String appName, - String dbURL, - String key, - String path, - ReadableArray modifiers, - Boolean state - ) { - getInternalReferenceForApp(appName, dbURL, key, path, modifiers) - .getQuery() - .keepSynced(state); - } - - /** - * @param transactionId - * @param updates - */ - @ReactMethod - public void transactionTryCommit( - String appName, - String dbURL, - int transactionId, - ReadableMap updates - ) { - RNFirebaseTransactionHandler handler = transactionHandlers.get(transactionId); - - if (handler != null) { - handler.signalUpdateReceived(updates); - } - } - - /** - * Start a native transaction and store it's state in - * - * @param appName - * @param path - * @param transactionId - * @param applyLocally - */ - @ReactMethod - public void transactionStart( - final String appName, - final String dbURL, - final String path, - final int transactionId, - final Boolean applyLocally - ) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - DatabaseReference reference = getReferenceForAppPath(appName, dbURL, path); - - reference.runTransaction(new Transaction.Handler() { - @Nonnull - @Override - public Transaction.Result doTransaction(@Nonnull MutableData mutableData) { - final RNFirebaseTransactionHandler transactionHandler = new RNFirebaseTransactionHandler( - transactionId, - appName, - dbURL - ); - transactionHandlers.put(transactionId, transactionHandler); - final WritableMap updatesMap = transactionHandler.createUpdateMap(mutableData); - - // emit the updates to js using an async task - // otherwise it gets blocked by the lock await - AsyncTask.execute(new Runnable() { - @Override - public void run() { - Utils.sendEvent( - getReactApplicationContext(), - "database_transaction_event", - updatesMap - ); - } - }); - - // wait for js to return the updates (js calls transactionTryCommit) - try { - transactionHandler.await(); - } catch (InterruptedException e) { - transactionHandler.interrupted = true; - return Transaction.abort(); - } - - if (transactionHandler.abort) { - return Transaction.abort(); - } - - if (transactionHandler.timeout) { - return Transaction.abort(); - } - - mutableData.setValue(transactionHandler.value); - return Transaction.success(mutableData); - } - - @Override - public void onComplete(DatabaseError error, boolean committed, DataSnapshot snapshot) { - RNFirebaseTransactionHandler transactionHandler = transactionHandlers.get(transactionId); - WritableMap resultMap = transactionHandler.createResultMap(error, committed, snapshot); - Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", resultMap); - transactionHandlers.delete(transactionId); - } - - }, applyLocally); - } - }); - } - - /** - * Set a value on a ref when the client disconnects from the firebase server. - * - * @param appName - * @param path - * @param props - * @param promise - */ - @ReactMethod - public void onDisconnectSet( - String appName, - String dbURL, - String path, - ReadableMap props, - final Promise promise - ) { - String type = props.getString("type"); - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - - OnDisconnect onDisconnect = ref.onDisconnect(); - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - switch (type) { - case "object": - Map map = Utils.recursivelyDeconstructReadableMap(props.getMap("value")); - onDisconnect.setValue(map, listener); - break; - case "array": - List list = Utils.recursivelyDeconstructReadableArray(props.getArray("value")); - onDisconnect.setValue(list, listener); - break; - case "string": - onDisconnect.setValue(props.getString("value"), listener); - break; - case "number": - onDisconnect.setValue(props.getDouble("value"), listener); - break; - case "boolean": - onDisconnect.setValue(props.getBoolean("value"), listener); - break; - case "null": - onDisconnect.setValue(null, listener); - break; - } - } - - /** - * Update a value on a ref when the client disconnects from the firebase server. - * - * @param appName - * @param path - * @param props - * @param promise - */ - @ReactMethod - public void onDisconnectUpdate( - String appName, - String dbURL, - String path, - ReadableMap props, - final Promise promise - ) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - OnDisconnect ondDisconnect = ref.onDisconnect(); - - Map map = Utils.recursivelyDeconstructReadableMap(props); - - ondDisconnect.updateChildren(map, new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }); - } - - /** - * Remove a ref when the client disconnects from the firebase server. - * - * @param appName - * @param path - * @param promise - */ - @ReactMethod - public void onDisconnectRemove(String appName, String dbURL, String path, final Promise promise) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - OnDisconnect onDisconnect = ref.onDisconnect(); - - onDisconnect.removeValue(new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }); - } - - /** - * Cancel a pending onDisconnect action. - * - * @param appName - * @param path - * @param promise - */ - @ReactMethod - public void onDisconnectCancel(String appName, String dbURL, String path, final Promise promise) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - OnDisconnect onDisconnect = ref.onDisconnect(); - - onDisconnect.cancel(new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }); - } - - /** - * @param appName - * @param path - * @param props - * @param promise - */ - @ReactMethod - public void set( - String appName, - String dbURL, - String path, - ReadableMap props, - final Promise promise - ) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - Object value = Utils - .recursivelyDeconstructReadableMap(props) - .get("value"); - - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - ref.setValue(value, listener); - } - - /** - * @param appName - * @param path - * @param priority - * @param promise - */ - @ReactMethod - public void setPriority( - String appName, - String dbURL, - String path, - ReadableMap priority, - final Promise promise - ) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - Object priorityValue = Utils - .recursivelyDeconstructReadableMap(priority) - .get("value"); - - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - ref.setPriority(priorityValue, listener); - } - - /** - * @param appName - * @param path - * @param data - * @param priority - * @param promise - */ - @ReactMethod - public void setWithPriority( - String appName, - String dbURL, - String path, - ReadableMap data, - ReadableMap priority, - final Promise promise - ) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - Object dataValue = Utils - .recursivelyDeconstructReadableMap(data) - .get("value"); - Object priorityValue = Utils - .recursivelyDeconstructReadableMap(priority) - .get("value"); - - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - ref.setValue(dataValue, priorityValue, listener); - } - - /** - * @param appName - * @param path - * @param props - * @param promise - */ - @ReactMethod - public void update( - String appName, - String dbURL, - String path, - ReadableMap props, - final Promise promise - ) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - Map updates = Utils.recursivelyDeconstructReadableMap(props); - - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - ref.updateChildren(updates, listener); - } - - /** - * @param appName - * @param path - * @param promise - */ - @ReactMethod - public void remove(String appName, String dbURL, String path, final Promise promise) { - DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path); - - DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { - @Override - public void onComplete(DatabaseError error, DatabaseReference ref) { - handlePromise(promise, error); - } - }; - - ref.removeValue(listener); - } - - /* - * INTERNALS/UTILS - */ - - /** - * Subscribe once to a firebase reference. - * - * @param appName - * @param key - * @param path - * @param modifiers - * @param eventType - * @param promise - */ - @ReactMethod - public void once( - String appName, - String dbURL, - String key, - String path, - ReadableArray modifiers, - String eventType, - Promise promise - ) { - getInternalReferenceForApp(appName, dbURL, key, path, modifiers).once(eventType, promise); - } - - /** - * Subscribe to real time events for the specified database path + modifiers - * - * @param appName String - * @param props ReadableMap - */ - @ReactMethod - public void on(String appName, String dbURL, ReadableMap props) { - getCachedInternalReferenceForApp(appName, dbURL, props) - .on( - props.getString("eventType"), - props.getMap("registration") - ); - } - - /** - * Removes the specified event registration key. - * If the ref no longer has any listeners the the ref is removed. - * - * @param key - * @param eventRegistrationKey - */ - @ReactMethod - public void off(String key, String eventRegistrationKey) { - RNFirebaseDatabaseReference nativeRef = references.get(key); - if (nativeRef != null) { - nativeRef.removeEventListener(eventRegistrationKey); - - if (!nativeRef.hasListeners()) { - references.remove(key); - } - } - } - - /** - * Get a database reference for a specific app and path - * - * @param appName - * @param path - * @return - */ - private DatabaseReference getReferenceForAppPath(String appName, String dbURL, String path) { - return getDatabaseForApp(appName, dbURL).getReference(path); - } - - /** - * Return an existing or create a new RNFirebaseDatabaseReference instance. - * - * @param appName - * @param key - * @param path - * @param modifiers - * @return - */ - private RNFirebaseDatabaseReference getInternalReferenceForApp( - String appName, - String dbURL, - String key, - String path, - ReadableArray modifiers - ) { - return new RNFirebaseDatabaseReference( - appName, - dbURL, - key, - path, - modifiers - ); - } - - /** - * TODO - * - * @param appName - * @param props - * @return - */ - private RNFirebaseDatabaseReference getCachedInternalReferenceForApp( - String appName, - String dbURL, - ReadableMap props - ) { - String key = props.getString("key"); - String path = props.getString("path"); - ReadableArray modifiers = props.getArray("modifiers"); - - RNFirebaseDatabaseReference existingRef = references.get(key); - - if (existingRef == null) { - existingRef = getInternalReferenceForApp(appName, dbURL, key, path, modifiers); - references.put(key, existingRef); - } - - return existingRef; - } - - /** - * React Method - returns this module name - * - * @return - */ - @Override - public String getName() { - return "RNFirebaseDatabase"; - } - - /** - * React Native constants for RNFirebaseDatabase - * - * @return - */ - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - constants.put("serverValueTimestamp", ServerValue.TIMESTAMP); - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabasePackage.java b/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabasePackage.java deleted file mode 100644 index 1711e0da..00000000 --- a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabasePackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.database; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseDatabasePackage implements ReactPackage { - public RNFirebaseDatabasePackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseDatabase(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseReference.java b/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseReference.java deleted file mode 100644 index f3e660e1..00000000 --- a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseReference.java +++ /dev/null @@ -1,615 +0,0 @@ -package io.invertase.firebase.database; - -import android.annotation.SuppressLint; -import android.os.AsyncTask; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.database.ChildEventListener; -import com.google.firebase.database.DataSnapshot; -import com.google.firebase.database.DatabaseError; -import com.google.firebase.database.FirebaseDatabase; -import com.google.firebase.database.Query; -import com.google.firebase.database.ValueEventListener; - -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -class RNFirebaseDatabaseReference { - private static final String TAG = "RNFirebaseDBReference"; - private String key; - private Query query; - private String appName; - private String dbURL; - private HashMap childEventListeners = new HashMap<>(); - private HashMap valueEventListeners = new HashMap<>(); - - /** - * RNFirebase wrapper around FirebaseDatabaseReference, - * handles Query generation and event listeners. - * - * @param app - * @param refKey - * @param refPath - * @param modifiersArray - */ - RNFirebaseDatabaseReference( - String app, - String url, - String refKey, - String refPath, - ReadableArray modifiersArray - ) { - key = refKey; - query = null; - appName = app; - dbURL = url; - buildDatabaseQueryAtPathAndModifiers(refPath, modifiersArray); - } - - void removeAllEventListeners() { - if (hasListeners()) { - Iterator valueIterator = valueEventListeners.entrySet().iterator(); - - while (valueIterator.hasNext()) { - Map.Entry pair = (Map.Entry) valueIterator.next(); - ValueEventListener valueEventListener = (ValueEventListener) pair.getValue(); - query.removeEventListener(valueEventListener); - valueIterator.remove(); - } - - Iterator childIterator = childEventListeners.entrySet().iterator(); - - while (childIterator.hasNext()) { - Map.Entry pair = (Map.Entry) childIterator.next(); - ChildEventListener childEventListener = (ChildEventListener) pair.getValue(); - query.removeEventListener(childEventListener); - childIterator.remove(); - } - } - } - - - /** - * Used outside of class for keepSynced etc. - * - * @return Query - */ - Query getQuery() { - return query; - } - - /** - * Returns true/false whether this internal ref has a specific listener by eventRegistrationKey. - * - * @param eventRegistrationKey - * @return - */ - private Boolean hasEventListener(String eventRegistrationKey) { - return valueEventListeners.containsKey(eventRegistrationKey) || childEventListeners.containsKey( - eventRegistrationKey); - } - - /** - * Returns true/false whether this internal ref has any child or value listeners. - * - * @return - */ - Boolean hasListeners() { - return valueEventListeners.size() > 0 || childEventListeners.size() > 0; - } - - /** - * Remove an event listener by key, will remove either a ValueEventListener or - * a ChildEventListener - * - * @param eventRegistrationKey - */ - void removeEventListener(String eventRegistrationKey) { - if (valueEventListeners.containsKey(eventRegistrationKey)) { - query.removeEventListener(valueEventListeners.get(eventRegistrationKey)); - valueEventListeners.remove(eventRegistrationKey); - } - - if (childEventListeners.containsKey(eventRegistrationKey)) { - query.removeEventListener(childEventListeners.get(eventRegistrationKey)); - childEventListeners.remove(eventRegistrationKey); - } - } - - /** - * Add a ValueEventListener to the query and internally keep a reference to it. - * - * @param eventRegistrationKey - * @param listener - */ - private void addEventListener(String eventRegistrationKey, ValueEventListener listener) { - valueEventListeners.put(eventRegistrationKey, listener); - query.addValueEventListener(listener); - - } - - /** - * Add a ChildEventListener to the query and internally keep a reference to it. - * - * @param eventRegistrationKey - * @param listener - */ - private void addEventListener(String eventRegistrationKey, ChildEventListener listener) { - childEventListeners.put(eventRegistrationKey, listener); - query.addChildEventListener(listener); - - } - - /** - * Listen for a single .once('value',..) event from firebase. - * - * @param promise - */ - private void addOnceValueEventListener(final Promise promise) { - @SuppressLint("StaticFieldLeak") final DataSnapshotToMapAsyncTask asyncTask = new DataSnapshotToMapAsyncTask( - this - ) { - @Override - protected void onPostExecute(WritableMap writableMap) { - if (this.isAvailable()) promise.resolve(writableMap); - } - }; - - ValueEventListener onceValueEventListener = new ValueEventListener() { - @Override - public void onDataChange(@Nonnull DataSnapshot dataSnapshot) { - asyncTask.execute(dataSnapshot, null); - } - - @Override - public void onCancelled(@Nonnull DatabaseError error) { - RNFirebaseDatabase.handlePromise(promise, error); - } - }; - - query.addListenerForSingleValueEvent(onceValueEventListener); - Log.d(TAG, "Added OnceValueEventListener for key: " + key); - } - - /** - * Listen for single '.once(child_X, ...)' event from firebase. - * - * @param eventName - * @param promise - */ - private void addChildOnceEventListener(final String eventName, final Promise promise) { - ChildEventListener childEventListener = new ChildEventListener() { - @Override - public void onChildAdded(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_added".equals(eventName)) { - query.removeEventListener(this); - WritableMap data = RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName); - promise.resolve(data); - } - } - - @Override - public void onChildChanged(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_changed".equals(eventName)) { - query.removeEventListener(this); - WritableMap data = RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName); - promise.resolve(data); - } - } - - @Override - public void onChildRemoved(@Nonnull DataSnapshot dataSnapshot) { - if ("child_removed".equals(eventName)) { - query.removeEventListener(this); - WritableMap data = RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, null); - promise.resolve(data); - } - } - - @Override - public void onChildMoved(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_moved".equals(eventName)) { - query.removeEventListener(this); - WritableMap data = RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName); - promise.resolve(data); - } - } - - @Override - public void onCancelled(@Nonnull DatabaseError error) { - query.removeEventListener(this); - RNFirebaseDatabase.handlePromise(promise, error); - } - }; - - query.addChildEventListener(childEventListener); - } - - /** - * Handles a React Native JS '.on(..)' request and initializes listeners. - * - * @param registration - */ - void on(String eventType, ReadableMap registration) { - if (eventType.equals("value")) { - addValueEventListener(registration); - } else { - addChildEventListener(registration, eventType); - } - } - - /** - * Handles a React Native JS 'once' request. - * - * @param eventType - * @param promise - */ - void once(String eventType, Promise promise) { - if (eventType.equals("value")) { - addOnceValueEventListener(promise); - } else { - addChildOnceEventListener(eventType, promise); - } - } - - /** - * Add a native .on('child_X',.. ) event listener. - * - * @param registration - * @param eventType - */ - private void addChildEventListener(final ReadableMap registration, final String eventType) { - final String eventRegistrationKey = registration.getString("eventRegistrationKey"); - final String registrationCancellationKey = registration.getString("registrationCancellationKey"); - - if (!hasEventListener(eventRegistrationKey)) { - ChildEventListener childEventListener = new ChildEventListener() { - @Override - public void onChildAdded(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_added".equals(eventType)) { - handleDatabaseEvent("child_added", registration, dataSnapshot, previousChildName); - } - } - - @Override - public void onChildChanged(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_changed".equals(eventType)) { - handleDatabaseEvent("child_changed", registration, dataSnapshot, previousChildName); - } - } - - @Override - public void onChildRemoved(@Nonnull DataSnapshot dataSnapshot) { - if ("child_removed".equals(eventType)) { - handleDatabaseEvent("child_removed", registration, dataSnapshot, null); - } - } - - @Override - public void onChildMoved(@Nonnull DataSnapshot dataSnapshot, String previousChildName) { - if ("child_moved".equals(eventType)) { - handleDatabaseEvent("child_moved", registration, dataSnapshot, previousChildName); - } - } - - @Override - public void onCancelled(@Nonnull DatabaseError error) { - removeEventListener(eventRegistrationKey); - handleDatabaseError(registration, error); - } - }; - - addEventListener(eventRegistrationKey, childEventListener); - } - } - - /** - * Add a native .on('value',.. ) event listener. - * - * @param registration - */ - private void addValueEventListener(final ReadableMap registration) { - final String eventRegistrationKey = registration.getString("eventRegistrationKey"); - - if (!hasEventListener(eventRegistrationKey)) { - ValueEventListener valueEventListener = new ValueEventListener() { - @Override - public void onDataChange(@Nonnull DataSnapshot dataSnapshot) { - handleDatabaseEvent("value", registration, dataSnapshot, null); - } - - @Override - public void onCancelled(@Nonnull DatabaseError error) { - removeEventListener(eventRegistrationKey); - handleDatabaseError(registration, error); - } - }; - - addEventListener(eventRegistrationKey, valueEventListener); - } - } - - /** - * Handles value/child update events. - * - * @param eventType - * @param dataSnapshot - * @param previousChildName - */ - private void handleDatabaseEvent( - final String eventType, - final ReadableMap registration, - DataSnapshot dataSnapshot, - @Nullable String previousChildName - ) { - @SuppressLint("StaticFieldLeak") - DataSnapshotToMapAsyncTask asyncTask = new DataSnapshotToMapAsyncTask(this) { - @Override - protected void onPostExecute(WritableMap data) { - if (this.isAvailable()) { - WritableMap event = Arguments.createMap(); - event.putMap("data", data); - event.putString("key", key); - event.putString("eventType", eventType); - event.putMap("registration", Utils.readableMapToWritableMap(registration)); - Utils.sendEvent( - RNFirebaseDatabase.getReactApplicationContextInstance(), - "database_sync_event", - event - ); - } - } - }; - - asyncTask.execute(dataSnapshot, previousChildName); - } - - /** - * Handles a database listener cancellation error. - * - * @param error - */ - private void handleDatabaseError(ReadableMap registration, DatabaseError error) { - WritableMap event = Arguments.createMap(); - - event.putString("key", key); - event.putMap("error", RNFirebaseDatabase.getJSError(error)); - event.putMap("registration", Utils.readableMapToWritableMap(registration)); - - Utils.sendEvent( - RNFirebaseDatabase.getReactApplicationContextInstance(), - "database_sync_event", - event - ); - } - - /** - * @param path - * @param modifiers - * @return - */ - private void buildDatabaseQueryAtPathAndModifiers(String path, ReadableArray modifiers) { - FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName, dbURL); - query = firebaseDatabase.getReference(path); - List modifiersList = Utils.recursivelyDeconstructReadableArray(modifiers); - - for (Object m : modifiersList) { - Map modifier = (Map) m; - String type = (String) modifier.get("type"); - String name = (String) modifier.get("name"); - - if ("orderBy".equals(type)) { - applyOrderByModifier(name, type, modifier); - } else if ("limit".equals(type)) { - applyLimitModifier(name, type, modifier); - } else if ("filter".equals(type)) { - applyFilterModifier(name, modifier); - } - } - } - - /** - * @param name - * @param type - * @param modifier - */ - private void applyOrderByModifier(String name, String type, Map modifier) { - switch (name) { - case "orderByKey": - query = query.orderByKey(); - break; - case "orderByPriority": - query = query.orderByPriority(); - break; - case "orderByValue": - query = query.orderByValue(); - break; - case "orderByChild": - String key = (String) modifier.get("key"); - query = query.orderByChild(key); - } - } - - /* ================= - * QUERY MODIFIERS - * ================= - */ - - /** - * @param name - * @param type - * @param modifier - */ - private void applyLimitModifier(String name, String type, Map modifier) { - int limit = ((Double) modifier.get("limit")).intValue(); - if ("limitToLast".equals(name)) { - query = query.limitToLast(limit); - } else if ("limitToFirst".equals(name)) { - query = query.limitToFirst(limit); - } - } - - /** - * @param name - * @param modifier - */ - private void applyFilterModifier(String name, Map modifier) { - String valueType = (String) modifier.get("valueType"); - String key = (String) modifier.get("key"); - if ("equalTo".equals(name)) { - applyEqualToFilter(key, valueType, modifier); - } else if ("endAt".equals(name)) { - applyEndAtFilter(key, valueType, modifier); - } else if ("startAt".equals(name)) { - applyStartAtFilter(key, valueType, modifier); - } - } - - /** - * @param key - * @param valueType - * @param modifier - */ - private void applyEqualToFilter(String key, String valueType, Map modifier) { - if ("number".equals(valueType)) { - double value = (Double) modifier.get("value"); - if (key == null) { - query = query.equalTo(value); - } else { - query = query.equalTo(value, key); - } - } else if ("boolean".equals(valueType)) { - boolean value = (Boolean) modifier.get("value"); - if (key == null) { - query = query.equalTo(value); - } else { - query = query.equalTo(value, key); - } - } else if ("string".equals(valueType)) { - String value = (String) modifier.get("value"); - if (key == null) { - query = query.equalTo(value); - } else { - query = query.equalTo(value, key); - } - } - } - - - /* =============== - * QUERY FILTERS - * =============== - */ - - /** - * @param key - * @param valueType - * @param modifier - */ - private void applyEndAtFilter(String key, String valueType, Map modifier) { - if ("number".equals(valueType)) { - double value = (Double) modifier.get("value"); - if (key == null) { - query = query.endAt(value); - } else { - query = query.endAt(value, key); - } - } else if ("boolean".equals(valueType)) { - boolean value = (Boolean) modifier.get("value"); - if (key == null) { - query = query.endAt(value); - } else { - query = query.endAt(value, key); - } - } else if ("string".equals(valueType)) { - String value = (String) modifier.get("value"); - if (key == null) { - query = query.endAt(value); - } else { - query = query.endAt(value, key); - } - } - } - - /** - * @param key - * @param valueType - * @param modifier - */ - private void applyStartAtFilter(String key, String valueType, Map modifier) { - if ("number".equals(valueType)) { - double value = (Double) modifier.get("value"); - if (key == null) { - query = query.startAt(value); - } else { - query = query.startAt(value, key); - } - } else if ("boolean".equals(valueType)) { - boolean value = (Boolean) modifier.get("value"); - if (key == null) { - query = query.startAt(value); - } else { - query = query.startAt(value, key); - } - } else if ("string".equals(valueType)) { - String value = (String) modifier.get("value"); - if (key == null) { - query = query.startAt(value); - } else { - query = query.startAt(value, key); - } - } - } - - /** - * AsyncTask to convert DataSnapshot instances to WritableMap instances. - *

- * Introduced due to https://github.com/invertase/react-native-firebase/issues/1284 - */ - private static class DataSnapshotToMapAsyncTask extends AsyncTask { - private WeakReference referenceWeakReference; - - DataSnapshotToMapAsyncTask(RNFirebaseDatabaseReference reference) { - referenceWeakReference = new WeakReference<>(reference); - } - - @Override - protected final WritableMap doInBackground(Object... params) { - DataSnapshot dataSnapshot = (DataSnapshot) params[0]; - @Nullable String previousChildName = (String) params[1]; - - try { - return RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName); - } catch (RuntimeException e) { - if (isAvailable()) { - RNFirebaseDatabase.getReactApplicationContextInstance() - .handleException(e); - } - throw e; - } - } - - @Override - protected void onPostExecute(WritableMap writableMap) { - // do nothing as overridden on usage - } - - Boolean isAvailable() { - return RNFirebaseDatabase.getReactApplicationContextInstance() != null && referenceWeakReference.get() != null; - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseUtils.java b/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseUtils.java deleted file mode 100644 index c1fb5a18..00000000 --- a/android/src/main/java/io/invertase/firebase/database/RNFirebaseDatabaseUtils.java +++ /dev/null @@ -1,396 +0,0 @@ -package io.invertase.firebase.database; - -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; -import com.google.firebase.database.DataSnapshot; -import com.google.firebase.database.MutableData; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -public class RNFirebaseDatabaseUtils { - private static final String TAG = "RNFirebaseDatabaseUtils"; - - /** - * @param dataSnapshot - * @param previousChildName - * @return - */ - public static WritableMap snapshotToMap( - DataSnapshot dataSnapshot, - @Nullable String previousChildName - ) { - WritableMap result = Arguments.createMap(); - WritableMap snapshot = snapshotToMap(dataSnapshot); - - result.putMap("snapshot", snapshot); - result.putString("previousChildName", previousChildName); - return result; - } - - /** - * @param dataSnapshot - * @return - */ - public static WritableMap snapshotToMap(DataSnapshot dataSnapshot) { - WritableMap snapshot = Arguments.createMap(); - - snapshot.putString("key", dataSnapshot.getKey()); - snapshot.putBoolean("exists", dataSnapshot.exists()); - snapshot.putBoolean("hasChildren", dataSnapshot.hasChildren()); - snapshot.putDouble("childrenCount", dataSnapshot.getChildrenCount()); - snapshot.putArray("childKeys", getChildKeys(dataSnapshot)); - Utils.mapPutValue("priority", dataSnapshot.getPriority(), snapshot); - - if (!dataSnapshot.hasChildren()) { - Utils.mapPutValue("value", dataSnapshot.getValue(), snapshot); - } else { - Object value = castValue(dataSnapshot); - if (value instanceof WritableNativeArray) { - snapshot.putArray("value", (WritableArray) value); - } else { - snapshot.putMap("value", (WritableMap) value); - } - } - - return snapshot; - } - - /** - * @param snapshot - * @param - * @return - */ - public static Any castValue(DataSnapshot snapshot) { - if (snapshot.hasChildren()) { - if (isArray(snapshot)) { - return (Any) buildArray(snapshot); - } else { - return (Any) buildMap(snapshot); - } - } else { - if (snapshot.getValue() != null) { - String type = snapshot - .getValue() - .getClass() - .getName(); - switch (type) { - case "java.lang.Boolean": - case "java.lang.Long": - case "java.lang.Double": - case "java.lang.String": - return (Any) (snapshot.getValue()); - default: - Log.w(TAG, "Invalid type: " + type); - return null; - } - } - return null; - } - } - - /** - * @param mutableData - * @param - * @return - */ - public static Any castValue(MutableData mutableData) { - if (mutableData.hasChildren()) { - if (isArray(mutableData)) { - return (Any) buildArray(mutableData); - } else { - return (Any) buildMap(mutableData); - } - } else { - if (mutableData.getValue() != null) { - String type = mutableData - .getValue() - .getClass() - .getName(); - switch (type) { - case "java.lang.Boolean": - case "java.lang.Long": - case "java.lang.Double": - case "java.lang.String": - return (Any) (mutableData.getValue()); - default: - Log.w(TAG, "Invalid type: " + type); - return null; - } - } - return null; - } - } - - /** - * Data should be treated as an array if: - * 1) All the keys are integers - * 2) More than half the keys between 0 and the maximum key in the object have non-empty values - *

- * Definition from: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html - * - * @param snapshot - * @return - */ - private static boolean isArray(DataSnapshot snapshot) { - long expectedKey = -1; - long maxAllowedKey = (snapshot.getChildrenCount() * 2) - 1; - for (DataSnapshot child : snapshot.getChildren()) { - try { - long key = Long.parseLong(child.getKey()); - if (key > expectedKey && key <= maxAllowedKey) { - expectedKey = key; - } else { - return false; - } - } catch (NumberFormatException ex) { - return false; - } - } - return true; - } - - /** - * Data should be treated as an array if: - * 1) All the keys are integers - * 2) More than half the keys between 0 and the maximum key in the object have non-empty values - *

- * Definition from: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html - * - * @param mutableData - * @return - */ - private static boolean isArray(MutableData mutableData) { - long expectedKey = -1; - long maxAllowedKey = (mutableData.getChildrenCount() * 2) - 1; - for (MutableData child : mutableData.getChildren()) { - try { - long key = Long.parseLong(child.getKey()); - if (key > expectedKey && key <= maxAllowedKey) { - expectedKey++; - } else { - return false; - } - } catch (NumberFormatException ex) { - return false; - } - } - return true; - } - - /** - * @param snapshot - * @param - * @return - */ - private static WritableArray buildArray(DataSnapshot snapshot) { - long expectedKey = 0; - WritableArray array = Arguments.createArray(); - for (DataSnapshot child : snapshot.getChildren()) { - long key = Long.parseLong(child.getKey()); - if (key > expectedKey) { - for (long i = expectedKey; i < key; i++) { - array.pushNull(); - } - expectedKey = key; - } - Any castedChild = castValue(child); - switch (castedChild - .getClass() - .getName()) { - case "java.lang.Boolean": - array.pushBoolean((Boolean) castedChild); - break; - case "java.lang.Long": - Long longVal = (Long) castedChild; - array.pushDouble((double) longVal); - break; - case "java.lang.Double": - array.pushDouble((Double) castedChild); - break; - case "java.lang.String": - array.pushString((String) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeMap": - array.pushMap((WritableMap) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeArray": - array.pushArray((WritableArray) castedChild); - break; - default: - Log.w( - TAG, - "Invalid type: " + castedChild - .getClass() - .getName() - ); - break; - } - expectedKey++; - } - return array; - } - - /** - * @param mutableData - * @param - * @return - */ - private static WritableArray buildArray(MutableData mutableData) { - long expectedKey = 0; - WritableArray array = Arguments.createArray(); - for (MutableData child : mutableData.getChildren()) { - long key = Long.parseLong(child.getKey()); - if (key > expectedKey) { - for (long i = expectedKey; i < key; i++) { - array.pushNull(); - } - expectedKey = key; - } - Any castedChild = castValue(child); - switch (castedChild - .getClass() - .getName()) { - case "java.lang.Boolean": - array.pushBoolean((Boolean) castedChild); - break; - case "java.lang.Long": - Long longVal = (Long) castedChild; - array.pushDouble((double) longVal); - break; - case "java.lang.Double": - array.pushDouble((Double) castedChild); - break; - case "java.lang.String": - array.pushString((String) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeMap": - array.pushMap((WritableMap) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeArray": - array.pushArray((WritableArray) castedChild); - break; - default: - Log.w( - TAG, - "Invalid type: " + castedChild - .getClass() - .getName() - ); - break; - } - expectedKey++; - } - return array; - } - - /** - * @param snapshot - * @param - * @return - */ - private static WritableMap buildMap(DataSnapshot snapshot) { - WritableMap map = Arguments.createMap(); - for (DataSnapshot child : snapshot.getChildren()) { - Any castedChild = castValue(child); - - switch (castedChild - .getClass() - .getName()) { - case "java.lang.Boolean": - map.putBoolean(child.getKey(), (Boolean) castedChild); - break; - case "java.lang.Long": - map.putDouble(child.getKey(), (double) ((Long) castedChild)); - break; - case "java.lang.Double": - map.putDouble(child.getKey(), (Double) castedChild); - break; - case "java.lang.String": - map.putString(child.getKey(), (String) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeMap": - map.putMap(child.getKey(), (WritableMap) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeArray": - map.putArray(child.getKey(), (WritableArray) castedChild); - break; - default: - Log.w( - TAG, - "Invalid type: " + castedChild - .getClass() - .getName() - ); - break; - } - } - return map; - } - - /** - * @param mutableData - * @param - * @return - */ - private static WritableMap buildMap(MutableData mutableData) { - WritableMap map = Arguments.createMap(); - for (MutableData child : mutableData.getChildren()) { - Any castedChild = castValue(child); - - switch (castedChild - .getClass() - .getName()) { - case "java.lang.Boolean": - map.putBoolean(child.getKey(), (Boolean) castedChild); - break; - case "java.lang.Long": - map.putDouble(child.getKey(), (double) ((Long) castedChild)); - break; - case "java.lang.Double": - map.putDouble(child.getKey(), (Double) castedChild); - break; - case "java.lang.String": - map.putString(child.getKey(), (String) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeMap": - map.putMap(child.getKey(), (WritableMap) castedChild); - break; - case "com.facebook.react.bridge.WritableNativeArray": - map.putArray(child.getKey(), (WritableArray) castedChild); - break; - default: - Log.w( - TAG, - "Invalid type: " + castedChild - .getClass() - .getName() - ); - break; - } - } - return map; - } - - /** - * @param snapshot - * @return - */ - public static WritableArray getChildKeys(DataSnapshot snapshot) { - WritableArray childKeys = Arguments.createArray(); - - if (snapshot.hasChildren()) { - for (DataSnapshot child : snapshot.getChildren()) { - childKeys.pushString(child.getKey()); - } - } - - return childKeys; - } - -} diff --git a/android/src/main/java/io/invertase/firebase/database/RNFirebaseTransactionHandler.java b/android/src/main/java/io/invertase/firebase/database/RNFirebaseTransactionHandler.java deleted file mode 100644 index cfae155d..00000000 --- a/android/src/main/java/io/invertase/firebase/database/RNFirebaseTransactionHandler.java +++ /dev/null @@ -1,164 +0,0 @@ -package io.invertase.firebase.database; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; -import com.google.firebase.database.DataSnapshot; -import com.google.firebase.database.DatabaseError; -import com.google.firebase.database.MutableData; - -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -public class RNFirebaseTransactionHandler { - private final ReentrantLock lock; - private final Condition condition; - public Object value; - boolean interrupted; - boolean abort = false; - boolean timeout = false; - private int transactionId; - private String appName; - private String dbURL; - private Map data; - private boolean signalled; - - RNFirebaseTransactionHandler(int id, String app, String url) { - appName = app; - dbURL = url; - transactionId = id; - lock = new ReentrantLock(); - condition = lock.newCondition(); - } - - /** - * Signal that the transaction data has been received - * - * @param updates - */ - void signalUpdateReceived(ReadableMap updates) { - Map updateData = Utils.recursivelyDeconstructReadableMap(updates); - - lock.lock(); - value = updateData.get("value"); - abort = (Boolean) updateData.get("abort"); - - try { - if (signalled) { - throw new IllegalStateException("This transactionUpdateHandler has already been signalled."); - } - - signalled = true; - data = updateData; - condition.signalAll(); - } finally { - lock.unlock(); - } - } - - /** - * Wait for signalUpdateReceived to signal condition - * - * @throws InterruptedException - */ - void await() throws InterruptedException { - lock.lock(); - signalled = false; - - long timeoutExpired = System.currentTimeMillis() + 5000; - - try { - while (!timeout && !condition.await(250, TimeUnit.MILLISECONDS) && !signalled) { - if (!signalled && System.currentTimeMillis() > timeoutExpired) { - timeout = true; - } - } - } finally { - lock.unlock(); - } - } - - /** - * Get the - * - * @return - */ - Map getUpdates() { - return data; - } - - /** - * Create a RN map of transaction mutable data for sending to js - * - * @param updatesData - * @return - */ - WritableMap createUpdateMap(MutableData updatesData) { - final WritableMap updatesMap = Arguments.createMap(); - - updatesMap.putInt("id", transactionId); - updatesMap.putString("type", "update"); - - // all events get distributed js side based on app name - updatesMap.putString("appName", appName); - updatesMap.putString("dbURL", dbURL); - - if (!updatesData.hasChildren()) { - Utils.mapPutValue("value", updatesData.getValue(), updatesMap); - } else { - Object value = RNFirebaseDatabaseUtils.castValue(updatesData); - - if (value instanceof WritableNativeArray) { - updatesMap.putArray("value", (WritableArray) value); - } else { - updatesMap.putMap("value", (WritableMap) value); - } - } - - return updatesMap; - } - - - WritableMap createResultMap( - @Nullable DatabaseError error, - boolean committed, - DataSnapshot snapshot - ) { - WritableMap resultMap = Arguments.createMap(); - - resultMap.putInt("id", transactionId); - resultMap.putString("appName", appName); - resultMap.putString("dbURL", dbURL); - - resultMap.putBoolean("timeout", timeout); - resultMap.putBoolean("committed", committed); - resultMap.putBoolean("interrupted", interrupted); - - if (error != null || timeout || interrupted) { - resultMap.putString("type", "error"); - if (error != null) resultMap.putMap("error", RNFirebaseDatabase.getJSError(error)); - if (error == null && timeout) { - WritableMap timeoutError = Arguments.createMap(); - timeoutError.putString("code", "DATABASE/INTERNAL-TIMEOUT"); - timeoutError.putString( - "message", - "A timeout occurred whilst waiting for RN JS thread to send transaction updates." - ); - resultMap.putMap("error", timeoutError); - } - } else { - resultMap.putString("type", "complete"); - resultMap.putMap("snapshot", RNFirebaseDatabaseUtils.snapshotToMap(snapshot)); - } - - return resultMap; - } -} diff --git a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java deleted file mode 100644 index c4902c2d..00000000 --- a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlytics.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.invertase.firebase.fabric.crashlytics; - -import android.util.Log; - -import com.crashlytics.android.Crashlytics; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; - -import io.fabric.sdk.android.Fabric; - -public class RNFirebaseCrashlytics extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseCrashlytics"; - - public RNFirebaseCrashlytics(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void crash() { - Crashlytics - .getInstance() - .crash(); - } - - @ReactMethod - public void log(final String message) { - Crashlytics.log(message); - } - - @ReactMethod - public void recordError(final int code, final String domain) { - Crashlytics.logException(new Exception(code + ": " + domain)); - } - - @ReactMethod - public void setBoolValue(final String key, final boolean boolValue) { - Crashlytics.setBool(key, boolValue); - } - - @ReactMethod - public void setFloatValue(final String key, final float floatValue) { - Crashlytics.setFloat(key, floatValue); - } - - @ReactMethod - public void setIntValue(final String key, final int intValue) { - Crashlytics.setInt(key, intValue); - } - - @ReactMethod - public void setStringValue(final String key, final String stringValue) { - Crashlytics.setString(key, stringValue); - } - - @ReactMethod - public void setUserIdentifier(String userId) { - Crashlytics.setUserIdentifier(userId); - } - - @ReactMethod - public void enableCrashlyticsCollection() { - Fabric.with(getReactApplicationContext(), new Crashlytics()); - } - -} diff --git a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java b/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java deleted file mode 100644 index 44f31e37..00000000 --- a/android/src/main/java/io/invertase/firebase/fabric/crashlytics/RNFirebaseCrashlyticsPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.fabric.crashlytics; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseCrashlyticsPackage implements ReactPackage { - public RNFirebaseCrashlyticsPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseCrashlytics(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/DocumentSnapshotSerializeAsyncTask.java b/android/src/main/java/io/invertase/firebase/firestore/DocumentSnapshotSerializeAsyncTask.java deleted file mode 100644 index 520ed6b4..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/DocumentSnapshotSerializeAsyncTask.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.invertase.firebase.firestore; - -import android.os.AsyncTask; - -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.firestore.DocumentSnapshot; - -import java.lang.ref.WeakReference; - -class DocumentSnapshotSerializeAsyncTask extends AsyncTask { - private WeakReference reactContextWeakReference; - private WeakReference referenceWeakReference; - - DocumentSnapshotSerializeAsyncTask( - ReactContext context, - RNFirebaseFirestoreDocumentReference reference - ) { - referenceWeakReference = new WeakReference<>(reference); - reactContextWeakReference = new WeakReference<>(context); - } - - @Override - protected final WritableMap doInBackground(Object... params) { - DocumentSnapshot querySnapshot = (DocumentSnapshot) params[0]; - - try { - return FirestoreSerialize.snapshotToWritableMap(querySnapshot); - } catch (RuntimeException e) { - if (isAvailable()) { - reactContextWeakReference - .get() - .handleException(e); - } else { - throw e; - } - return null; - } - } - - @Override - protected void onPostExecute(WritableMap writableMap) { - // do nothing as overridden on usage - } - - private Boolean isAvailable() { - return reactContextWeakReference.get() != null && referenceWeakReference.get() != null; - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java deleted file mode 100644 index 68604504..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ /dev/null @@ -1,518 +0,0 @@ -package io.invertase.firebase.firestore; - -import android.util.Base64; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableMapKeySetIterator; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.firestore.Blob; -import com.google.firebase.firestore.DocumentChange; -import com.google.firebase.firestore.DocumentReference; -import com.google.firebase.firestore.DocumentSnapshot; -import com.google.firebase.firestore.FieldPath; -import com.google.firebase.firestore.FieldValue; -import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.GeoPoint; -import com.google.firebase.firestore.QuerySnapshot; -import com.google.firebase.firestore.SnapshotMetadata; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -class FirestoreSerialize { - private static final String TAG = "FirestoreSerialize"; - - // Keys - private static final String TYPE = "type"; - private static final String VALUE = "value"; - private static final String KEY_DATA = "data"; - private static final String KEY_PATH = "path"; - private static final String KEY_META = "metadata"; - private static final String KEY_CHANGES = "changes"; - private static final String KEY_OPTIONS = "options"; - private static final String KEY_LATITUDE = "latitude"; - private static final String KEY_LONGITUDE = "longitude"; - private static final String KEY_DOCUMENTS = "documents"; - private static final String KEY_DOC_CHANGE_TYPE = "type"; - private static final String KEY_META_FROM_CACHE = "fromCache"; - private static final String KEY_DOC_CHANGE_DOCUMENT = "document"; - private static final String KEY_DOC_CHANGE_NEW_INDEX = "newIndex"; - private static final String KEY_DOC_CHANGE_OLD_INDEX = "oldIndex"; - private static final String KEY_META_HAS_PENDING_WRITES = "hasPendingWrites"; - - // Types - private static final String TYPE_NAN = "nan"; - private static final String TYPE_NULL = "null"; - private static final String TYPE_BLOB = "blob"; - private static final String TYPE_DATE = "date"; - private static final String TYPE_ARRAY = "array"; - private static final String TYPE_STRING = "string"; - private static final String TYPE_NUMBER = "number"; - private static final String TYPE_OBJECT = "object"; - private static final String TYPE_BOOLEAN = "boolean"; - private static final String TYPE_GEOPOINT = "geopoint"; - private static final String TYPE_INFINITY = "infinity"; - private static final String TYPE_REFERENCE = "reference"; - private static final String TYPE_DOCUMENTID = "documentid"; - private static final String TYPE_FIELDVALUE = "fieldvalue"; - private static final String TYPE_FIELDVALUE_DELETE = "delete"; - private static final String TYPE_FIELDVALUE_TIMESTAMP = "timestamp"; - private static final String TYPE_FIELDVALUE_UNION = "union"; - private static final String TYPE_FIELDVALUE_REMOVE = "remove"; - private static final String TYPE_FIELDVALUE_TYPE = "type"; - private static final String TYPE_FIELDVALUE_ELEMENTS = "elements"; - - // Document Change Types - private static final String CHANGE_ADDED = "added"; - private static final String CHANGE_MODIFIED = "modified"; - private static final String CHANGE_REMOVED = "removed"; - - /** - * Convert a DocumentSnapshot instance into a React Native WritableMap - * - * @param documentSnapshot DocumentSnapshot - * @return WritableMap - */ - static WritableMap snapshotToWritableMap(DocumentSnapshot documentSnapshot) { - WritableMap metadata = Arguments.createMap(); - WritableMap documentMap = Arguments.createMap(); - SnapshotMetadata snapshotMetadata = documentSnapshot.getMetadata(); - - // build metadata - metadata.putBoolean(KEY_META_FROM_CACHE, snapshotMetadata.isFromCache()); - metadata.putBoolean(KEY_META_HAS_PENDING_WRITES, snapshotMetadata.hasPendingWrites()); - - documentMap.putMap(KEY_META, metadata); - documentMap.putString(KEY_PATH, documentSnapshot.getReference().getPath()); - if (documentSnapshot.exists()) - documentMap.putMap(KEY_DATA, objectMapToWritable(documentSnapshot.getData())); - - return documentMap; - } - - /** - * Convert a Firestore QuerySnapshot instance to a RN serializable WritableMap type map - * - * @param querySnapshot QuerySnapshot - * @return WritableMap - */ - static WritableMap snapshotToWritableMap(QuerySnapshot querySnapshot) { - WritableMap metadata = Arguments.createMap(); - WritableMap writableMap = Arguments.createMap(); - WritableArray documents = Arguments.createArray(); - - SnapshotMetadata snapshotMetadata = querySnapshot.getMetadata(); - List documentSnapshots = querySnapshot.getDocuments(); - List documentChanges = querySnapshot.getDocumentChanges(); - - // convert documents documents - for (DocumentSnapshot documentSnapshot : documentSnapshots) { - documents.pushMap(snapshotToWritableMap(documentSnapshot)); - } - - // build metadata - metadata.putBoolean(KEY_META_FROM_CACHE, snapshotMetadata.isFromCache()); - metadata.putBoolean(KEY_META_HAS_PENDING_WRITES, snapshotMetadata.hasPendingWrites()); - - // set metadata - writableMap.putMap(KEY_META, metadata); - - // set documents - writableMap.putArray(KEY_DOCUMENTS, documents); - - // set document changes - writableMap.putArray( - KEY_CHANGES, - documentChangesToWritableArray(documentChanges) - ); - - return writableMap; - } - - /** - * Convert a List of DocumentChange instances into a React Native WritableArray - * - * @param documentChanges List - * @return WritableArray - */ - private static WritableArray documentChangesToWritableArray(List documentChanges) { - WritableArray documentChangesWritable = Arguments.createArray(); - - for (DocumentChange documentChange : documentChanges) { - documentChangesWritable.pushMap(documentChangeToWritableMap(documentChange)); - } - - return documentChangesWritable; - } - - /** - * Convert a DocumentChange instance into a React Native WritableMap - * - * @param documentChange DocumentChange - * @return WritableMap - */ - private static WritableMap documentChangeToWritableMap(DocumentChange documentChange) { - WritableMap documentChangeMap = Arguments.createMap(); - - switch (documentChange.getType()) { - case ADDED: - documentChangeMap.putString(KEY_DOC_CHANGE_TYPE, CHANGE_ADDED); - break; - case MODIFIED: - documentChangeMap.putString(KEY_DOC_CHANGE_TYPE, CHANGE_MODIFIED); - break; - case REMOVED: - documentChangeMap.putString(KEY_DOC_CHANGE_TYPE, CHANGE_REMOVED); - break; - } - - documentChangeMap.putMap( - KEY_DOC_CHANGE_DOCUMENT, - snapshotToWritableMap(documentChange.getDocument()) - ); - - documentChangeMap.putInt(KEY_DOC_CHANGE_NEW_INDEX, documentChange.getNewIndex()); - documentChangeMap.putInt(KEY_DOC_CHANGE_OLD_INDEX, documentChange.getOldIndex()); - - return documentChangeMap; - } - - /** - * Converts an Object Map into a React Native WritableMap. - * - * @param map Map - * @return WritableMap - */ - private static WritableMap objectMapToWritable(Map map) { - WritableMap writableMap = Arguments.createMap(); - - for (Map.Entry entry : map.entrySet()) { - WritableMap typeMap = buildTypeMap(entry.getValue()); - writableMap.putMap(entry.getKey(), typeMap); - } - - return writableMap; - } - - /** - * Converts a Object array into a React Native WritableArray. - * - * @param array Object[] - * @return WritableArray - */ - private static WritableArray objectArrayToWritable(Object[] array) { - WritableArray writableArray = Arguments.createArray(); - - for (Object item : array) { - WritableMap typeMap = buildTypeMap(item); - writableArray.pushMap(typeMap); - } - - return writableArray; - } - - /** - * Convert an Object to a type map for use in JS land to convert to JS equivalent. - * - * @param value Object - * @return WritableMap - */ - private static WritableMap buildTypeMap(Object value) { - WritableMap typeMap = Arguments.createMap(); - - if (value == null) { - typeMap.putString(TYPE, TYPE_NULL); - typeMap.putNull(VALUE); - return typeMap; - } - - if (value instanceof Boolean) { - typeMap.putString(TYPE, TYPE_BOOLEAN); - typeMap.putBoolean(VALUE, (Boolean) value); - return typeMap; - } - - if (value instanceof Integer) { - typeMap.putString(TYPE, TYPE_NUMBER); - typeMap.putDouble(VALUE, ((Integer) value).doubleValue()); - return typeMap; - } - - if (value instanceof Double) { - Double doubleValue = (Double) value; - - if (Double.isInfinite(doubleValue)) { - typeMap.putString(TYPE, TYPE_INFINITY); - return typeMap; - } - - if (Double.isNaN(doubleValue)) { - typeMap.putString(TYPE, TYPE_NAN); - return typeMap; - } - - typeMap.putString(TYPE, TYPE_NUMBER); - typeMap.putDouble(VALUE, doubleValue); - return typeMap; - } - - if (value instanceof Float) { - typeMap.putString(TYPE, TYPE_NUMBER); - typeMap.putDouble(VALUE, ((Float) value).doubleValue()); - return typeMap; - } - - if (value instanceof Long) { - typeMap.putString(TYPE, TYPE_NUMBER); - typeMap.putDouble(VALUE, ((Long) value).doubleValue()); - return typeMap; - } - - if (value instanceof String) { - typeMap.putString(TYPE, TYPE_STRING); - typeMap.putString(VALUE, (String) value); - return typeMap; - } - - if (value instanceof Date) { - typeMap.putString(TYPE, TYPE_DATE); - typeMap.putDouble(VALUE, ((Date) value).getTime()); - return typeMap; - } - - if (Map.class.isAssignableFrom(value.getClass())) { - typeMap.putString(TYPE, TYPE_OBJECT); - typeMap.putMap(VALUE, objectMapToWritable((Map) value)); - return typeMap; - } - - if (List.class.isAssignableFrom(value.getClass())) { - typeMap.putString(TYPE, TYPE_ARRAY); - List list = (List) value; - Object[] array = list.toArray(new Object[list.size()]); - typeMap.putArray(VALUE, objectArrayToWritable(array)); - return typeMap; - } - - if (value instanceof DocumentReference) { - typeMap.putString(TYPE, TYPE_REFERENCE); - typeMap.putString(VALUE, ((DocumentReference) value).getPath()); - return typeMap; - } - - if (value instanceof GeoPoint) { - WritableMap geoPoint = Arguments.createMap(); - - geoPoint.putDouble(KEY_LATITUDE, ((GeoPoint) value).getLatitude()); - geoPoint.putDouble(KEY_LONGITUDE, ((GeoPoint) value).getLongitude()); - - typeMap.putMap(VALUE, geoPoint); - typeMap.putString(TYPE, TYPE_GEOPOINT); - - return typeMap; - } - - if (value instanceof Blob) { - typeMap.putString(TYPE, TYPE_BLOB); - typeMap.putString(VALUE, Base64.encodeToString(((Blob) value).toBytes(), Base64.NO_WRAP)); - return typeMap; - } - - Log.w(TAG, "Unknown object of type " + value.getClass()); - typeMap.putString(TYPE, TYPE_NULL); - typeMap.putNull(VALUE); - return typeMap; - } - - /** - * Converts a ReadableMap to a usable format for Firestore - * - * @param firestore FirebaseFirestore - * @param readableMap ReadableMap - * @return Map<> - */ - static Map parseReadableMap( - FirebaseFirestore firestore, - @Nullable ReadableMap readableMap - ) { - Map map = new HashMap<>(); - if (readableMap == null) return map; - - ReadableMapKeySetIterator iterator = readableMap.keySetIterator(); - while (iterator.hasNextKey()) { - String key = iterator.nextKey(); - map.put(key, parseTypeMap(firestore, readableMap.getMap(key))); - } - - return map; - } - - /** - * Convert a RN array to a valid Firestore array - * - * @param firestore FirebaseFirestore - * @param readableArray ReadableArray - * @return List - */ - static List parseReadableArray( - FirebaseFirestore firestore, - @Nullable ReadableArray readableArray - ) { - List list = new ArrayList<>(); - if (readableArray == null) return list; - - for (int i = 0; i < readableArray.size(); i++) { - list.add(parseTypeMap(firestore, readableArray.getMap(i))); - } - - return list; - } - - /** - * Convert a JS type to a Firestore type - * - * @param firestore FirebaseFirestore - * @param typeMap ReadableMap - * @return Object - */ - static Object parseTypeMap(FirebaseFirestore firestore, ReadableMap typeMap) { - String type = typeMap.getString(TYPE); - - if (TYPE_NULL.equals(type)) { - return null; - } - - if (TYPE_BOOLEAN.equals(type)) { - return typeMap.getBoolean(VALUE); - } - - if (TYPE_NAN.equals(type)) { - return Double.NaN; - } - - if (TYPE_NUMBER.equals(type)) { - return typeMap.getDouble(VALUE); - } - - if (TYPE_INFINITY.equals(type)) { - return Double.POSITIVE_INFINITY; - } - - if (TYPE_STRING.equals(type)) { - return typeMap.getString(VALUE); - } - - if (TYPE_ARRAY.equals(type)) { - return parseReadableArray(firestore, typeMap.getArray(VALUE)); - } - - if (TYPE_OBJECT.equals(type)) { - return parseReadableMap(firestore, typeMap.getMap(VALUE)); - } - - if (TYPE_DATE.equals(type)) { - Double time = typeMap.getDouble(VALUE); - return new Date(time.longValue()); - } - - /* -------------------------- - * Firestore Specific Types - * -------------------------- */ - - if (TYPE_DOCUMENTID.equals(type)) { - return FieldPath.documentId(); - } - - if (TYPE_GEOPOINT.equals(type)) { - ReadableMap geoPoint = typeMap.getMap(VALUE); - return new GeoPoint(geoPoint.getDouble(KEY_LATITUDE), geoPoint.getDouble(KEY_LONGITUDE)); - } - - if (TYPE_BLOB.equals(type)) { - String base64String = typeMap.getString(VALUE); - return Blob.fromBytes(Base64.decode(base64String, Base64.NO_WRAP)); - } - - if (TYPE_REFERENCE.equals(type)) { - String path = typeMap.getString(VALUE); - return firestore.document(path); - } - - if (TYPE_FIELDVALUE.equals(type)) { - ReadableMap fieldValueMap = typeMap.getMap(VALUE); - String fieldValueType = fieldValueMap.getString(TYPE_FIELDVALUE_TYPE); - - if (TYPE_FIELDVALUE_TIMESTAMP.equals(fieldValueType)) { - return FieldValue.serverTimestamp(); - } - - if (TYPE_FIELDVALUE_DELETE.equals(fieldValueType)) { - return FieldValue.delete(); - } - - if (TYPE_FIELDVALUE_UNION.equals(fieldValueType)) { - ReadableArray elements = fieldValueMap.getArray(TYPE_FIELDVALUE_ELEMENTS); - return FieldValue.arrayUnion(parseReadableArray(firestore, elements).toArray()); - } - - if (TYPE_FIELDVALUE_REMOVE.equals(fieldValueType)) { - ReadableArray elements = fieldValueMap.getArray(TYPE_FIELDVALUE_ELEMENTS); - return FieldValue.arrayRemove(parseReadableArray(firestore, elements).toArray()); - } - - Log.w(TAG, "Unknown FieldValue type: " + fieldValueType); - return null; - } - - Log.w(TAG, "Unknown object of type " + type); - return null; - } - - /** - * Parse JS batches array - * - * @param firestore FirebaseFirestore - * @param readableArray ReadableArray - * @return List - */ - static List parseDocumentBatches( - FirebaseFirestore firestore, - ReadableArray readableArray - ) { - List writes = new ArrayList<>(readableArray.size()); - - for (int i = 0; i < readableArray.size(); i++) { - Map write = new HashMap<>(); - ReadableMap map = readableArray.getMap(i); - - write.put(TYPE, map.getString(TYPE)); - write.put(KEY_PATH, map.getString(KEY_PATH)); - - if (map.hasKey(KEY_DATA)) { - write.put(KEY_DATA, parseReadableMap(firestore, map.getMap(KEY_DATA))); - } - - if (map.hasKey(KEY_OPTIONS)) { - write.put( - KEY_OPTIONS, - Utils.recursivelyDeconstructReadableMap(map.getMap(KEY_OPTIONS)) - ); - } - - writes.add(write); - } - - return writes; - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/QuerySnapshotSerializeAsyncTask.java b/android/src/main/java/io/invertase/firebase/firestore/QuerySnapshotSerializeAsyncTask.java deleted file mode 100644 index 0b882b05..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/QuerySnapshotSerializeAsyncTask.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.invertase.firebase.firestore; - -import android.os.AsyncTask; - -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.firestore.QuerySnapshot; - -import java.lang.ref.WeakReference; - -class QuerySnapshotSerializeAsyncTask extends AsyncTask { - private WeakReference reactContextWeakReference; - private WeakReference referenceWeakReference; - - QuerySnapshotSerializeAsyncTask( - ReactContext context, - RNFirebaseFirestoreCollectionReference reference - ) { - referenceWeakReference = new WeakReference<>(reference); - reactContextWeakReference = new WeakReference<>(context); - } - - @Override - protected final WritableMap doInBackground(Object... params) { - QuerySnapshot querySnapshot = (QuerySnapshot) params[0]; - - try { - return FirestoreSerialize.snapshotToWritableMap(querySnapshot); - } catch (RuntimeException e) { - if (isAvailable()) { - reactContextWeakReference - .get() - .handleException(e); - } else { - throw e; - } - return null; - } - } - - @Override - protected void onPostExecute(WritableMap writableMap) { - // do nothing as overridden on usage - } - - private Boolean isAvailable() { - return reactContextWeakReference.get() != null && referenceWeakReference.get() != null; - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java deleted file mode 100644 index 1a587ec0..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java +++ /dev/null @@ -1,770 +0,0 @@ -package io.invertase.firebase.firestore; - -import android.os.AsyncTask; -import android.util.Log; -import android.util.SparseArray; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.FirebaseApp; -import com.google.firebase.firestore.DocumentReference; -import com.google.firebase.firestore.FieldValue; -import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.FirebaseFirestoreException; -import com.google.firebase.firestore.FirebaseFirestoreSettings; -import com.google.firebase.firestore.SetOptions; -import com.google.firebase.firestore.Transaction; -import com.google.firebase.firestore.WriteBatch; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.ErrorUtils; -import io.invertase.firebase.Utils; - -public class RNFirebaseFirestore extends ReactContextBaseJavaModule { - private static final String TAG = "RNFirebaseFirestore"; - private SparseArray transactionHandlers = new SparseArray<>(); - - RNFirebaseFirestore(ReactApplicationContext reactContext) { - super(reactContext); - } - - - /* - * REACT NATIVE METHODS - */ - - /** - * Generates a js-like error from an exception and rejects the provided promise with it. - * - * @param exception Exception Exception normally from a task result. - * @param promise Promise react native promise - */ - static void promiseRejectException(Promise promise, FirebaseFirestoreException exception) { - WritableMap jsError = getJSError(exception); - promise.reject( - jsError.getString("code"), - jsError.getString("message"), - exception - ); - } - - /** - * Get a database instance for a specific firebase app instance - * - * @param appName appName - * @return FirebaseFirestore - */ - static FirebaseFirestore getFirestoreForApp(String appName) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - return FirebaseFirestore.getInstance(firebaseApp); - } - - /** - * Convert as firebase DatabaseError instance into a writable map - * with the correct web-like error codes. - * - * @param nativeException nativeException - * @return WritableMap - */ - static WritableMap getJSError(FirebaseFirestoreException nativeException) { - WritableMap errorMap = Arguments.createMap(); - errorMap.putInt( - "nativeErrorCode", - nativeException - .getCode() - .value() - ); - errorMap.putString("nativeErrorMessage", nativeException.getMessage()); - - String code; - String message; - String service = "Firestore"; - - // TODO: Proper error mappings - switch (nativeException.getCode()) { - case OK: - code = ErrorUtils.getCodeWithService(service, "ok"); - message = ErrorUtils.getMessageWithService("Ok.", service, code); - break; - case CANCELLED: - code = ErrorUtils.getCodeWithService(service, "cancelled"); - message = ErrorUtils.getMessageWithService("The operation was cancelled.", service, code); - break; - case UNKNOWN: - code = ErrorUtils.getCodeWithService(service, "unknown"); - message = ErrorUtils.getMessageWithService( - "Unknown error or an error from a different error domain.", - service, - code - ); - break; - case INVALID_ARGUMENT: - code = ErrorUtils.getCodeWithService(service, "invalid-argument"); - message = ErrorUtils.getMessageWithService( - "Client specified an invalid argument.", - service, - code - ); - break; - case DEADLINE_EXCEEDED: - code = ErrorUtils.getCodeWithService(service, "deadline-exceeded"); - message = ErrorUtils.getMessageWithService( - "Deadline expired before operation could complete.", - service, - code - ); - break; - case NOT_FOUND: - code = ErrorUtils.getCodeWithService(service, "not-found"); - message = ErrorUtils.getMessageWithService( - "Some requested document was not found.", - service, - code - ); - break; - case ALREADY_EXISTS: - code = ErrorUtils.getCodeWithService(service, "already-exists"); - message = ErrorUtils.getMessageWithService( - "Some document that we attempted to create already exists.", - service, - code - ); - break; - case PERMISSION_DENIED: - code = ErrorUtils.getCodeWithService(service, "permission-denied"); - message = ErrorUtils.getMessageWithService( - "The caller does not have permission to execute the specified operation.", - service, - code - ); - break; - case RESOURCE_EXHAUSTED: - code = ErrorUtils.getCodeWithService(service, "resource-exhausted"); - message = ErrorUtils.getMessageWithService( - "Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.", - service, - code - ); - break; - case FAILED_PRECONDITION: - code = ErrorUtils.getCodeWithService(service, "failed-precondition"); - message = ErrorUtils.getMessageWithService( - "Operation was rejected because the system is not in a state required for the operation`s execution.", - service, - code - ); - break; - case ABORTED: - code = ErrorUtils.getCodeWithService(service, "aborted"); - message = ErrorUtils.getMessageWithService( - "The operation was aborted, typically due to a concurrency issue like transaction aborts, etc.", - service, - code - ); - break; - case OUT_OF_RANGE: - code = ErrorUtils.getCodeWithService(service, "out-of-range"); - message = ErrorUtils.getMessageWithService( - "Operation was attempted past the valid range.", - service, - code - ); - break; - case UNIMPLEMENTED: - code = ErrorUtils.getCodeWithService(service, "unimplemented"); - message = ErrorUtils.getMessageWithService( - "Operation is not implemented or not supported/enabled.", - service, - code - ); - break; - case INTERNAL: - code = ErrorUtils.getCodeWithService(service, "internal"); - message = ErrorUtils.getMessageWithService("Internal errors.", service, code); - break; - case UNAVAILABLE: - code = ErrorUtils.getCodeWithService(service, "unavailable"); - message = ErrorUtils.getMessageWithService( - "The service is currently unavailable.", - service, - code - ); - break; - case DATA_LOSS: - code = ErrorUtils.getCodeWithService(service, "data-loss"); - message = ErrorUtils.getMessageWithService( - "Unrecoverable data loss or corruption.", - service, - code - ); - break; - case UNAUTHENTICATED: - code = ErrorUtils.getCodeWithService(service, "unauthenticated"); - message = ErrorUtils.getMessageWithService( - "The request does not have valid authentication credentials for the operation.", - service, - code - ); - break; - default: - code = ErrorUtils.getCodeWithService(service, "unknown"); - message = ErrorUtils.getMessageWithService("An unknown error occurred.", service, code); - } - - errorMap.putString("code", code); - errorMap.putString("message", message); - return errorMap; - } - - @ReactMethod - public void disableNetwork(String appName, final Promise promise) { - getFirestoreForApp(appName) - .disableNetwork() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "disableNetwork:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "disableNetwork:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - @ReactMethod - public void setLogLevel(String logLevel) { - if ("debug".equals(logLevel) || "error".equals(logLevel)) { - FirebaseFirestore.setLoggingEnabled(true); - } else { - FirebaseFirestore.setLoggingEnabled(false); - } - } - - @ReactMethod - public void enableNetwork(String appName, final Promise promise) { - getFirestoreForApp(appName) - .enableNetwork() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "enableNetwork:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "enableNetwork:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - @ReactMethod - public void collectionGet( - String appName, String path, ReadableArray filters, - ReadableArray orders, ReadableMap options, ReadableMap getOptions, - final Promise promise - ) { - RNFirebaseFirestoreCollectionReference ref = getCollectionForAppPath( - appName, - path, - filters, - orders, - options - ); - ref.get(getOptions, promise); - } - - @ReactMethod - public void collectionOffSnapshot( - String appName, String path, ReadableArray filters, - ReadableArray orders, ReadableMap options, String listenerId - ) { - RNFirebaseFirestoreCollectionReference.offSnapshot(listenerId); - } - - @ReactMethod - public void collectionOnSnapshot( - String appName, String path, ReadableArray filters, - ReadableArray orders, ReadableMap options, String listenerId, - ReadableMap queryListenOptions - ) { - RNFirebaseFirestoreCollectionReference ref = getCollectionForAppPath( - appName, - path, - filters, - orders, - options - ); - ref.onSnapshot(listenerId, queryListenOptions); - } - - @ReactMethod - public void documentBatch( - final String appName, final ReadableArray writes, - final Promise promise - ) { - FirebaseFirestore firestore = getFirestoreForApp(appName); - WriteBatch batch = firestore.batch(); - final List writesArray = FirestoreSerialize.parseDocumentBatches(firestore, writes); - - for (Object w : writesArray) { - Map write = (Map) w; - String type = (String) write.get("type"); - String path = (String) write.get("path"); - Map data = (Map) write.get("data"); - - DocumentReference ref = firestore.document(path); - switch (type) { - case "DELETE": - batch = batch.delete(ref); - break; - case "SET": - Map options = (Map) write.get("options"); - if (options != null && options.containsKey("merge") && (boolean) options.get("merge")) { - batch = batch.set(ref, data, SetOptions.merge()); - } else { - batch = batch.set(ref, data); - } - - break; - case "UPDATE": - batch = batch.update(ref, data); - break; - } - } - - batch - .commit() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "documentBatch:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "documentBatch:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - @ReactMethod - public void documentDelete(String appName, String path, final Promise promise) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.delete(promise); - } - - @ReactMethod - public void documentGet( - String appName, - String path, - ReadableMap getOptions, - final Promise promise - ) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.get(getOptions, promise); - } - - @ReactMethod - public void documentOffSnapshot(String appName, String path, String listenerId) { - RNFirebaseFirestoreDocumentReference.offSnapshot(listenerId); - } - - @ReactMethod - public void documentOnSnapshot( - String appName, String path, String listenerId, - ReadableMap docListenOptions - ) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.onSnapshot(listenerId, docListenOptions); - } - - @ReactMethod - public void documentSet( - String appName, - String path, - ReadableMap data, - ReadableMap options, - final Promise promise - ) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.set(data, options, promise); - } - - - /* - * Transaction Methods - */ - - @ReactMethod - public void documentUpdate(String appName, String path, ReadableMap data, final Promise promise) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.update(data, promise); - } - - @ReactMethod - public void settings(String appName, ReadableMap settings, final Promise promise) { - FirebaseFirestore firestore = getFirestoreForApp(appName); - FirebaseFirestoreSettings.Builder firestoreSettings = new FirebaseFirestoreSettings.Builder(); - if (settings.hasKey("host")) { - firestoreSettings.setHost(settings.getString("host")); - } else { - firestoreSettings.setHost(firestore - .getFirestoreSettings() - .getHost()); - } - if (settings.hasKey("persistence")) { - firestoreSettings.setPersistenceEnabled(settings.getBoolean("persistence")); - } else { - firestoreSettings.setPersistenceEnabled(firestore - .getFirestoreSettings() - .isPersistenceEnabled()); - } - if (settings.hasKey("ssl")) { - firestoreSettings.setSslEnabled(settings.getBoolean("ssl")); - } else { - firestoreSettings.setSslEnabled(firestore - .getFirestoreSettings() - .isSslEnabled()); - } - -// if (settings.hasKey("timestampsInSnapshots")) { -// // TODO: Not supported on Android yet -// } - - firestore.setFirestoreSettings(firestoreSettings.build()); - promise.resolve(null); - } - - /** - * Try clean up previous transactions on reload - */ - @Override - public void onCatalystInstanceDestroy() { - for (int i = 0, size = transactionHandlers.size(); i < size; i++) { - RNFirebaseFirestoreTransactionHandler transactionHandler = transactionHandlers.get(i); - if (transactionHandler != null) { - transactionHandler.abort(); - } - } - - transactionHandlers.clear(); - } - - /** - * Calls the internal Firestore Transaction classes instance .get(ref) method and resolves with - * the DocumentSnapshot. - * - * @param appName appName - * @param transactionId transactionId - * @param path path - * @param promise promise - */ - @ReactMethod - public void transactionGetDocument( - String appName, - int transactionId, - String path, - final Promise promise - ) { - RNFirebaseFirestoreTransactionHandler handler = transactionHandlers.get(transactionId); - - if (handler == null) { - promise.reject( - "internal-error", - "An internal error occurred whilst attempting to find a native transaction by id." - ); - } else { - DocumentReference ref = getDocumentForAppPath(appName, path).getRef(); - handler.getDocument(ref, promise); - } - } - - - /* - * INTERNALS/UTILS - */ - - /** - * Aborts any pending signals and deletes the transaction handler. - * - * @param appName appName - * @param transactionId transactionId - */ - @ReactMethod - public void transactionDispose(String appName, int transactionId) { - RNFirebaseFirestoreTransactionHandler handler = transactionHandlers.get(transactionId); - - if (handler != null) { - handler.abort(); - transactionHandlers.delete(transactionId); - } - } - - /** - * Signals to transactionHandler that the command buffer is ready. - * - * @param appName appName - * @param transactionId transactionId - * @param commandBuffer commandBuffer - */ - @ReactMethod - public void transactionApplyBuffer( - String appName, - int transactionId, - ReadableArray commandBuffer - ) { - RNFirebaseFirestoreTransactionHandler handler = transactionHandlers.get(transactionId); - - if (handler != null) { - handler.signalBufferReceived(commandBuffer); - } - } - - /** - * Begin a new transaction via AsyncTask 's - * - * @param appName appName - * @param transactionId transactionId - */ - @ReactMethod - public void transactionBegin(final String appName, int transactionId) { - final RNFirebaseFirestoreTransactionHandler transactionHandler = new RNFirebaseFirestoreTransactionHandler( - appName, - transactionId - ); - - transactionHandlers.put(transactionId, transactionHandler); - - AsyncTask.execute(new Runnable() { - @Override - public void run() { - getFirestoreForApp(appName) - .runTransaction(new Transaction.Function() { - @Override - public Void apply(@Nonnull Transaction transaction) throws FirebaseFirestoreException { - transactionHandler.resetState(transaction); - - // emit the update cycle to JS land using an async task - // otherwise it gets blocked by the pending lock await - AsyncTask.execute(new Runnable() { - @Override - public void run() { - WritableMap eventMap = transactionHandler.createEventMap(null, "update"); - Utils.sendEvent( - getReactApplicationContext(), - "firestore_transaction_event", - eventMap - ); - } - }); - - // wait for a signal to be received from JS land code - transactionHandler.await(); - - // exit early if aborted - has to throw an exception otherwise will just keep trying ... - if (transactionHandler.aborted) { - throw new FirebaseFirestoreException( - "abort", - FirebaseFirestoreException.Code.ABORTED - ); - } - - // exit early if timeout from bridge - has to throw an exception otherwise will just keep trying ... - if (transactionHandler.timeout) { - throw new FirebaseFirestoreException( - "timeout", - FirebaseFirestoreException.Code.DEADLINE_EXCEEDED - ); - } - - // process any buffered commands from JS land - ReadableArray buffer = transactionHandler.getCommandBuffer(); - - // exit early if no commands - if (buffer == null) { - return null; - } - - for (int i = 0, size = buffer.size(); i < size; i++) { - ReadableMap data; - ReadableMap command = buffer.getMap(i); - String path = command.getString("path"); - String type = command.getString("type"); - RNFirebaseFirestoreDocumentReference documentReference = getDocumentForAppPath( - appName, - path - ); - - switch (type) { - case "set": - data = command.getMap("data"); - ReadableMap options = command.getMap("options"); - Map setData = FirestoreSerialize.parseReadableMap( - RNFirebaseFirestore.getFirestoreForApp(appName), - data - ); - - if (options != null && options.hasKey("merge") && options.getBoolean("merge")) { - transaction.set(documentReference.getRef(), setData, SetOptions.merge()); - } else { - transaction.set(documentReference.getRef(), setData); - } - break; - case "update": - data = command.getMap("data"); - - Map updateData = FirestoreSerialize.parseReadableMap( - RNFirebaseFirestore.getFirestoreForApp(appName), - data - ); - - transaction.update(documentReference.getRef(), updateData); - break; - case "delete": - transaction.delete(documentReference.getRef()); - break; - default: - throw new IllegalArgumentException("Unknown command type at index " + i + "."); - } - } - - return null; - } - }) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(Void aVoid) { - if (!transactionHandler.aborted) { - Log.d(TAG, "Transaction onSuccess!"); - WritableMap eventMap = transactionHandler.createEventMap(null, "complete"); - Utils.sendEvent( - getReactApplicationContext(), - "firestore_transaction_event", - eventMap - ); - } - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception e) { - if (!transactionHandler.aborted) { - Log.w(TAG, "Transaction onFailure.", e); - WritableMap eventMap = transactionHandler.createEventMap( - (FirebaseFirestoreException) e, - "error" - ); - Utils.sendEvent( - getReactApplicationContext(), - "firestore_transaction_event", - eventMap - ); - } - } - }); - } - }); - } - - /** - * Get a collection reference for a specific app and path - * - * @param appName appName - * @param filters filters - * @param orders orders - * @param options options - * @param path @return - */ - private RNFirebaseFirestoreCollectionReference getCollectionForAppPath( - String appName, String path, - ReadableArray filters, - ReadableArray orders, - ReadableMap options - ) { - return new RNFirebaseFirestoreCollectionReference( - this.getReactApplicationContext(), - appName, - path, - filters, - orders, - options - ); - } - - /** - * Get a document reference for a specific app and path - * - * @param appName appName - * @param path path - * @return RNFirebaseFirestoreDocumentReference - */ - private RNFirebaseFirestoreDocumentReference getDocumentForAppPath(String appName, String path) { - return new RNFirebaseFirestoreDocumentReference( - this.getReactApplicationContext(), - appName, - path - ); - } - - /** - * React Method - returns this module name - * - * @return - */ - @Override - public String getName() { - return "RNFirebaseFirestore"; - } - - /** - * React Native constants for RNFirebaseFirestore - * - * @return - */ - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - constants.put( - "deleteFieldValue", - FieldValue - .delete() - .toString() - ); - constants.put( - "serverTimestampFieldValue", - FieldValue - .serverTimestamp() - .toString() - ); - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java deleted file mode 100644 index 98da9d54..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java +++ /dev/null @@ -1,335 +0,0 @@ -package io.invertase.firebase.firestore; - - -import android.annotation.SuppressLint; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.firestore.EventListener; -import com.google.firebase.firestore.FieldPath; -import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.FirebaseFirestoreException; -import com.google.firebase.firestore.ListenerRegistration; -import com.google.firebase.firestore.MetadataChanges; -import com.google.firebase.firestore.Query; -import com.google.firebase.firestore.QuerySnapshot; -import com.google.firebase.firestore.Source; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -class RNFirebaseFirestoreCollectionReference { - private static final String TAG = "RNFSCollectionReference"; - private static Map collectionSnapshotListeners = new HashMap<>(); - - private final String path; - private final Query query; - private final String appName; - private final ReadableMap options; - private final ReadableArray orders; - private final ReadableArray filters; - private ReactContext reactContext; - - RNFirebaseFirestoreCollectionReference( - ReactContext reactContext, - String appName, - String path, - ReadableArray filters, - ReadableArray orders, - ReadableMap options - ) { - this.appName = appName; - this.path = path; - this.filters = filters; - this.orders = orders; - this.options = options; - this.query = buildQuery(); - this.reactContext = reactContext; - } - - static void offSnapshot(final String listenerId) { - ListenerRegistration listenerRegistration = collectionSnapshotListeners.remove(listenerId); - if (listenerRegistration != null) { - listenerRegistration.remove(); - } - } - - void get(ReadableMap getOptions, final Promise promise) { - Source source; - if (getOptions != null && getOptions.hasKey("source")) { - String optionsSource = getOptions.getString("source"); - if ("server".equals(optionsSource)) { - source = Source.SERVER; - } else if ("cache".equals(optionsSource)) { - source = Source.CACHE; - } else { - source = Source.DEFAULT; - } - } else { - source = Source.DEFAULT; - } - - @SuppressLint("StaticFieldLeak") final QuerySnapshotSerializeAsyncTask serializeAsyncTask = new QuerySnapshotSerializeAsyncTask( - reactContext, this - ) { - @Override - protected void onPostExecute(WritableMap writableMap) { - promise.resolve(writableMap); - } - }; - - query - .get(source) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "get:onComplete:success"); - serializeAsyncTask.execute(task.getResult()); - } else { - Log.e(TAG, "get:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - void onSnapshot(final String listenerId, final ReadableMap queryListenOptions) { - if (!collectionSnapshotListeners.containsKey(listenerId)) { - final EventListener listener = new EventListener() { - @Override - public void onEvent(QuerySnapshot querySnapshot, FirebaseFirestoreException exception) { - if (exception == null) { - handleQuerySnapshotEvent(listenerId, querySnapshot); - } else { - ListenerRegistration listenerRegistration = collectionSnapshotListeners.remove( - listenerId); - if (listenerRegistration != null) { - listenerRegistration.remove(); - } - handleQuerySnapshotError(listenerId, exception); - } - } - }; - MetadataChanges metadataChanges; - - if (queryListenOptions != null - && queryListenOptions.hasKey("includeMetadataChanges") - && queryListenOptions.getBoolean("includeMetadataChanges")) { - metadataChanges = MetadataChanges.INCLUDE; - } else { - metadataChanges = MetadataChanges.EXCLUDE; - } - - ListenerRegistration listenerRegistration = this.query.addSnapshotListener( - metadataChanges, - listener - ); - collectionSnapshotListeners.put(listenerId, listenerRegistration); - } - } - - /* - * INTERNALS/UTILS - */ - - boolean hasListeners() { - return !collectionSnapshotListeners.isEmpty(); - } - - private Query buildQuery() { - FirebaseFirestore firestore = RNFirebaseFirestore.getFirestoreForApp(appName); - Query query = firestore.collection(path); - query = applyFilters(firestore, query); - query = applyOrders(query); - query = applyOptions(firestore, query); - - return query; - } - - private Query applyFilters(FirebaseFirestore firestore, Query query) { - for (int i = 0; i < filters.size(); i++) { - ReadableMap filter = filters.getMap(i); - ReadableMap fieldPathMap = filter.getMap("fieldPath"); - String fieldPathType = fieldPathMap.getString("type"); - - String operator = filter.getString("operator"); - ReadableMap jsValue = filter.getMap("value"); - Object value = FirestoreSerialize.parseTypeMap(firestore, jsValue); - - if (fieldPathType.equals("string")) { - String fieldPath = fieldPathMap.getString("string"); - switch (operator) { - case "EQUAL": - query = query.whereEqualTo(fieldPath, value); - break; - case "GREATER_THAN": - query = query.whereGreaterThan(fieldPath, value); - break; - case "GREATER_THAN_OR_EQUAL": - query = query.whereGreaterThanOrEqualTo(fieldPath, value); - break; - case "LESS_THAN": - query = query.whereLessThan(fieldPath, value); - break; - case "LESS_THAN_OR_EQUAL": - query = query.whereLessThanOrEqualTo(fieldPath, value); - break; - case "ARRAY_CONTAINS": - query = query.whereArrayContains(fieldPath, value); - break; - } - } else { - ReadableArray fieldPathElements = fieldPathMap.getArray("elements"); - String[] fieldPathArray = new String[fieldPathElements.size()]; - for (int j = 0; j < fieldPathElements.size(); j++) { - fieldPathArray[j] = fieldPathElements.getString(j); - } - FieldPath fieldPath = FieldPath.of(fieldPathArray); - switch (operator) { - case "EQUAL": - query = query.whereEqualTo(fieldPath, value); - break; - case "GREATER_THAN": - query = query.whereGreaterThan(fieldPath, value); - break; - case "GREATER_THAN_OR_EQUAL": - query = query.whereGreaterThanOrEqualTo(fieldPath, value); - break; - case "LESS_THAN": - query = query.whereLessThan(fieldPath, value); - break; - case "LESS_THAN_OR_EQUAL": - query = query.whereLessThanOrEqualTo(fieldPath, value); - break; - case "ARRAY_CONTAINS": - query = query.whereArrayContains(fieldPath, value); - break; - } - } - } - return query; - } - - private Query applyOrders(Query query) { - List ordersList = Utils.recursivelyDeconstructReadableArray(orders); - for (Object o : ordersList) { - Map order = (Map) o; - String direction = (String) order.get("direction"); - Map fieldPathMap = (Map) order.get("fieldPath"); - String fieldPathType = (String) fieldPathMap.get("type"); - - if (fieldPathType.equals("string")) { - String fieldPath = (String) fieldPathMap.get("string"); - query = query.orderBy(fieldPath, Query.Direction.valueOf(direction)); - } else { - List fieldPathElements = (List) fieldPathMap.get("elements"); - FieldPath fieldPath = FieldPath.of(fieldPathElements.toArray(new String[fieldPathElements.size()])); - query = query.orderBy(fieldPath, Query.Direction.valueOf(direction)); - } - } - return query; - } - - private Query applyOptions(FirebaseFirestore firestore, Query query) { - if (options.hasKey("endAt")) { - List endAtList = FirestoreSerialize.parseReadableArray( - firestore, - options.getArray("endAt") - ); - query = query.endAt(endAtList.toArray()); - } - - if (options.hasKey("endBefore")) { - List endBeforeList = FirestoreSerialize.parseReadableArray( - firestore, - options.getArray("endBefore") - ); - query = query.endBefore(endBeforeList.toArray()); - } - - if (options.hasKey("limit")) { - int limit = options.getInt("limit"); - query = query.limit(limit); - } -// if (options.hasKey("offset")) { - // Android doesn't support offset -// } -// if (options.hasKey("selectFields")) { - // Android doesn't support selectFields -// } - if (options.hasKey("startAfter")) { - List startAfterList = FirestoreSerialize.parseReadableArray( - firestore, - options.getArray("startAfter") - ); - query = query.startAfter(startAfterList.toArray()); - } - - if (options.hasKey("startAt")) { - List startAtList = FirestoreSerialize.parseReadableArray( - firestore, - options.getArray("startAt") - ); - query = query.startAt(startAtList.toArray()); - } - - return query; - } - - /** - * Handles documentSnapshot events. - * - * @param listenerId id - * @param querySnapshot snapshot - */ - private void handleQuerySnapshotEvent(final String listenerId, QuerySnapshot querySnapshot) { - @SuppressLint("StaticFieldLeak") final QuerySnapshotSerializeAsyncTask serializeAsyncTask = new QuerySnapshotSerializeAsyncTask( - reactContext, this - ) { - @Override - protected void onPostExecute(WritableMap writableMap) { - WritableMap event = Arguments.createMap(); - event.putString("path", path); - event.putString("appName", appName); - event.putString("listenerId", listenerId); - event.putMap("querySnapshot", writableMap); - Utils.sendEvent(reactContext, "firestore_collection_sync_event", event); - } - }; - - serializeAsyncTask.execute(querySnapshot); - } - - /** - * Handles a documentSnapshot error event - * - * @param listenerId id - * @param exception exception - */ - private void handleQuerySnapshotError(String listenerId, FirebaseFirestoreException exception) { - WritableMap event = Arguments.createMap(); - - event.putString("appName", appName); - event.putString("path", path); - event.putString("listenerId", listenerId); - event.putMap("error", RNFirebaseFirestore.getJSError(exception)); - - Utils.sendEvent(reactContext, "firestore_collection_sync_event", event); - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java deleted file mode 100644 index 25ffab96..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java +++ /dev/null @@ -1,274 +0,0 @@ -package io.invertase.firebase.firestore; - -import android.annotation.SuppressLint; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.firestore.DocumentReference; -import com.google.firebase.firestore.DocumentSnapshot; -import com.google.firebase.firestore.EventListener; -import com.google.firebase.firestore.FirebaseFirestoreException; -import com.google.firebase.firestore.ListenerRegistration; -import com.google.firebase.firestore.MetadataChanges; -import com.google.firebase.firestore.SetOptions; -import com.google.firebase.firestore.Source; - -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - - -public class RNFirebaseFirestoreDocumentReference { - private static final String TAG = "RNFBFSDocumentReference"; - private static Map documentSnapshotListeners = new HashMap<>(); - - private final String appName; - private final String path; - private final DocumentReference ref; - private ReactContext reactContext; - - RNFirebaseFirestoreDocumentReference(ReactContext reactContext, String appName, String path) { - this.path = path; - this.appName = appName; - this.reactContext = reactContext; - this.ref = RNFirebaseFirestore - .getFirestoreForApp(appName) - .document(path); - } - - static void offSnapshot(final String listenerId) { - ListenerRegistration listenerRegistration = documentSnapshotListeners.remove(listenerId); - if (listenerRegistration != null) { - listenerRegistration.remove(); - } - } - - void delete(final Promise promise) { - this.ref - .delete() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "delete:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "delete:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - void get(final ReadableMap getOptions, final Promise promise) { - Source source; - - if (getOptions != null && getOptions.hasKey("source")) { - String optionsSource = getOptions.getString("source"); - if ("server".equals(optionsSource)) { - source = Source.SERVER; - } else if ("cache".equals(optionsSource)) { - source = Source.CACHE; - } else { - source = Source.DEFAULT; - } - } else { - source = Source.DEFAULT; - } - - @SuppressLint("StaticFieldLeak") final DocumentSnapshotSerializeAsyncTask serializeAsyncTask = new DocumentSnapshotSerializeAsyncTask( - reactContext, this - ) { - @Override - protected void onPostExecute(WritableMap writableMap) { - promise.resolve(writableMap); - } - }; - - this.ref - .get(source) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "get:onComplete:success"); - serializeAsyncTask.execute(task.getResult()); - } else { - Log.e(TAG, "get:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - void onSnapshot(final String listenerId, final ReadableMap docListenOptions) { - if (!documentSnapshotListeners.containsKey(listenerId)) { - final EventListener listener = new EventListener() { - @Override - public void onEvent( - DocumentSnapshot documentSnapshot, - FirebaseFirestoreException exception - ) { - if (exception == null) { - handleDocumentSnapshotEvent(listenerId, documentSnapshot); - } else { - ListenerRegistration listenerRegistration = documentSnapshotListeners.remove(listenerId); - - if (listenerRegistration != null) { - listenerRegistration.remove(); - } - - handleDocumentSnapshotError(listenerId, exception); - } - } - }; - - MetadataChanges metadataChanges; - - if (docListenOptions != null - && docListenOptions.hasKey("includeMetadataChanges") - && docListenOptions.getBoolean("includeMetadataChanges")) { - metadataChanges = MetadataChanges.INCLUDE; - } else { - metadataChanges = MetadataChanges.EXCLUDE; - } - - ListenerRegistration listenerRegistration = this.ref.addSnapshotListener( - metadataChanges, - listener - ); - - documentSnapshotListeners.put(listenerId, listenerRegistration); - } - } - - public void set(final ReadableMap data, final ReadableMap options, final Promise promise) { - Task task; - - Map map = FirestoreSerialize.parseReadableMap( - RNFirebaseFirestore.getFirestoreForApp(appName), - data - ); - - if (options != null && options.hasKey("merge") && options.getBoolean("merge")) { - task = this.ref.set(map, SetOptions.merge()); - } else { - task = this.ref.set(map); - } - - task.addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "set:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "set:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - void update(final ReadableMap data, final Promise promise) { - Map map = FirestoreSerialize.parseReadableMap( - RNFirebaseFirestore.getFirestoreForApp(appName), - data - ); - - this.ref - .update(map) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "update:onComplete:success"); - promise.resolve(null); - } else { - Log.e(TAG, "update:onComplete:failure", task.getException()); - RNFirebaseFirestore.promiseRejectException( - promise, - (FirebaseFirestoreException) task.getException() - ); - } - } - }); - } - - /* - * INTERNALS/UTILS - */ - - DocumentReference getRef() { - return ref; - } - - boolean hasListeners() { - return !documentSnapshotListeners.isEmpty(); - } - - /** - * Handles documentSnapshot events. - * - * @param listenerId id - * @param documentSnapshot snapshot - */ - private void handleDocumentSnapshotEvent( - final String listenerId, - DocumentSnapshot documentSnapshot - ) { - @SuppressLint("StaticFieldLeak") final DocumentSnapshotSerializeAsyncTask serializeAsyncTask = new DocumentSnapshotSerializeAsyncTask( - reactContext, this - ) { - @Override - protected void onPostExecute(WritableMap writableMap) { - WritableMap event = Arguments.createMap(); - event.putString("path", path); - event.putString("appName", appName); - event.putString("listenerId", listenerId); - event.putMap("documentSnapshot", writableMap); - Utils.sendEvent(reactContext, "firestore_document_sync_event", event); - } - }; - - serializeAsyncTask.execute(documentSnapshot); - } - - /** - * Handles a documentSnapshot error event - * - * @param listenerId id - * @param exception exception - */ - private void handleDocumentSnapshotError( - String listenerId, - FirebaseFirestoreException exception - ) { - WritableMap event = Arguments.createMap(); - - event.putString("path", path); - event.putString("appName", appName); - event.putString("listenerId", listenerId); - event.putMap("error", RNFirebaseFirestore.getJSError(exception)); - - Utils.sendEvent(reactContext, "firestore_document_sync_event", event); - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestorePackage.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestorePackage.java deleted file mode 100644 index 22629c35..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestorePackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.firestore; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseFirestorePackage implements ReactPackage { - public RNFirebaseFirestorePackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseFirestore(reactContext)); - - return modules; - } - - /** - * @param reactContext reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreTransactionHandler.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreTransactionHandler.java deleted file mode 100644 index dd908eb8..00000000 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreTransactionHandler.java +++ /dev/null @@ -1,166 +0,0 @@ -package io.invertase.firebase.firestore; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.firestore.DocumentReference; -import com.google.firebase.firestore.DocumentSnapshot; -import com.google.firebase.firestore.FirebaseFirestoreException; -import com.google.firebase.firestore.Transaction; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.Nullable; - - -class RNFirebaseFirestoreTransactionHandler { - private final ReentrantLock lock; - private final Condition condition; - boolean aborted = false; - boolean timeout = false; - private String appName; - private long timeoutAt; - private int transactionId; - private ReadableArray commandBuffer; - private Transaction firestoreTransaction; - - RNFirebaseFirestoreTransactionHandler(String app, int id) { - appName = app; - transactionId = id; - updateInternalTimeout(); - lock = new ReentrantLock(); - condition = lock.newCondition(); - } - - /* - * ------------- - * PACKAGE API - * ------------- - */ - - /** - * Abort the currently in progress transaction if any. - */ - void abort() { - aborted = true; - safeUnlock(); - } - - /** - * Reset handler state - clears command buffer + updates to new Transaction instance - * - * @param firestoreTransaction - */ - void resetState(Transaction firestoreTransaction) { - this.commandBuffer = null; - this.firestoreTransaction = firestoreTransaction; - } - - /** - * Signal that the transaction buffer has been received and needs to be processed. - * - * @param buffer - */ - void signalBufferReceived(ReadableArray buffer) { - lock.lock(); - - try { - commandBuffer = buffer; - condition.signalAll(); - } finally { - safeUnlock(); - } - } - - /** - * Wait for signalBufferReceived to signal condition - * - * @throws InterruptedException - */ - void await() { - lock.lock(); - - updateInternalTimeout(); - - try { - while (!aborted && !timeout && !condition.await(10, TimeUnit.MILLISECONDS)) { - if (System.currentTimeMillis() > timeoutAt) timeout = true; - } - } catch (InterruptedException ie) { - // should never be interrupted - } finally { - safeUnlock(); - } - } - - /** - * Get the current pending command buffer. - * - * @return - */ - ReadableArray getCommandBuffer() { - return commandBuffer; - } - - - /** - * Get and resolve a DocumentSnapshot from transaction.get(ref); - * - * @param ref - * @param promise - */ - void getDocument(DocumentReference ref, Promise promise) { - updateInternalTimeout(); - - try { - DocumentSnapshot documentSnapshot = firestoreTransaction.get(ref); - WritableMap writableMap = FirestoreSerialize.snapshotToWritableMap(documentSnapshot); - promise.resolve(writableMap); - } catch (FirebaseFirestoreException firestoreException) { - WritableMap jsError = RNFirebaseFirestore.getJSError(firestoreException); - promise.reject(jsError.getString("code"), jsError.getString("message")); - } - } - - /** - * Event map for `firestore_transaction_event` events. - * - * @param error - * @param type - * @return - */ - WritableMap createEventMap(@Nullable FirebaseFirestoreException error, String type) { - WritableMap eventMap = Arguments.createMap(); - - eventMap.putInt("id", transactionId); - eventMap.putString("appName", appName); - - if (error != null) { - eventMap.putString("type", "error"); - eventMap.putMap("error", RNFirebaseFirestore.getJSError(error)); - } else { - eventMap.putString("type", type); - } - - return eventMap; - } - - /* - * ------------- - * INTERNAL API - * ------------- - */ - - private void safeUnlock() { - if (lock.isLocked()) { - lock.unlock(); - } - } - - private void updateInternalTimeout() { - timeoutAt = System.currentTimeMillis() + 15000; - } -} diff --git a/android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctionsPackage.java b/android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctionsPackage.java deleted file mode 100644 index f4379c77..00000000 --- a/android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctionsPackage.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.invertase.firebase.functions; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseFunctionsPackage implements ReactPackage { - public RNFirebaseFunctionsPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseFunctions(reactContext)); - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceId.java b/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceId.java deleted file mode 100644 index 1587862c..00000000 --- a/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceId.java +++ /dev/null @@ -1,75 +0,0 @@ -package io.invertase.firebase.instanceid; - - -import android.util.Log; - -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.google.firebase.iid.FirebaseInstanceId; - -import java.io.IOException; - -public class RNFirebaseInstanceId extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseInstanceId"; - - public RNFirebaseInstanceId(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void delete(Promise promise) { - try { - Log.d(TAG, "Deleting instance id"); - FirebaseInstanceId - .getInstance() - .deleteInstanceId(); - promise.resolve(null); - } catch (IOException e) { - Log.e(TAG, e.getMessage()); - promise.reject("instance_id_error", e.getMessage()); - } - } - - @ReactMethod - public void get(Promise promise) { - String id = FirebaseInstanceId - .getInstance() - .getId(); - promise.resolve(id); - } - - @ReactMethod - public void getToken(String authorizedEntity, String scope, Promise promise) { - try { - String token = FirebaseInstanceId - .getInstance() - .getToken(authorizedEntity, scope); - Log.d(TAG, "Firebase token for " + authorizedEntity + ": " + token); - promise.resolve(token); - } catch (IOException e) { - promise.reject("iid/request-failed", "getToken request failed", e); - } - } - - @ReactMethod - public void deleteToken(String authorizedEntity, String scope, Promise promise) { - try { - FirebaseInstanceId - .getInstance() - .deleteToken(authorizedEntity, scope); - Log.d(TAG, "Firebase token deleted for " + authorizedEntity); - promise.resolve(null); - } catch (IOException e) { - promise.reject("iid/request-failed", "deleteToken request failed", e); - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceIdPackage.java b/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceIdPackage.java deleted file mode 100644 index 2d635dc6..00000000 --- a/android/src/main/java/io/invertase/firebase/instanceid/RNFirebaseInstanceIdPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.instanceid; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseInstanceIdPackage implements ReactPackage { - public RNFirebaseInstanceIdPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseInstanceId(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvites.java b/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvites.java deleted file mode 100644 index c3e7e530..00000000 --- a/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvites.java +++ /dev/null @@ -1,268 +0,0 @@ -package io.invertase.firebase.invites; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import android.util.Log; - -import com.facebook.react.bridge.ActivityEventListener; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableMapKeySetIterator; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.appinvite.AppInviteInvitation; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.firebase.appinvite.FirebaseAppInvite; -import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import com.google.firebase.dynamiclinks.PendingDynamicLinkData; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -public class RNFirebaseInvites extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener { - private static final String TAG = "RNFirebaseInvites"; - private static final int REQUEST_INVITE = 17517; - private boolean mInitialInvitationInitialized = false; - private String mInitialDeepLink = null; - private String mInitialInvitationId = null; - private Promise mPromise = null; - - public RNFirebaseInvites(ReactApplicationContext context) { - super(context); - getReactApplicationContext().addActivityEventListener(this); - } - - @Override - public String getName() { - return "RNFirebaseInvites"; - } - - @ReactMethod - public void getInitialInvitation(final Promise promise) { - if (mInitialInvitationInitialized) { - if (mInitialDeepLink != null || mInitialInvitationId != null) { - promise.resolve(buildInvitationMap(mInitialDeepLink, mInitialInvitationId)); - } else { - promise.resolve(null); - } - } else { - if (getCurrentActivity() != null) { - FirebaseDynamicLinks - .getInstance() - .getDynamicLink(getCurrentActivity().getIntent()) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null) { - FirebaseAppInvite invite = FirebaseAppInvite.getInvitation( - pendingDynamicLinkData); - if (invite == null) { - promise.resolve(null); - return; - } - - mInitialDeepLink = pendingDynamicLinkData - .getLink() - .toString(); - mInitialInvitationId = invite.getInvitationId(); - promise.resolve(buildInvitationMap( - mInitialDeepLink, - mInitialInvitationId - )); - } else { - promise.resolve(null); - } - mInitialInvitationInitialized = true; - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception e) { - Log.e(TAG, "getInitialInvitation: failed to resolve invitation", e); - promise.reject( - "invites/initial-invitation-error", - e.getMessage(), - e - ); - } - }); - } else { - Log.d(TAG, "getInitialInvitation: activity is null"); - promise.resolve(null); - } - } - } - - @ReactMethod - public void sendInvitation(ReadableMap invitationMap, Promise promise) { - if (!invitationMap.hasKey("message")) { - promise.reject( - "invites/invalid-invitation", - "The supplied invitation is missing a 'message' field" - ); - return; - } - if (!invitationMap.hasKey("title")) { - promise.reject( - "invites/invalid-invitation", - "The supplied invitation is missing a 'title' field" - ); - return; - } - - AppInviteInvitation.IntentBuilder ib = new AppInviteInvitation.IntentBuilder(invitationMap.getString( - "title")); - if (invitationMap.hasKey("androidMinimumVersionCode")) { - Double androidMinimumVersionCode = invitationMap.getDouble("androidMinimumVersionCode"); - ib = ib.setAndroidMinimumVersionCode(androidMinimumVersionCode.intValue()); - } - if (invitationMap.hasKey("callToActionText")) { - ib = ib.setCallToActionText(invitationMap.getString("callToActionText")); - } - if (invitationMap.hasKey("customImage")) { - ib = ib.setCustomImage(Uri.parse(invitationMap.getString("customImage"))); - } - if (invitationMap.hasKey("deepLink")) { - ib = ib.setDeepLink(Uri.parse(invitationMap.getString("deepLink"))); - } - if (invitationMap.hasKey("iosClientId")) { - ib = ib.setOtherPlatformsTargetApplication( - AppInviteInvitation.IntentBuilder.PlatformMode.PROJECT_PLATFORM_IOS, - invitationMap.getString("iosClientId") - ); - } - ib = ib.setMessage(invitationMap.getString("message")); - - // Android specific properties - if (invitationMap.hasKey("android")) { - ReadableMap androidMap = invitationMap.getMap("android"); - - if (androidMap.hasKey("additionalReferralParameters")) { - Map arpMap = new HashMap<>(); - ReadableMap arpReadableMap = androidMap.getMap("additionalReferralParameters"); - ReadableMapKeySetIterator iterator = arpReadableMap.keySetIterator(); - while (iterator.hasNextKey()) { - String key = iterator.nextKey(); - arpMap.put(key, arpReadableMap.getString(key)); - } - ib = ib.setAdditionalReferralParameters(arpMap); - } - if (androidMap.hasKey("emailHtmlContent")) { - ib = ib.setEmailHtmlContent(androidMap.getString("emailHtmlContent")); - } - if (androidMap.hasKey("emailSubject")) { - ib = ib.setEmailSubject(androidMap.getString("emailSubject")); - } - if (androidMap.hasKey("googleAnalyticsTrackingId")) { - ib = ib.setGoogleAnalyticsTrackingId(androidMap.getString("googleAnalyticsTrackingId")); - } - } - - Intent invitationIntent = ib.build(); - // Save the promise for later - this.mPromise = promise; - - // Start the intent - this - .getCurrentActivity() - .startActivityForResult(invitationIntent, REQUEST_INVITE); - } - - ////////////////////////////////////////////////////////////////////// - // Start ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - @Override - public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_INVITE) { - if (resultCode == Activity.RESULT_OK) { - String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data); - mPromise.resolve(Arguments.fromList(Arrays.asList(ids))); - } else if (resultCode == Activity.RESULT_CANCELED) { - mPromise.reject("invites/invitation-cancelled", "Invitation cancelled"); - } else { - mPromise.reject("invites/invitation-error", "Invitation failed to send"); - } - // Clear the promise - mPromise = null; - } - } - - @Override - public void onNewIntent(Intent intent) { - FirebaseDynamicLinks - .getInstance() - .getDynamicLink(intent) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null) { - FirebaseAppInvite invite = FirebaseAppInvite.getInvitation( - pendingDynamicLinkData); - if (invite == null) { - // this is a dynamic link, not an invitation - return; - } - - String deepLink = pendingDynamicLinkData - .getLink() - .toString(); - String invitationId = invite.getInvitationId(); - WritableMap invitationMap = buildInvitationMap( - deepLink, - invitationId - ); - Utils.sendEvent( - getReactApplicationContext(), - "invites_invitation_received", - invitationMap - ); - } - } - }); - } - ////////////////////////////////////////////////////////////////////// - // End ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////// - // Start LifecycleEventListener methods - ////////////////////////////////////////////////////////////////////// - @Override - public void onHostResume() { - // Not required for this module - } - - @Override - public void onHostPause() { - // Not required for this module - } - - @Override - public void onHostDestroy() { - mInitialDeepLink = null; - mInitialInvitationId = null; - mInitialInvitationInitialized = false; - } - ////////////////////////////////////////////////////////////////////// - // End LifecycleEventListener methods - ////////////////////////////////////////////////////////////////////// - - private WritableMap buildInvitationMap(String deepLink, String invitationId) { - WritableMap invitationMap = Arguments.createMap(); - invitationMap.putString("deepLink", deepLink); - invitationMap.putString("invitationId", invitationId); - - return invitationMap; - } -} diff --git a/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvitesPackage.java b/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvitesPackage.java deleted file mode 100644 index 23bd64c7..00000000 --- a/android/src/main/java/io/invertase/firebase/invites/RNFirebaseInvitesPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.invites; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseInvitesPackage implements ReactPackage { - public RNFirebaseInvitesPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseInvites(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java b/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java deleted file mode 100644 index fb4d90b3..00000000 --- a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java +++ /dev/null @@ -1,353 +0,0 @@ -package io.invertase.firebase.links; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import android.util.Log; - -import com.facebook.react.bridge.ActivityEventListener; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.appinvite.FirebaseAppInvite; -import com.google.firebase.dynamiclinks.DynamicLink; -import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import com.google.firebase.dynamiclinks.PendingDynamicLinkData; -import com.google.firebase.dynamiclinks.ShortDynamicLink; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -public class RNFirebaseLinks extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener { - private final static String TAG = RNFirebaseLinks.class.getCanonicalName(); - private String mInitialLink = null; - private boolean mInitialLinkInitialized = false; - - public RNFirebaseLinks(ReactApplicationContext reactContext) { - super(reactContext); - getReactApplicationContext().addActivityEventListener(this); - getReactApplicationContext().addLifecycleEventListener(this); - } - - @Override - public String getName() { - return "RNFirebaseLinks"; - } - - @ReactMethod - public void createDynamicLink(final ReadableMap linkData, final Promise promise) { - try { - DynamicLink.Builder builder = getDynamicLinkBuilder(linkData); - String link = builder - .buildDynamicLink() - .getUri() - .toString(); - Log.d(TAG, "created dynamic link: " + link); - promise.resolve(link); - } catch (Exception ex) { - Log.e(TAG, "create dynamic link failure " + ex.getMessage()); - promise.reject("links/failure", ex.getMessage(), ex); - } - } - - @ReactMethod - public void createShortDynamicLink( - final ReadableMap linkData, - final String type, - final Promise promise - ) { - try { - DynamicLink.Builder builder = getDynamicLinkBuilder(linkData); - Task shortLinkTask; - if ("SHORT".equals(type)) { - shortLinkTask = builder.buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT); - } else if ("UNGUESSABLE".equals(type)) { - shortLinkTask = builder.buildShortDynamicLink(ShortDynamicLink.Suffix.UNGUESSABLE); - } else { - shortLinkTask = builder.buildShortDynamicLink(); - } - - shortLinkTask.addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - String shortLink = task - .getResult() - .getShortLink() - .toString(); - Log.d(TAG, "created short dynamic link: " + shortLink); - promise.resolve(shortLink); - } else { - Log.e( - TAG, - "create short dynamic link failure " + task - .getException() - .getMessage() - ); - promise.reject( - "links/failure", - task - .getException() - .getMessage(), - task.getException() - ); - } - } - }); - } catch (Exception ex) { - Log.e(TAG, "create short dynamic link failure " + ex.getMessage()); - promise.reject("links/failure", ex.getMessage(), ex); - } - } - - @ReactMethod - public void getInitialLink(final Promise promise) { - if (mInitialLinkInitialized) { - promise.resolve(mInitialLink); - } else { - if (getCurrentActivity() != null) { - FirebaseDynamicLinks - .getInstance() - .getDynamicLink(getCurrentActivity().getIntent()) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null - && !isInvitation(pendingDynamicLinkData)) { - - mInitialLink = pendingDynamicLinkData - .getLink() - .toString(); - } - Log.d(TAG, "getInitialLink: link is: " + mInitialLink); - mInitialLinkInitialized = true; - promise.resolve(mInitialLink); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception e) { - Log.e(TAG, "getInitialLink: failed to resolve link", e); - promise.reject("link/initial-link-error", e.getMessage(), e); - } - }); - } else { - Log.d(TAG, "getInitialLink: activity is null"); - promise.resolve(null); - } - } - } - - ////////////////////////////////////////////////////////////////////// - // Start ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - @Override - public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { - // Not required for this module - } - - @Override - public void onNewIntent(Intent intent) { - FirebaseDynamicLinks - .getInstance() - .getDynamicLink(intent) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null - && !isInvitation(pendingDynamicLinkData)) { - String link = pendingDynamicLinkData - .getLink() - .toString(); - Utils.sendEvent( - getReactApplicationContext(), - "links_link_received", - link - ); - } - } - }); - } - ////////////////////////////////////////////////////////////////////// - // End ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////// - // Start LifecycleEventListener methods - ////////////////////////////////////////////////////////////////////// - @Override - public void onHostResume() { - // Not required for this module - } - - @Override - public void onHostPause() { - // Not required for this module - } - - @Override - public void onHostDestroy() { - mInitialLink = null; - mInitialLinkInitialized = false; - } - ////////////////////////////////////////////////////////////////////// - // End LifecycleEventListener methods - ////////////////////////////////////////////////////////////////////// - - // Looks at the internals of the link data to detect whether it's an invitation or not - private boolean isInvitation(PendingDynamicLinkData pendingDynamicLinkData) { - FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(pendingDynamicLinkData); - if (invite != null && invite.getInvitationId() != null && !invite - .getInvitationId() - .isEmpty()) { - return true; - } - return false; - } - - private DynamicLink.Builder getDynamicLinkBuilder(final ReadableMap linkData) { - DynamicLink.Builder builder = FirebaseDynamicLinks - .getInstance() - .createDynamicLink(); - try { - builder.setLink(Uri.parse(linkData.getString("link"))); - builder.setDynamicLinkDomain(linkData.getString("dynamicLinkDomain")); - setAnalyticsParameters(linkData.getMap("analytics"), builder); - setAndroidParameters(linkData.getMap("android"), builder); - setIosParameters(linkData.getMap("ios"), builder); - setITunesParameters(linkData.getMap("itunes"), builder); - setNavigationParameters(linkData.getMap("navigation"), builder); - setSocialParameters(linkData.getMap("social"), builder); - } catch (Exception e) { - Log.e(TAG, "error while building parameters " + e.getMessage()); - throw e; - } - return builder; - } - - private void setAnalyticsParameters( - final ReadableMap analyticsData, - final DynamicLink.Builder builder - ) { - DynamicLink.GoogleAnalyticsParameters.Builder analyticsParameters = new DynamicLink.GoogleAnalyticsParameters.Builder(); - - if (analyticsData.hasKey("campaign")) { - analyticsParameters.setCampaign(analyticsData.getString("campaign")); - } - if (analyticsData.hasKey("content")) { - analyticsParameters.setContent(analyticsData.getString("content")); - } - if (analyticsData.hasKey("medium")) { - analyticsParameters.setMedium(analyticsData.getString("medium")); - } - if (analyticsData.hasKey("source")) { - analyticsParameters.setSource(analyticsData.getString("source")); - } - if (analyticsData.hasKey("term")) { - analyticsParameters.setTerm(analyticsData.getString("term")); - } - builder.setGoogleAnalyticsParameters(analyticsParameters.build()); - } - - private void setAndroidParameters( - final ReadableMap androidData, - final DynamicLink.Builder builder - ) { - if (androidData.hasKey("packageName")) { - DynamicLink.AndroidParameters.Builder androidParameters = new DynamicLink.AndroidParameters.Builder( - androidData.getString("packageName")); - - if (androidData.hasKey("fallbackUrl")) { - androidParameters.setFallbackUrl(Uri.parse(androidData.getString("fallbackUrl"))); - } - if (androidData.hasKey("minimumVersion")) { - androidParameters.setMinimumVersion(Integer.parseInt(androidData.getString("minimumVersion"))); - } - builder.setAndroidParameters(androidParameters.build()); - } - } - - private void setIosParameters(final ReadableMap iosData, final DynamicLink.Builder builder) { - if (iosData.hasKey("bundleId")) { - DynamicLink.IosParameters.Builder iosParameters = - new DynamicLink.IosParameters.Builder(iosData.getString("bundleId")); - - if (iosData.hasKey("appStoreId")) { - iosParameters.setAppStoreId(iosData.getString("appStoreId")); - } - if (iosData.hasKey("customScheme")) { - iosParameters.setCustomScheme(iosData.getString("customScheme")); - } - if (iosData.hasKey("fallbackUrl")) { - iosParameters.setFallbackUrl(Uri.parse(iosData.getString("fallbackUrl"))); - } - if (iosData.hasKey("iPadBundleId")) { - iosParameters.setIpadBundleId(iosData.getString("iPadBundleId")); - } - if (iosData.hasKey("iPadFallbackUrl")) { - iosParameters.setIpadFallbackUrl(Uri.parse(iosData.getString("iPadFallbackUrl"))); - } - if (iosData.hasKey("minimumVersion")) { - iosParameters.setMinimumVersion(iosData.getString("minimumVersion")); - } - builder.setIosParameters(iosParameters.build()); - } - } - - private void setITunesParameters( - final ReadableMap itunesData, - final DynamicLink.Builder builder - ) { - DynamicLink.ItunesConnectAnalyticsParameters.Builder itunesParameters = new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); - - if (itunesData.hasKey("affiliateToken")) { - itunesParameters.setAffiliateToken(itunesData.getString("affiliateToken")); - } - if (itunesData.hasKey("campaignToken")) { - itunesParameters.setCampaignToken(itunesData.getString("campaignToken")); - } - if (itunesData.hasKey("providerToken")) { - itunesParameters.setProviderToken(itunesData.getString("providerToken")); - } - builder.setItunesConnectAnalyticsParameters(itunesParameters.build()); - } - - private void setNavigationParameters( - final ReadableMap navigationData, - final DynamicLink.Builder builder - ) { - DynamicLink.NavigationInfoParameters.Builder navigationParameters = new DynamicLink.NavigationInfoParameters.Builder(); - - if (navigationData.hasKey("forcedRedirectEnabled")) { - navigationParameters.setForcedRedirectEnabled(navigationData.getBoolean( - "forcedRedirectEnabled")); - } - builder.setNavigationInfoParameters(navigationParameters.build()); - } - - private void setSocialParameters( - final ReadableMap socialData, - final DynamicLink.Builder builder - ) { - DynamicLink.SocialMetaTagParameters.Builder socialParameters = new DynamicLink.SocialMetaTagParameters.Builder(); - - if (socialData.hasKey("descriptionText")) { - socialParameters.setDescription(socialData.getString("descriptionText")); - } - if (socialData.hasKey("imageUrl")) { - socialParameters.setImageUrl(Uri.parse(socialData.getString("imageUrl"))); - } - if (socialData.hasKey("title")) { - socialParameters.setTitle(socialData.getString("title")); - } - builder.setSocialMetaTagParameters(socialParameters.build()); - } -} diff --git a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinksPackage.java b/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinksPackage.java deleted file mode 100644 index bb068466..00000000 --- a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinksPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.links; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseLinksPackage implements ReactPackage { - public RNFirebaseLinksPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseLinks(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/BundleJSONConverter.java b/android/src/main/java/io/invertase/firebase/messaging/BundleJSONConverter.java deleted file mode 100644 index 56a4c2d6..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/BundleJSONConverter.java +++ /dev/null @@ -1,244 +0,0 @@ -package io.invertase.firebase.messaging; - -// taken from https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/main/java/com/facebook/internal/BundleJSONConverter.java - -/* - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - *

- * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, - * copy, modify, and distribute this software in source code or binary form for use - * in connection with the web services and APIs provided by Facebook. - *

- * As with any software that integrates with the Facebook platform, your use of - * this software is subject to the Facebook Developer Principles and Policies - * [http://developers.facebook.com/policy/]. This copyright notice shall be - * included in all copies or substantial portions of the software. - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -import android.os.Bundle; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * com.facebook.internal is solely for the use of other packages within the Facebook SDK for - * Android. Use of any of the classes in this package is unsupported, and they may be modified or - * removed without warning at any time. - *

- * A helper class that can round trip between JSON and Bundle objects that contains the types: - * Boolean, Integer, Long, Double, String - * If other types are found, an IllegalArgumentException is thrown. - */ -public class BundleJSONConverter { - private static final Map, Setter> SETTERS = new HashMap<>(); - - static { - SETTERS.put(Boolean.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - bundle.putBoolean(key, (Boolean) value); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - json.put(key, value); - } - }); - SETTERS.put(Integer.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - bundle.putInt(key, (Integer) value); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - json.put(key, value); - } - }); - SETTERS.put(Long.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - bundle.putLong(key, (Long) value); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - json.put(key, value); - } - }); - SETTERS.put(Double.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - bundle.putDouble(key, (Double) value); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - json.put(key, value); - } - }); - SETTERS.put(String.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - bundle.putString(key, (String) value); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - json.put(key, value); - } - }); - SETTERS.put(String[].class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - throw new IllegalArgumentException("Unexpected type from JSON"); - } - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - JSONArray jsonArray = new JSONArray(); - for (String stringValue : (String[]) value) { - jsonArray.put(stringValue); - } - json.put(key, jsonArray); - } - }); - - SETTERS.put(JSONArray.class, new Setter() { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException { - JSONArray jsonArray = (JSONArray) value; - // Assume an empty list is an ArrayList - if (jsonArray.length() == 0 || jsonArray.get(0) instanceof String) { - ArrayList stringArrayList = new ArrayList<>(); - for (int i = 0; i < jsonArray.length(); i++) { - stringArrayList.add((String) jsonArray.get(i)); - } - bundle.putStringArrayList(key, stringArrayList); - } else if (jsonArray.get(0) instanceof Integer) { - ArrayList integerArrayList = new ArrayList<>(); - for (int i = 0; i < jsonArray.length(); i++) { - integerArrayList.add((Integer) jsonArray.get(i)); - } - bundle.putIntegerArrayList(key, integerArrayList); - } else if (jsonArray.get(0) instanceof Boolean) { - boolean[] booleanArray = new boolean[jsonArray.length()]; - for (int i = 0; i < jsonArray.length(); i++) { - booleanArray[i] = (Boolean) jsonArray.get(i); - } - bundle.putBooleanArray(key, booleanArray); - } else if (jsonArray.get(0) instanceof Double) { - double[] doubleArray = new double[jsonArray.length()]; - for (int i = 0; i < jsonArray.length(); i++) { - doubleArray[i] = (Double) jsonArray.get(i); - } - bundle.putDoubleArray(key, doubleArray); - } else if (jsonArray.get(0) instanceof Long) { - long[] longArray = new long[jsonArray.length()]; - for (int i = 0; i < jsonArray.length(); i++) { - longArray[i] = (Long) jsonArray.get(i); - } - bundle.putLongArray(key, longArray); - } else if (jsonArray.get(0) instanceof JSONObject) { - ArrayList bundleArrayList = new ArrayList<>(); - for (int i = 0; i < jsonArray.length(); i++) { - bundleArrayList.add(convertToBundle((JSONObject) jsonArray.get(i))); - } - bundle.putSerializable(key, bundleArrayList); - } else { - throw new IllegalArgumentException("Unexpected type in an array: " + jsonArray - .get(0) - .getClass()); - } - } - - @Override - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException { - throw new IllegalArgumentException("JSONArray's are not supported in bundles."); - } - }); - } - - public static JSONObject convertToJSON(Bundle bundle) throws JSONException { - JSONObject json = new JSONObject(); - - for (String key : bundle.keySet()) { - Object value = bundle.get(key); - if (value == null) { - // Null is not supported. - continue; - } - - // Special case List as getClass would not work, since List is an interface - if (value instanceof List) { - JSONArray jsonArray = new JSONArray(); - List listValue = (List) value; - for (Object objValue : listValue) { - if (objValue instanceof String - || objValue instanceof Integer - || objValue instanceof Double - || objValue instanceof Long - || objValue instanceof Boolean) { - jsonArray.put(objValue); - } else if (objValue instanceof Bundle) { - jsonArray.put(convertToJSON((Bundle) objValue)); - } else { - throw new IllegalArgumentException("Unsupported type: " + objValue.getClass()); - } - } - json.put(key, jsonArray); - continue; - } - - // Special case Bundle as it's one way, on the return it will be JSONObject - if (value instanceof Bundle) { - json.put(key, convertToJSON((Bundle) value)); - continue; - } - - Setter setter = SETTERS.get(value.getClass()); - if (setter == null) { - throw new IllegalArgumentException("Unsupported type: " + value.getClass()); - } - setter.setOnJSON(json, key, value); - } - - return json; - } - - public static Bundle convertToBundle(JSONObject jsonObject) throws JSONException { - Bundle bundle = new Bundle(); - @SuppressWarnings("unchecked") - Iterator jsonIterator = jsonObject.keys(); - while (jsonIterator.hasNext()) { - String key = jsonIterator.next(); - Object value = jsonObject.get(key); - if (value == null || value == JSONObject.NULL) { - // Null is not supported. - continue; - } - - // Special case JSONObject as it's one way, on the return it would be Bundle. - if (value instanceof JSONObject) { - bundle.putBundle(key, convertToBundle((JSONObject) value)); - continue; - } - - Setter setter = SETTERS.get(value.getClass()); - if (setter == null) { - throw new IllegalArgumentException("Unsupported type: " + value.getClass()); - } - setter.setOnBundle(bundle, key, value); - } - - return bundle; - } - - public interface Setter { - public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException; - - public void setOnJSON(JSONObject json, String key, Object value) throws JSONException; - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/MessagingSerializer.java b/android/src/main/java/io/invertase/firebase/messaging/MessagingSerializer.java deleted file mode 100644 index 12df03c3..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/MessagingSerializer.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.invertase.firebase.messaging; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.messaging.RemoteMessage; - -import java.util.Map; - -public class MessagingSerializer { - public static WritableMap parseRemoteMessage(RemoteMessage message) { - WritableMap messageMap = Arguments.createMap(); - WritableMap dataMap = Arguments.createMap(); - - if (message.getCollapseKey() != null) { - messageMap.putString("collapseKey", message.getCollapseKey()); - } - - if (message.getData() != null) { - for (Map.Entry e : message - .getData() - .entrySet()) { - dataMap.putString(e.getKey(), e.getValue()); - } - } - messageMap.putMap("data", dataMap); - - if (message.getFrom() != null) { - messageMap.putString("from", message.getFrom()); - } - if (message.getMessageId() != null) { - messageMap.putString("messageId", message.getMessageId()); - } - if (message.getMessageType() != null) { - messageMap.putString("messageType", message.getMessageType()); - } - messageMap.putDouble("sentTime", message.getSentTime()); - if (message.getTo() != null) { - messageMap.putString("to", message.getTo()); - } - messageMap.putDouble("ttl", message.getTtl()); - - return messageMap; - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseBackgroundMessagingService.java b/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseBackgroundMessagingService.java deleted file mode 100644 index 1e0f69c4..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseBackgroundMessagingService.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.invertase.firebase.messaging; - -import android.content.Intent; -import android.os.Bundle; - -import com.facebook.react.HeadlessJsTaskService; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.jstasks.HeadlessJsTaskConfig; -import com.google.firebase.messaging.RemoteMessage; - -import javax.annotation.Nullable; - -public class RNFirebaseBackgroundMessagingService extends HeadlessJsTaskService { - @Override - protected @Nullable - HeadlessJsTaskConfig getTaskConfig(Intent intent) { - Bundle extras = intent.getExtras(); - if (extras != null) { - RemoteMessage message = intent.getParcelableExtra("message"); - WritableMap messageMap = MessagingSerializer.parseRemoteMessage(message); - return new HeadlessJsTaskConfig( - "RNFirebaseBackgroundMessage", - messageMap, - 60000, - false - ); - } - return null; - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseInstanceIdService.java b/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseInstanceIdService.java deleted file mode 100644 index af91257b..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseInstanceIdService.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.invertase.firebase.messaging; - -import android.util.Log; - -import com.google.firebase.iid.FirebaseInstanceIdService; - -public class RNFirebaseInstanceIdService extends FirebaseInstanceIdService { -// public static final String TOKEN_REFRESH_EVENT = "messaging-token-refresh"; - private static final String TAG = "RNFInstanceIdService"; - - // TODO now deprecated, remove in v6 - @Override - public void onTokenRefresh() { - Log.d(TAG, "DEPRECATED onTokenRefresh event received"); - // - // // Build an Intent to pass the token to the RN Application - // Intent tokenRefreshEvent = new Intent(TOKEN_REFRESH_EVENT); - // - // // Broadcast it so it is only available to the RN Application - // LocalBroadcastManager - // .getInstance(this) - // .sendBroadcast(tokenRefreshEvent); - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessaging.java b/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessaging.java deleted file mode 100644 index d0836e26..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessaging.java +++ /dev/null @@ -1,216 +0,0 @@ -package io.invertase.firebase.messaging; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.support.v4.app.NotificationManagerCompat; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; - -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableMapKeySetIterator; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.FirebaseApp; -import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.messaging.FirebaseMessaging; -import com.google.firebase.messaging.RemoteMessage; - -import java.io.IOException; - -import javax.annotation.Nonnull; - -import io.invertase.firebase.Utils; - -public class RNFirebaseMessaging extends ReactContextBaseJavaModule { - private static final String TAG = "RNFirebaseMessaging"; - - RNFirebaseMessaging(ReactApplicationContext context) { - super(context); - LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); - - // Subscribe to message events - localBroadcastManager.registerReceiver( - new MessageReceiver(), - new IntentFilter(RNFirebaseMessagingService.MESSAGE_EVENT) - ); - - // Subscribe to new token events - localBroadcastManager.registerReceiver( - new RefreshTokenReceiver(), - new IntentFilter(RNFirebaseMessagingService.NEW_TOKEN_EVENT) - ); - } - - @Override - public String getName() { - return "RNFirebaseMessaging"; - } - - @ReactMethod - public void getToken(Promise promise) { - try { - String senderId = FirebaseApp.getInstance().getOptions().getGcmSenderId(); - String token = FirebaseInstanceId - .getInstance() - .getToken(senderId, FirebaseMessaging.INSTANCE_ID_SCOPE); - promise.resolve(token); - } catch (Throwable e) { - e.printStackTrace(); - promise.reject("messaging/fcm-token-error", e.getMessage()); - } - } - - @ReactMethod - public void deleteToken(Promise promise) { - try { - String senderId = FirebaseApp.getInstance().getOptions().getGcmSenderId(); - FirebaseInstanceId.getInstance().deleteToken(senderId, FirebaseMessaging.INSTANCE_ID_SCOPE); - promise.resolve(null); - } catch (Throwable e) { - e.printStackTrace(); - promise.reject("messaging/fcm-token-error", e.getMessage()); - } - } - - @ReactMethod - public void requestPermission(Promise promise) { - promise.resolve(null); - } - - // Non Web SDK methods - @ReactMethod - public void hasPermission(Promise promise) { - Boolean enabled = NotificationManagerCompat - .from(getReactApplicationContext()) - .areNotificationsEnabled(); - promise.resolve(enabled); - } - - @ReactMethod - public void sendMessage(ReadableMap messageMap, Promise promise) { - if (!messageMap.hasKey("to")) { - promise.reject("messaging/invalid-message", "The supplied message is missing a 'to' field"); - return; - } - - RemoteMessage.Builder mb = new RemoteMessage.Builder(messageMap.getString("to")); - - if (messageMap.hasKey("collapseKey")) { - mb = mb.setCollapseKey(messageMap.getString("collapseKey")); - } - if (messageMap.hasKey("messageId")) { - mb = mb.setMessageId(messageMap.getString("messageId")); - } - if (messageMap.hasKey("messageType")) { - mb = mb.setMessageType(messageMap.getString("messageType")); - } - if (messageMap.hasKey("ttl")) { - mb = mb.setTtl(messageMap.getInt("ttl")); - } - if (messageMap.hasKey("data")) { - ReadableMap dataMap = messageMap.getMap("data"); - ReadableMapKeySetIterator iterator = dataMap.keySetIterator(); - while (iterator.hasNextKey()) { - String key = iterator.nextKey(); - mb = mb.addData(key, dataMap.getString(key)); - } - } - - FirebaseMessaging.getInstance().send(mb.build()); - - // TODO: Listen to onMessageSent and onSendError for better feedback? - promise.resolve(null); - } - - @ReactMethod - public void subscribeToTopic(String topic, final Promise promise) { - FirebaseMessaging - .getInstance() - .subscribeToTopic(topic) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "subscribeToTopic:onComplete:success"); - promise.resolve(null); - } else { - Exception exception = task.getException(); - Log.e(TAG, "subscribeToTopic:onComplete:failure", exception); - promise.reject(exception); - } - } - }); - } - - @ReactMethod - public void unsubscribeFromTopic(String topic, final Promise promise) { - FirebaseMessaging - .getInstance() - .unsubscribeFromTopic(topic) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@Nonnull Task task) { - if (task.isSuccessful()) { - Log.d(TAG, "unsubscribeFromTopic:onComplete:success"); - promise.resolve(null); - } else { - Exception exception = task.getException(); - Log.e(TAG, "unsubscribeFromTopic:onComplete:failure", exception); - promise.reject(exception); - } - } - }); - } - - private class MessageReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (getReactApplicationContext().hasActiveCatalystInstance()) { - Log.d(TAG, "Received new message"); - - RemoteMessage message = intent.getParcelableExtra("message"); - WritableMap messageMap = MessagingSerializer.parseRemoteMessage(message); - - Utils.sendEvent(getReactApplicationContext(), "messaging_message_received", messageMap); - } - } - } - - private class RefreshTokenReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (getReactApplicationContext().hasActiveCatalystInstance()) { - Log.d(TAG, "Received new messaging token."); - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - String token = null; - String senderId = FirebaseApp.getInstance().getOptions().getGcmSenderId(); - - try { - token = FirebaseInstanceId - .getInstance() - .getToken(senderId, FirebaseMessaging.INSTANCE_ID_SCOPE); - } catch (IOException e) { - Log.d(TAG, "onNewToken error", e); - } - - if (token != null) { - Log.d(TAG, "Sending new messaging token event."); - Utils.sendEvent(getReactApplicationContext(), "messaging_token_refreshed", token); - } - } - }); - - thread.start(); - } - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingPackage.java b/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingPackage.java deleted file mode 100644 index 6457c897..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.messaging; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseMessagingPackage implements ReactPackage { - public RNFirebaseMessagingPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseMessaging(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingService.java b/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingService.java deleted file mode 100644 index b99e3379..00000000 --- a/android/src/main/java/io/invertase/firebase/messaging/RNFirebaseMessagingService.java +++ /dev/null @@ -1,75 +0,0 @@ -package io.invertase.firebase.messaging; - -import android.content.Intent; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; - -import com.facebook.react.HeadlessJsTaskService; -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; - -import io.invertase.firebase.Utils; - -public class RNFirebaseMessagingService extends FirebaseMessagingService { - private static final String TAG = "RNFMessagingService"; - - public static final String MESSAGE_EVENT = "messaging-message"; - public static final String NEW_TOKEN_EVENT = "messaging-token-refresh"; - public static final String REMOTE_NOTIFICATION_EVENT = "notifications-remote-notification"; - - @Override - public void onNewToken(String token) { - Log.d(TAG, "onNewToken event received"); - - Intent newTokenEvent = new Intent(NEW_TOKEN_EVENT); - LocalBroadcastManager - .getInstance(this) - .sendBroadcast(newTokenEvent); - } - - @Override - public void onMessageReceived(RemoteMessage message) { - Log.d(TAG, "onMessageReceived event received"); - - if (message.getNotification() != null) { - // It's a notification, pass to the Notifications module - Intent notificationEvent = new Intent(REMOTE_NOTIFICATION_EVENT); - notificationEvent.putExtra("notification", message); - - // Broadcast it to the (foreground) RN Application - LocalBroadcastManager - .getInstance(this) - .sendBroadcast(notificationEvent); - } else { - // It's a data message - // If the app is in the foreground we send it to the Messaging module - if (Utils.isAppInForeground(this.getApplicationContext())) { - Intent messagingEvent = new Intent(MESSAGE_EVENT); - messagingEvent.putExtra("message", message); - // Broadcast it so it is only available to the RN Application - LocalBroadcastManager - .getInstance(this) - .sendBroadcast(messagingEvent); - } else { - try { - // If the app is in the background we send it to the Headless JS Service - Intent headlessIntent = new Intent( - this.getApplicationContext(), - RNFirebaseBackgroundMessagingService.class - ); - headlessIntent.putExtra("message", message); - this - .getApplicationContext() - .startService(headlessIntent); - HeadlessJsTaskService.acquireWakeLockNow(this.getApplicationContext()); - } catch (IllegalStateException ex) { - Log.e( - TAG, - "Background messages will only work if the message priority is set to 'high'", - ex - ); - } - } - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/DisplayNotificationTask.java b/android/src/main/java/io/invertase/firebase/notifications/DisplayNotificationTask.java deleted file mode 100644 index 2195f110..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/DisplayNotificationTask.java +++ /dev/null @@ -1,580 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.RemoteInput; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import io.invertase.firebase.Utils; - -public class DisplayNotificationTask extends AsyncTask { - private static final String TAG = "DisplayNotificationTask"; - private final WeakReference contextWeakReference; - private final WeakReference reactContextWeakReference; - - private final Promise promise; - private final Bundle notification; - private final NotificationManager notificationManager; - - DisplayNotificationTask( - Context context, ReactApplicationContext reactContext, - NotificationManager notificationManager, - Bundle notification, Promise promise - ) { - this.contextWeakReference = new WeakReference<>(context); - this.reactContextWeakReference = new WeakReference<>(reactContext); - - this.promise = promise; - this.notification = notification; - this.notificationManager = notificationManager; - } - - @Override - protected void onPostExecute(Void result) { - contextWeakReference.clear(); - reactContextWeakReference.clear(); - } - - @Override - protected Void doInBackground(Void... voids) { - Context context = contextWeakReference.get(); - if (context == null) return null; - - try { - Class intentClass = getMainActivityClass(context); - - if (intentClass == null) { - if (promise != null) { - promise.reject( - "notification/display_notification_error", - "Could not find main activity class" - ); - } - return null; - } - - Bundle android = notification.getBundle("android"); - String notificationId = notification.getString("notificationId"); - - NotificationCompat.Builder nb; - try { - String channelId = android.getString("channelId"); - nb = new NotificationCompat.Builder(context, channelId); - } catch (Throwable t) { - // thrown if v4 android support library < 26 - nb = new NotificationCompat.Builder(context); - } - - if (notification.containsKey("body")) { - nb = nb.setContentText(notification.getString("body")); - } - - if (notification.containsKey("data")) { - nb = nb.setExtras(notification.getBundle("data")); - } - - if (notification.containsKey("sound")) { - Uri sound = RNFirebaseNotificationManager.getSound( - context, - notification.getString("sound") - ); - nb = nb.setSound(sound); - } - - if (notification.containsKey("subtitle")) { - nb = nb.setSubText(notification.getString("subtitle")); - } - - if (notification.containsKey("title")) { - nb = nb.setContentTitle(notification.getString("title")); - } - - if (android.containsKey("autoCancel")) { - nb = nb.setAutoCancel(android.getBoolean("autoCancel")); - } - - if (android.containsKey("badgeIconType") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - Double badgeIconType = android.getDouble("badgeIconType"); - try { - nb = nb.setBadgeIconType(badgeIconType.intValue()); - } catch (Throwable t) { - // thrown if v4 android support library < 26 - // do nothing - } - } - - if (android.containsKey("bigPicture")) { - Bundle bigPicture = android.getBundle("bigPicture"); - NotificationCompat.BigPictureStyle bp = new NotificationCompat.BigPictureStyle(); - Bitmap picture = getBitmap(bigPicture.getString("picture")); - - if (picture != null) { - bp = bp.bigPicture(picture); - } - - if (bigPicture.containsKey("largeIcon")) { - Bitmap largeIcon = getBitmap(bigPicture.getString("largeIcon")); - if (largeIcon != null) { - bp = bp.bigLargeIcon(largeIcon); - } - } - - if (bigPicture.containsKey("contentTitle")) { - bp = bp.setBigContentTitle(bigPicture.getString("contentTitle")); - } - - if (bigPicture.containsKey("summaryText")) { - bp = bp.setSummaryText(bigPicture.getString("summaryText")); - } - - nb = nb.setStyle(bp); - } - - if (android.containsKey("bigText")) { - Bundle bigText = android.getBundle("bigText"); - - NotificationCompat.BigTextStyle bt = new NotificationCompat.BigTextStyle(); - bt.bigText(bigText.getString("text")); - if (bigText.containsKey("contentTitle")) { - bt = bt.setBigContentTitle(bigText.getString("contentTitle")); - } - if (bigText.containsKey("summaryText")) { - bt = bt.setSummaryText(bigText.getString("summaryText")); - } - nb = nb.setStyle(bt); - } - - if (android.containsKey("category")) { - nb = nb.setCategory(android.getString("category")); - } - - if (android.containsKey("color")) { - String color = android.getString("color"); - nb = nb.setColor(Color.parseColor(color)); - } - - if (android.containsKey("colorized") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - try { - nb = nb.setColorized(android.getBoolean("colorized")); - } catch (Throwable t) { - // thrown if v4 android support library < 26 - // do nothing - } - } - - if (android.containsKey("contentInfo")) { - nb = nb.setContentInfo(android.getString("contentInfo")); - } - - if (android.containsKey("defaults")) { - Double defaultValues = android.getDouble("defaults"); - int defaults = defaultValues.intValue(); - - if (defaults == 0) { - ArrayList defaultsArray = android.getIntegerArrayList("defaults"); - if (defaultsArray != null) { - for (Integer defaultValue : defaultsArray) { - defaults |= defaultValue; - } - } - } - - nb = nb.setDefaults(defaults); - } - - if (android.containsKey("group")) { - nb = nb.setGroup(android.getString("group")); - } - - if (android.containsKey("groupAlertBehaviour") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - Double groupAlertBehaviour = android.getDouble("groupAlertBehaviour"); - try { - nb = nb.setGroupAlertBehavior(groupAlertBehaviour.intValue()); - } catch (Throwable t) { - // thrown if v4 android support library < 26 - // do nothing - } - } - - if (android.containsKey("groupSummary")) { - nb = nb.setGroupSummary(android.getBoolean("groupSummary")); - } - - if (android.containsKey("largeIcon")) { - Bitmap largeIcon = getBitmap(android.getString("largeIcon")); - if (largeIcon != null) { - nb = nb.setLargeIcon(largeIcon); - } - } - - if (android.containsKey("lights")) { - Bundle lights = android.getBundle("lights"); - Double argb = lights.getDouble("argb"); - Double onMs = lights.getDouble("onMs"); - Double offMs = lights.getDouble("offMs"); - nb = nb.setLights(argb.intValue(), onMs.intValue(), offMs.intValue()); - } - - if (android.containsKey("localOnly")) { - nb = nb.setLocalOnly(android.getBoolean("localOnly")); - } - - if (android.containsKey("number")) { - Double number = android.getDouble("number"); - nb = nb.setNumber(number.intValue()); - } - - if (android.containsKey("ongoing")) { - nb = nb.setOngoing(android.getBoolean("ongoing")); - } - - if (android.containsKey("onlyAlertOnce")) { - nb = nb.setOnlyAlertOnce(android.getBoolean("onlyAlertOnce")); - } - - if (android.containsKey("people")) { - List people = android.getStringArrayList("people"); - if (people != null) { - for (String person : people) { - nb = nb.addPerson(person); - } - } - } - - if (android.containsKey("priority")) { - Double priority = android.getDouble("priority"); - nb = nb.setPriority(priority.intValue()); - } - - if (android.containsKey("progress")) { - Bundle progress = android.getBundle("progress"); - Double max = progress.getDouble("max"); - Double progressI = progress.getDouble("progress"); - nb = nb.setProgress( - max.intValue(), - progressI.intValue(), - progress.getBoolean("indeterminate") - ); - } - - // TODO: Public version of notification - /* if (android.containsKey("publicVersion")) { - nb = nb.setPublicVersion(); - } */ - - if (android.containsKey("remoteInputHistory")) { - nb = nb.setRemoteInputHistory(android.getStringArray("remoteInputHistory")); - } - - if (android.containsKey("shortcutId") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - try { - nb = nb.setShortcutId(android.getString("shortcutId")); - } catch (Throwable t) { - // thrown if v4 android support library < 26 - // do nothing - } - } - - if (android.containsKey("showWhen")) { - nb = nb.setShowWhen(android.getBoolean("showWhen")); - } - - if (android.containsKey("smallIcon")) { - Bundle smallIcon = android.getBundle("smallIcon"); - int smallIconResourceId = getIcon(smallIcon.getString("icon")); - if (smallIconResourceId != 0) { - if (smallIcon.containsKey("level")) { - Double level = smallIcon.getDouble("level"); - nb = nb.setSmallIcon(smallIconResourceId, level.intValue()); - } else { - nb = nb.setSmallIcon(smallIconResourceId); - } - } - } - - if (android.containsKey("sortKey")) { - nb = nb.setSortKey(android.getString("sortKey")); - } - - if (android.containsKey("ticker")) { - nb = nb.setTicker(android.getString("ticker")); - } - - if (android.containsKey("timeoutAfter")) { - Double timeoutAfter = android.getDouble("timeoutAfter"); - nb = nb.setTimeoutAfter(timeoutAfter.longValue()); - } - - if (android.containsKey("usesChronometer")) { - nb = nb.setUsesChronometer(android.getBoolean("usesChronometer")); - } - - if (android.containsKey("vibrate")) { - ArrayList vibrate = android.getIntegerArrayList("vibrate"); - if (vibrate != null) { - long[] vibrateArray = new long[vibrate.size()]; - for (int i = 0; i < vibrate.size(); i++) { - vibrateArray[i] = vibrate - .get(i) - .longValue(); - } - nb = nb.setVibrate(vibrateArray); - } - } - - if (android.containsKey("visibility")) { - Double visibility = android.getDouble("visibility"); - nb = nb.setVisibility(visibility.intValue()); - } - - if (android.containsKey("when")) { - Double when = android.getDouble("when"); - nb = nb.setWhen(when.longValue()); - } - - // Build any actions - if (android.containsKey("actions")) { - List actions = (List) android.getSerializable("actions"); - for (Bundle a : actions) { - NotificationCompat.Action action = createAction(context, a, intentClass, notification); - nb = nb.addAction(action); - } - } - - String tag = null; - if (android.containsKey("tag")) { - tag = android.getString("tag"); - } - - // Create the notification intent - PendingIntent contentIntent = createIntent( - context, - intentClass, - notification, - android.getString("clickAction") - ); - - nb = nb.setContentIntent(contentIntent); - - // Build the notification and send it - Notification builtNotification = nb.build(); - notificationManager.notify(tag, notificationId.hashCode(), builtNotification); - - if (reactContextWeakReference.get() != null) { - Utils.sendEvent( - reactContextWeakReference.get(), - "notifications_notification_displayed", - Arguments.fromBundle(notification) - ); - } - - if (promise != null) { - promise.resolve(null); - } - - } catch (Exception e) { - Log.e(TAG, "Failed to send notification", e); - if (promise != null) { - promise.reject("notification/display_notification_error", "Could not send notification", e); - } - } - - return null; - } - - private NotificationCompat.Action createAction( - Context context, - Bundle action, - Class intentClass, - Bundle notification - ) { - String actionKey = action.getString("action"); - boolean showUserInterface = action.containsKey("showUserInterface") && action.getBoolean( - "showUserInterface"); - - PendingIntent actionIntent = showUserInterface ? - createIntent(context, intentClass, notification, actionKey) : - createBroadcastIntent(context, notification, actionKey); - - int icon = getIcon(action.getString("icon")); - String title = action.getString("title"); - - NotificationCompat.Action.Builder ab = new NotificationCompat.Action.Builder( - icon, - title, - actionIntent - ); - - if (action.containsKey("allowGeneratedReplies")) { - ab = ab.setAllowGeneratedReplies(action.getBoolean("allowGeneratedReplies")); - } - - if (action.containsKey("remoteInputs")) { - List remoteInputs = (List) action.getSerializable("remoteInputs"); - for (Bundle ri : remoteInputs) { - RemoteInput remoteInput = createRemoteInput(ri); - ab = ab.addRemoteInput(remoteInput); - } - } - - // TODO: SemanticAction and ShowsUserInterface only available on v28? - // if (action.containsKey("semanticAction")) { - // Double semanticAction = action.getDouble("semanticAction"); - // ab = ab.setSemanticAction(semanticAction.intValue()); - // } - // if (action.containsKey("showsUserInterface")) { - // ab = ab.setShowsUserInterface(action.getBoolean("showsUserInterface")); - // } - - return ab.build(); - } - - private PendingIntent createIntent( - Context context, - Class intentClass, - Bundle notification, - String action - ) { - Intent intent = new Intent(context, intentClass); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - intent.putExtras(notification); - - if (action != null) { - intent.setAction(action); - } - - String notificationId = notification.getString("notificationId"); - return PendingIntent.getActivity( - context, - notificationId.hashCode(), - intent, - PendingIntent.FLAG_UPDATE_CURRENT - ); - } - - private PendingIntent createBroadcastIntent(Context context, Bundle notification, String action) { - String notificationId = notification.getString("notificationId") + action; - Intent intent = new Intent(context, RNFirebaseBackgroundNotificationActionReceiver.class); - - intent.putExtra("action", action); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - intent.putExtra("notification", notification); - intent.setAction("io.invertase.firebase.notifications.BackgroundAction"); - - return PendingIntent.getBroadcast( - context, - notificationId.hashCode(), - intent, - PendingIntent.FLAG_UPDATE_CURRENT - ); - } - - private RemoteInput createRemoteInput(Bundle remoteInput) { - String resultKey = remoteInput.getString("resultKey"); - RemoteInput.Builder rb = new RemoteInput.Builder(resultKey); - - if (remoteInput.containsKey("allowedDataTypes")) { - List allowedDataTypes = (List) remoteInput.getSerializable("allowedDataTypes"); - for (Bundle adt : allowedDataTypes) { - rb.setAllowDataType(adt.getString("mimeType"), adt.getBoolean("allow")); - } - } - - if (remoteInput.containsKey("allowFreeFormInput")) { - rb.setAllowFreeFormInput(remoteInput.getBoolean("allowFreeFormInput")); - } - - if (remoteInput.containsKey("choices")) { - List choices = remoteInput.getStringArrayList("choices"); - rb.setChoices(choices.toArray(new String[choices.size()])); - } - - if (remoteInput.containsKey("label")) { - rb.setLabel(remoteInput.getString("label")); - } - - return rb.build(); - } - - private Bitmap getBitmap(String image) { - if (image.startsWith("http://") || image.startsWith("https://")) { - return getBitmapFromUrl(image); - } - - if (image.startsWith("file://")) { - return BitmapFactory.decodeFile(image.replace("file://", "")); - } - - int largeIconResId = getIcon(image); - return BitmapFactory.decodeResource( - contextWeakReference.get().getResources(), - largeIconResId - ); - } - - private Bitmap getBitmapFromUrl(String imageUrl) { - try { - HttpURLConnection connection = (HttpURLConnection) new URL(imageUrl).openConnection(); - connection.setDoInput(true); - connection.connect(); - return BitmapFactory.decodeStream(connection.getInputStream()); - } catch (IOException e) { - Log.e(TAG, "Failed to get bitmap for url: " + imageUrl, e); - return null; - } - } - - private int getIcon(String icon) { - int resourceId = RNFirebaseNotificationManager.getResourceId( - contextWeakReference.get(), - "mipmap", - icon - ); - - if (resourceId == 0) { - resourceId = RNFirebaseNotificationManager.getResourceId( - contextWeakReference.get(), - "drawable", - icon - ); - } - - return resourceId; - } - - private Class getMainActivityClass(Context context) { - String packageName = context.getPackageName(); - Intent launchIntent = context - .getPackageManager() - .getLaunchIntentForPackage(packageName); - - try { - return Class.forName(launchIntent.getComponent().getClassName()); - } catch (ClassNotFoundException e) { - Log.e(TAG, "Failed to get main activity class", e); - return null; - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionReceiver.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionReceiver.java deleted file mode 100644 index 67379203..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionReceiver.java +++ /dev/null @@ -1,69 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.RemoteInput; - -import com.facebook.react.HeadlessJsTaskService; -import com.facebook.react.ReactApplication; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.WritableMap; - -import io.invertase.firebase.Utils; - -public class RNFirebaseBackgroundNotificationActionReceiver extends BroadcastReceiver { - static boolean isBackgroundNotficationIntent(Intent intent) { - return intent.getExtras() != null && intent.hasExtra("action") && intent.hasExtra("notification"); - } - - static WritableMap toNotificationOpenMap(Intent intent) { - Bundle extras = intent.getExtras(); - WritableMap notificationMap = Arguments.makeNativeMap(extras.getBundle("notification")); - WritableMap notificationOpenMap = Arguments.createMap(); - notificationOpenMap.putString("action", extras.getString("action")); - notificationOpenMap.putMap("notification", notificationMap); - - Bundle extrasBundle = extras.getBundle("results"); - if (extrasBundle != null) { - WritableMap results = Arguments.makeNativeMap(extrasBundle); - notificationOpenMap.putMap("results", results); - } - - return notificationOpenMap; - } - - @Override - public void onReceive(Context context, Intent intent) { - if (!isBackgroundNotficationIntent(intent)) { - return; - } - - if (Utils.isAppInForeground(context)) { - WritableMap notificationOpenMap = toNotificationOpenMap(intent); - - ReactApplication reactApplication = (ReactApplication) context.getApplicationContext(); - ReactContext reactContext = reactApplication - .getReactNativeHost() - .getReactInstanceManager() - .getCurrentReactContext(); - - Utils.sendEvent(reactContext, "notifications_notification_opened", notificationOpenMap); - } else { - Intent serviceIntent = new Intent( - context, - RNFirebaseBackgroundNotificationActionsService.class - ); - serviceIntent.putExtras(intent.getExtras()); - - Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); - if (remoteInput != null) { - serviceIntent.putExtra("results", remoteInput); - } - context.startService(serviceIntent); - HeadlessJsTaskService.acquireWakeLockNow(context); - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionsService.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionsService.java deleted file mode 100644 index 56f702d4..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseBackgroundNotificationActionsService.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.content.Intent; - -import com.facebook.react.HeadlessJsTaskService; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.jstasks.HeadlessJsTaskConfig; - -import javax.annotation.Nullable; - -import static io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver.isBackgroundNotficationIntent; -import static io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver.toNotificationOpenMap; - -public class RNFirebaseBackgroundNotificationActionsService extends HeadlessJsTaskService { - @Override - protected @Nullable - HeadlessJsTaskConfig getTaskConfig(Intent intent) { - if (isBackgroundNotficationIntent(intent)) { - WritableMap notificationOpenMap = toNotificationOpenMap(intent); - - return new HeadlessJsTaskConfig( - "RNFirebaseBackgroundNotificationAction", - notificationOpenMap, - 60000, - true - ); - } - return null; - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationManager.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationManager.java deleted file mode 100644 index 25a04427..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationManager.java +++ /dev/null @@ -1,492 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.app.AlarmManager; -import android.app.NotificationChannel; -import android.app.NotificationChannelGroup; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.service.notification.StatusBarNotification; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; -import io.invertase.firebase.messaging.BundleJSONConverter; - -class RNFirebaseNotificationManager { - static final String SCHEDULED_NOTIFICATION_EVENT = "notifications-scheduled-notification"; - private static final String PREFERENCES_KEY = "RNFNotifications"; - private static final String TAG = "RNFNotificationManager"; - private AlarmManager alarmManager; - private Context context; - private ReactApplicationContext reactContext; - private NotificationManager notificationManager; - private SharedPreferences preferences; - - RNFirebaseNotificationManager(ReactApplicationContext reactContext) { - this(reactContext.getApplicationContext()); - this.reactContext = reactContext; - } - - RNFirebaseNotificationManager(Context context) { - this.alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - this.context = context; - this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - this.preferences = context.getSharedPreferences(PREFERENCES_KEY, Context.MODE_PRIVATE); - } - - static int getResourceId(Context context, String type, String image) { - return context - .getResources() - .getIdentifier(image, type, context.getPackageName()); - } - - static Uri getSound(Context context, String sound) { - if (sound == null) { - return null; - } else if (sound.contains("://")) { - return Uri.parse(sound); - } else if (sound.equalsIgnoreCase("default")) { - return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - } else { - int soundResourceId = getResourceId(context, "raw", sound); - if (soundResourceId == 0) { - soundResourceId = getResourceId(context, "raw", sound.substring(0, sound.lastIndexOf('.'))); - } - return Uri.parse("android.resource://" + context.getPackageName() + "/" + soundResourceId); - } - } - - void cancelAllNotifications(Promise promise) { - try { - Map notifications = preferences.getAll(); - - for (String notificationId : notifications.keySet()) { - cancelAlarm(notificationId); - } - - preferences - .edit() - .clear() - .apply(); - - promise.resolve(null); - } catch (SecurityException e) { - // TODO: Identify what these situations are - // In some devices/situations cancelAllLocalNotifications can throw a SecurityException. - Log.e(TAG, e.getMessage()); - promise.reject( - "notification/cancel_notifications_error", - "Could not cancel notifications", - e - ); - } - } - - void cancelNotification(String notificationId, Promise promise) { - try { - cancelAlarm(notificationId); - preferences - .edit() - .remove(notificationId) - .apply(); - promise.resolve(null); - } catch (SecurityException e) { - // TODO: Identify what these situations are - // In some devices/situations cancelAllLocalNotifications can throw a SecurityException. - Log.e(TAG, e.getMessage()); - promise.reject("notification/cancel_notification_error", "Could not cancel notifications", e); - } - } - - void createChannel(ReadableMap channelMap) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel = parseChannelMap(channelMap); - notificationManager.createNotificationChannel(channel); - } - } - - void createChannelGroup(ReadableMap channelGroupMap) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannelGroup channelGroup = parseChannelGroupMap(channelGroupMap); - notificationManager.createNotificationChannelGroup(channelGroup); - } - } - - void createChannelGroups(ReadableArray channelGroupsArray) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - List channelGroups = new ArrayList<>(); - for (int i = 0; i < channelGroupsArray.size(); i++) { - NotificationChannelGroup channelGroup = parseChannelGroupMap(channelGroupsArray.getMap(i)); - channelGroups.add(channelGroup); - } - notificationManager.createNotificationChannelGroups(channelGroups); - } - } - - void createChannels(ReadableArray channelsArray) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - List channels = new ArrayList<>(); - for (int i = 0; i < channelsArray.size(); i++) { - NotificationChannel channel = parseChannelMap(channelsArray.getMap(i)); - channels.add(channel); - } - notificationManager.createNotificationChannels(channels); - } - } - - void deleteChannelGroup(String groupId) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - notificationManager.deleteNotificationChannelGroup(groupId); - } - } - - void deleteChannel(String channelId) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - notificationManager.deleteNotificationChannel(channelId); - } - } - - void displayNotification(ReadableMap notification, Promise promise) { - Bundle notificationBundle = Arguments.toBundle(notification); - displayNotification(notificationBundle, promise); - } - - void displayScheduledNotification(Bundle notification) { - // If this isn't a repeated notification, clear it from the scheduled notifications list - if (!notification - .getBundle("schedule") - .containsKey("repeated") - || !notification - .getBundle("schedule") - .getBoolean("repeated")) { - String notificationId = notification.getString("notificationId"); - preferences - .edit() - .remove(notificationId) - .apply(); - } - - if (Utils.isAppInForeground(context)) { - // If the app is in the foreground, broadcast the notification to the RN Application - // It is up to the JS to decide whether to display the notification - Intent scheduledNotificationEvent = new Intent(SCHEDULED_NOTIFICATION_EVENT); - scheduledNotificationEvent.putExtra("notification", notification); - LocalBroadcastManager - .getInstance(context) - .sendBroadcast(scheduledNotificationEvent); - } else { - // If the app is in the background, then we display it automatically - displayNotification(notification, null); - } - } - - ArrayList getScheduledNotifications() { - ArrayList array = new ArrayList<>(); - - Map notifications = preferences.getAll(); - - for (String notificationId : notifications.keySet()) { - try { - JSONObject json = new JSONObject((String) notifications.get(notificationId)); - Bundle bundle = BundleJSONConverter.convertToBundle(json); - array.add(bundle); - } catch (JSONException e) { - Log.e(TAG, e.getMessage()); - } - } - return array; - } - - void removeAllDeliveredNotifications(Promise promise) { - notificationManager.cancelAll(); - promise.resolve(null); - } - - void removeDeliveredNotification(String notificationId, Promise promise) { - notificationManager.cancel(notificationId.hashCode()); - promise.resolve(null); - } - - void removeDeliveredNotificationsByTag(String tag, Promise promise) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - StatusBarNotification[] statusBarNotifications = notificationManager.getActiveNotifications(); - for (StatusBarNotification statusBarNotification : statusBarNotifications) { - if (tag.equals(statusBarNotification.getTag())) { - notificationManager.cancel(statusBarNotification.getTag(), statusBarNotification.getId()); - } - } - } - - promise.resolve(null); - } - - void rescheduleNotifications() { - ArrayList bundles = getScheduledNotifications(); - for (Bundle bundle : bundles) { - scheduleNotification(bundle, null); - } - } - - void scheduleNotification(ReadableMap notification, Promise promise) { - Bundle notificationBundle = Arguments.toBundle(notification); - - scheduleNotification(notificationBundle, promise); - } - - private void cancelAlarm(String notificationId) { - Intent notificationIntent = new Intent(context, RNFirebaseNotificationReceiver.class); - PendingIntent pendingIntent = PendingIntent.getBroadcast( - context, - notificationId.hashCode(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT - ); - alarmManager.cancel(pendingIntent); - } - - private void displayNotification(Bundle notification, Promise promise) { - new DisplayNotificationTask( - context, - reactContext, - notificationManager, - notification, - promise - ).execute(); - } - - private NotificationChannelGroup parseChannelGroupMap(ReadableMap channelGroupMap) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - String groupId = channelGroupMap.getString("groupId"); - String name = channelGroupMap.getString("name"); - - return new NotificationChannelGroup(groupId, name); - } - return null; - } - - private NotificationChannel parseChannelMap(ReadableMap channelMap) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - String channelId = channelMap.getString("channelId"); - String name = channelMap.getString("name"); - int importance = channelMap.getInt("importance"); - - NotificationChannel channel = new NotificationChannel(channelId, name, importance); - if (channelMap.hasKey("bypassDnd")) { - channel.setBypassDnd(channelMap.getBoolean("bypassDnd")); - } - if (channelMap.hasKey("description")) { - channel.setDescription(channelMap.getString("description")); - } - if (channelMap.hasKey("group")) { - channel.setGroup(channelMap.getString("group")); - } - if (channelMap.hasKey("lightColor")) { - String lightColor = channelMap.getString("lightColor"); - channel.setLightColor(Color.parseColor(lightColor)); - } - if (channelMap.hasKey("lightsEnabled")) { - channel.enableLights(channelMap.getBoolean("lightsEnabled")); - } - if (channelMap.hasKey("lockScreenVisibility")) { - channel.setLockscreenVisibility(channelMap.getInt("lockScreenVisibility")); - } - if (channelMap.hasKey("showBadge")) { - channel.setShowBadge(channelMap.getBoolean("showBadge")); - } - if (channelMap.hasKey("sound")) { - Uri sound = getSound(context, channelMap.getString("sound")); - channel.setSound(sound, null); - } - if (channelMap.hasKey("vibrationEnabled")) { - channel.enableVibration(channelMap.getBoolean("vibrationEnabled")); - } - if (channelMap.hasKey("vibrationPattern")) { - ReadableArray vibrationArray = channelMap.getArray("vibrationPattern"); - long[] vibration = new long[vibrationArray.size()]; - for (int i = 0; i < vibrationArray.size(); i++) { - vibration[i] = (long) vibrationArray.getDouble(i); - } - channel.setVibrationPattern(vibration); - } - return channel; - } - return null; - } - - private void scheduleNotification(Bundle notification, @Nullable Promise promise) { - if (!notification.containsKey("notificationId")) { - if (promise == null) { - Log.e(TAG, "Missing notificationId"); - } else { - promise.reject("notification/schedule_notification_error", "Missing notificationId"); - } - return; - } - - if (!notification.containsKey("schedule")) { - if (promise == null) { - Log.e(TAG, "Missing schedule information"); - } else { - promise.reject("notification/schedule_notification_error", "Missing schedule information"); - } - return; - } - - String notificationId = notification.getString("notificationId"); - Bundle schedule = notification.getBundle("schedule"); - - // fireDate may be stored in the Bundle as 2 different types that we need to handle: - // 1. Double - when a call comes directly from React - // 2. Long - when notifications are rescheduled from boot service (Bundle is loaded from preferences). - // At the end we need Long value (timestamp) for the scheduler - Long fireDate = -1L; - Object fireDateObject = schedule.get("fireDate"); - if (fireDateObject instanceof Long) { - fireDate = (Long) fireDateObject; - } else if (fireDateObject instanceof Double) { - Double fireDateDouble = (Double) fireDateObject; - fireDate = fireDateDouble.longValue(); - } - - if (fireDate == -1) { - if (promise == null) { - Log.e(TAG, "Missing schedule information"); - } else { - promise.reject("notification/schedule_notification_error", "Missing fireDate information"); - } - return; - } - - // Scheduled alarms are cleared on restart - // We store them so that they can be re-scheduled when the phone restarts in RNFirebaseNotificationsRebootReceiver - try { - JSONObject json = BundleJSONConverter.convertToJSON(notification); - preferences - .edit() - .putString(notificationId, json.toString()) - .apply(); - } catch (JSONException e) { - if (promise == null) { - Log.e(TAG, "Failed to store notification"); - } else { - promise.reject( - "notification/schedule_notification_error", - "Failed to store notification", - e - ); - } - return; - } - - Intent notificationIntent = new Intent(context, RNFirebaseNotificationReceiver.class); - notificationIntent.putExtras(notification); - PendingIntent pendingIntent = PendingIntent.getBroadcast( - context, - notificationId.hashCode(), - notificationIntent, - PendingIntent.FLAG_UPDATE_CURRENT - ); - - if (schedule.containsKey("repeatInterval")) { - // If fireDate you specify is in the past, the alarm triggers immediately. - // So we need to adjust the time for correct operation. - if (fireDate < System.currentTimeMillis()) { - Log.w(TAG, "Scheduled notification date is in the past, will adjust it to be in future"); - Calendar newFireDate = Calendar.getInstance(); - Calendar pastFireDate = Calendar.getInstance(); - pastFireDate.setTimeInMillis(fireDate); - - newFireDate.set(Calendar.SECOND, pastFireDate.get(Calendar.SECOND)); - - switch (schedule.getString("repeatInterval")) { - case "minute": - newFireDate.add(Calendar.MINUTE, 1); - break; - case "hour": - newFireDate.set(Calendar.MINUTE, pastFireDate.get(Calendar.MINUTE)); - newFireDate.add(Calendar.HOUR, 1); - break; - case "day": - newFireDate.set(Calendar.MINUTE, pastFireDate.get(Calendar.MINUTE)); - newFireDate.set(Calendar.HOUR_OF_DAY, pastFireDate.get(Calendar.HOUR_OF_DAY)); - newFireDate.add(Calendar.DATE, 1); - break; - case "week": - newFireDate.set(Calendar.MINUTE, pastFireDate.get(Calendar.MINUTE)); - newFireDate.set(Calendar.HOUR_OF_DAY, pastFireDate.get(Calendar.HOUR_OF_DAY)); - newFireDate.set(Calendar.DATE, pastFireDate.get(Calendar.DATE)); - newFireDate.add(Calendar.DATE, 7); - break; - } - - fireDate = newFireDate.getTimeInMillis(); - } - - Long interval = null; - switch (schedule.getString("repeatInterval")) { - case "minute": - interval = 60000L; - break; - case "hour": - interval = AlarmManager.INTERVAL_HOUR; - break; - case "day": - interval = AlarmManager.INTERVAL_DAY; - break; - case "week": - interval = AlarmManager.INTERVAL_DAY * 7; - break; - default: - Log.e(TAG, "Invalid interval: " + schedule.getString("interval")); - break; - } - - if (interval == null) { - if (promise == null) { - Log.e(TAG, "Invalid interval"); - } else { - promise.reject("notification/schedule_notification_error", "Invalid interval"); - } - return; - } - - alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, fireDate, interval, pendingIntent); - } else { - if (schedule.containsKey("exact") - && schedule.getBoolean("exact") - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - alarmManager.setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); - } else { - alarmManager.set(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); - } - } - - if (promise != null) { - promise.resolve(null); - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationReceiver.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationReceiver.java deleted file mode 100644 index 903daf65..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationReceiver.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -/* - * This is invoked by the Alarm Manager when it is time to display a scheduled notification. - */ -public class RNFirebaseNotificationReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - new RNFirebaseNotificationManager(context).displayScheduledNotification(intent.getExtras()); - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotifications.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotifications.java deleted file mode 100644 index 86622a73..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotifications.java +++ /dev/null @@ -1,427 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.app.Activity; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.support.v4.app.RemoteInput; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; - -import com.facebook.react.bridge.ActivityEventListener; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.messaging.RemoteMessage; - -import java.util.ArrayList; -import java.util.Map; - -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; -import io.invertase.firebase.messaging.RNFirebaseMessagingService; -import me.leolin.shortcutbadger.ShortcutBadger; - -import static io.invertase.firebase.Utils.getResId; - -public class RNFirebaseNotifications extends ReactContextBaseJavaModule implements ActivityEventListener { - private static final String BADGE_FILE = "BadgeCountFile"; - private static final String BADGE_KEY = "BadgeCount"; - private static final String TAG = "RNFirebaseNotifications"; - - private SharedPreferences sharedPreferences = null; - - private RNFirebaseNotificationManager notificationManager; - - RNFirebaseNotifications(ReactApplicationContext context) { - super(context); - context.addActivityEventListener(this); - - notificationManager = new RNFirebaseNotificationManager(context); - sharedPreferences = context.getSharedPreferences(BADGE_FILE, Context.MODE_PRIVATE); - - LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); - - // Subscribe to remote notification events - localBroadcastManager.registerReceiver( - new RemoteNotificationReceiver(), - new IntentFilter(RNFirebaseMessagingService.REMOTE_NOTIFICATION_EVENT) - ); - - // Subscribe to scheduled notification events - localBroadcastManager.registerReceiver( - new ScheduledNotificationReceiver(), - new IntentFilter(RNFirebaseNotificationManager.SCHEDULED_NOTIFICATION_EVENT) - ); - } - - @Override - public String getName() { - return "RNFirebaseNotifications"; - } - - @ReactMethod - public void cancelAllNotifications(Promise promise) { - notificationManager.cancelAllNotifications(promise); - } - - @ReactMethod - public void cancelNotification(String notificationId, Promise promise) { - notificationManager.cancelNotification(notificationId, promise); - } - - @ReactMethod - public void displayNotification(ReadableMap notification, Promise promise) { - notificationManager.displayNotification(notification, promise); - } - - @ReactMethod - public void getBadge(Promise promise) { - int badge = sharedPreferences.getInt(BADGE_KEY, 0); - Log.d(TAG, "Got badge count: " + badge); - promise.resolve(badge); - } - - @ReactMethod - public void getInitialNotification(Promise promise) { - WritableMap notificationOpenMap = null; - if (getCurrentActivity() != null) { - notificationOpenMap = parseIntentForNotification(getCurrentActivity().getIntent()); - } - promise.resolve(notificationOpenMap); - } - - @ReactMethod - public void getScheduledNotifications(Promise promise) { - ArrayList bundles = notificationManager.getScheduledNotifications(); - WritableArray array = Arguments.createArray(); - for (Bundle bundle : bundles) { - array.pushMap(parseNotificationBundle(bundle)); - } - promise.resolve(array); - } - - @ReactMethod - public void removeAllDeliveredNotifications(Promise promise) { - notificationManager.removeAllDeliveredNotifications(promise); - } - - @ReactMethod - public void removeDeliveredNotification(String notificationId, Promise promise) { - notificationManager.removeDeliveredNotification(notificationId, promise); - } - - @ReactMethod - public void removeDeliveredNotificationsByTag(String tag, Promise promise) { - notificationManager.removeDeliveredNotificationsByTag(tag, promise); - } - - @ReactMethod - public void setBadge(int badge, Promise promise) { - // Store the badge count for later retrieval - sharedPreferences - .edit() - .putInt(BADGE_KEY, badge) - .apply(); - if (badge == 0) { - Log.d(TAG, "Remove badge count"); - ShortcutBadger.removeCount(this.getReactApplicationContext()); - } else { - Log.d(TAG, "Apply badge count: " + badge); - ShortcutBadger.applyCount(this.getReactApplicationContext(), badge); - } - promise.resolve(null); - } - - @ReactMethod - public void scheduleNotification(ReadableMap notification, Promise promise) { - notificationManager.scheduleNotification(notification, promise); - } - - ////////////////////////////////////////////////////////////////////// - // Start Android specific methods - ////////////////////////////////////////////////////////////////////// - @ReactMethod - public void createChannel(ReadableMap channelMap, Promise promise) { - try { - notificationManager.createChannel(channelMap); - } catch (Throwable t) { - // do nothing - most likely a NoSuchMethodError for < v4 support lib - } - promise.resolve(null); - } - - @ReactMethod - public void createChannelGroup(ReadableMap channelGroupMap, Promise promise) { - try { - notificationManager.createChannelGroup(channelGroupMap); - } catch (Throwable t) { - // do nothing - most likely a NoSuchMethodError for < v4 support lib - } - promise.resolve(null); - } - - @ReactMethod - public void createChannelGroups(ReadableArray channelGroupsArray, Promise promise) { - try { - notificationManager.createChannelGroups(channelGroupsArray); - } catch (Throwable t) { - // do nothing - most likely a NoSuchMethodError for < v4 support lib - } - promise.resolve(null); - } - - @ReactMethod - public void createChannels(ReadableArray channelsArray, Promise promise) { - try { - notificationManager.createChannels(channelsArray); - } catch (Throwable t) { - // do nothing - most likely a NoSuchMethodError for < v4 support lib - } - promise.resolve(null); - } - - @ReactMethod - public void deleteChannelGroup(String channelId, Promise promise) { - try { - notificationManager.deleteChannelGroup(channelId); - promise.resolve(null); - } catch (NullPointerException e) { - promise.reject( - "notifications/channel-group-not-found", - "The requested NotificationChannelGroup does not exist, have you created it?" - ); - } - } - - @ReactMethod - public void deleteChannel(String channelId, Promise promise) { - try { - notificationManager.deleteChannel(channelId); - } catch (Throwable t) { - // do nothing - most likely a NoSuchMethodError for < v4 support lib - } - promise.resolve(null); - } - ////////////////////////////////////////////////////////////////////// - // End Android specific methods - ////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////// - // Start ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - @Override - public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { - // FCM functionality does not need this function - } - - @Override - public void onNewIntent(Intent intent) { - WritableMap notificationOpenMap = parseIntentForNotification(intent); - if (notificationOpenMap != null) { - Utils.sendEvent( - getReactApplicationContext(), - "notifications_notification_opened", - notificationOpenMap - ); - } - } - - ////////////////////////////////////////////////////////////////////// - // End ActivityEventListener methods - ////////////////////////////////////////////////////////////////////// - - private WritableMap parseIntentForNotification(Intent intent) { - WritableMap notificationOpenMap = parseIntentForRemoteNotification(intent); - if (notificationOpenMap == null) { - notificationOpenMap = parseIntentForLocalNotification(intent); - } - return notificationOpenMap; - } - - private WritableMap parseIntentForLocalNotification(Intent intent) { - if (intent.getExtras() == null || !intent.hasExtra("notificationId")) { - return null; - } - - WritableMap notificationMap = Arguments.makeNativeMap(intent.getExtras()); - WritableMap notificationOpenMap = Arguments.createMap(); - notificationOpenMap.putString("action", intent.getAction()); - notificationOpenMap.putMap("notification", notificationMap); - - // Check for remote input results - Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); - if (remoteInput != null) { - notificationOpenMap.putMap("results", Arguments.makeNativeMap(remoteInput)); - } - - return notificationOpenMap; - } - - private WritableMap parseIntentForRemoteNotification(Intent intent) { - // Check if FCM data exists - if (intent.getExtras() == null || !intent.hasExtra("google.message_id")) { - return null; - } - - Bundle extras = intent.getExtras(); - - WritableMap notificationMap = Arguments.createMap(); - WritableMap dataMap = Arguments.createMap(); - - for (String key : extras.keySet()) { - if (key.equals("google.message_id")) { - notificationMap.putString("notificationId", extras.getString(key)); - } else if (key.equals("collapse_key") - || key.equals("from") - || key.equals("google.sent_time") - || key.equals("google.ttl") - || key.equals("_fbSourceApplicationHasBeenSet")) { - // ignore known unneeded fields - } else { - dataMap.putString(key, extras.getString(key)); - } - } - notificationMap.putMap("data", dataMap); - - WritableMap notificationOpenMap = Arguments.createMap(); - notificationOpenMap.putString("action", intent.getAction()); - notificationOpenMap.putMap("notification", notificationMap); - - return notificationOpenMap; - } - - private WritableMap parseNotificationBundle(Bundle notification) { - return Arguments.makeNativeMap(notification); - } - - private WritableMap parseRemoteMessage(RemoteMessage message) { - RemoteMessage.Notification notification = message.getNotification(); - - WritableMap notificationMap = Arguments.createMap(); - WritableMap dataMap = Arguments.createMap(); - - // Cross platform notification properties - String body = getNotificationBody(notification); - if (body != null) { - notificationMap.putString("body", body); - } - if (message.getData() != null) { - for (Map.Entry e : message - .getData() - .entrySet()) { - dataMap.putString(e.getKey(), e.getValue()); - } - } - notificationMap.putMap("data", dataMap); - if (message.getMessageId() != null) { - notificationMap.putString("notificationId", message.getMessageId()); - } - if (notification.getSound() != null) { - notificationMap.putString("sound", notification.getSound()); - } - String title = getNotificationTitle(notification); - if (title != null) { - notificationMap.putString("title", title); - } - - // Android specific notification properties - WritableMap androidMap = Arguments.createMap(); - if (notification.getClickAction() != null) { - androidMap.putString("clickAction", notification.getClickAction()); - } - if (notification.getColor() != null) { - androidMap.putString("color", notification.getColor()); - } - if (notification.getIcon() != null) { - WritableMap iconMap = Arguments.createMap(); - iconMap.putString("icon", notification.getIcon()); - androidMap.putMap("smallIcon", iconMap); - } - if (notification.getTag() != null) { - androidMap.putString("group", notification.getTag()); - androidMap.putString("tag", notification.getTag()); - } - notificationMap.putMap("android", androidMap); - - return notificationMap; - } - - private @Nullable - String getNotificationBody(RemoteMessage.Notification notification) { - String body = notification.getBody(); - String bodyLocKey = notification.getBodyLocalizationKey(); - if (bodyLocKey != null) { - String[] bodyLocArgs = notification.getBodyLocalizationArgs(); - Context ctx = getReactApplicationContext(); - int resId = getResId(ctx, bodyLocKey); - return ctx - .getResources() - .getString(resId, (Object[]) bodyLocArgs); - } else { - return body; - } - } - - private @Nullable - String getNotificationTitle(RemoteMessage.Notification notification) { - String title = notification.getTitle(); - String titleLocKey = notification.getTitleLocalizationKey(); - if (titleLocKey != null) { - String[] titleLocArgs = notification.getTitleLocalizationArgs(); - Context ctx = getReactApplicationContext(); - int resId = getResId(ctx, titleLocKey); - return ctx - .getResources() - .getString(resId, (Object[]) titleLocArgs); - } else { - return title; - } - } - - private class RemoteNotificationReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (getReactApplicationContext().hasActiveCatalystInstance()) { - Log.d(TAG, "Received new remote notification"); - - RemoteMessage message = intent.getParcelableExtra("notification"); - WritableMap messageMap = parseRemoteMessage(message); - - Utils.sendEvent( - getReactApplicationContext(), - "notifications_notification_received", - messageMap - ); - } - } - } - - private class ScheduledNotificationReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (getReactApplicationContext().hasActiveCatalystInstance()) { - Log.d(TAG, "Received new scheduled notification"); - - Bundle notification = intent.getBundleExtra("notification"); - WritableMap messageMap = parseNotificationBundle(notification); - - Utils.sendEvent( - getReactApplicationContext(), - "notifications_notification_received", - messageMap - ); - } - } - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsPackage.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsPackage.java deleted file mode 100644 index 74d4de23..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsPackage.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.invertase.firebase.notifications; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class RNFirebaseNotificationsPackage implements ReactPackage { - public RNFirebaseNotificationsPackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseNotifications(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsRebootReceiver.java b/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsRebootReceiver.java deleted file mode 100644 index 80e6750f..00000000 --- a/android/src/main/java/io/invertase/firebase/notifications/RNFirebaseNotificationsRebootReceiver.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.invertase.firebase.notifications; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -/* - * This is invoked when the phone restarts to ensure that all notifications are rescheduled - * correctly, as Android removes all scheduled alarms when the phone shuts down. - */ -public class RNFirebaseNotificationsRebootReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.i("RNFNotifRebootReceiver", "Received reboot event"); - new RNFirebaseNotificationManager(context).rescheduleNotifications(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformance.java b/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformance.java deleted file mode 100644 index 34196e91..00000000 --- a/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformance.java +++ /dev/null @@ -1,291 +0,0 @@ -package io.invertase.firebase.perf; - - -import android.util.Log; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.WritableMap; -import com.google.firebase.perf.FirebasePerformance; -import com.google.firebase.perf.metrics.HttpMetric; -import com.google.firebase.perf.metrics.Trace; - -import java.util.HashMap; -import java.util.Map; - -public class RNFirebasePerformance extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebasePerformance"; - private HashMap traces = new HashMap<>(); - private HashMap httpMetrics = new HashMap<>(); - - public RNFirebasePerformance(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); - } - - /** - * @return - */ - @Override - public String getName() { - return TAG; - } - - @ReactMethod - public void setPerformanceCollectionEnabled(Boolean enabled, Promise promise) { - FirebasePerformance.getInstance().setPerformanceCollectionEnabled(enabled); - promise.resolve(null); - } - - /** - * Trace - */ - - @ReactMethod - public void getTraceAttribute(String identifier, String attribute, Promise promise) { - promise.resolve(getOrCreateTrace(identifier).getAttribute(attribute)); - } - - @ReactMethod - public void getTraceAttributes(String identifier, Promise promise) { - Map attributes = getOrCreateTrace(identifier).getAttributes(); - WritableMap map = Arguments.createMap(); - - for (Map.Entry entry : attributes.entrySet()) { - map.putString(entry.getKey(), entry.getValue()); - } - - promise.resolve(map); - } - - @ReactMethod - public void getTraceLongMetric(String identifier, String metricName, Promise promise) { - Integer value = Long.valueOf(getOrCreateTrace(identifier).getLongMetric(metricName)).intValue(); - promise.resolve(value); - } - - @ReactMethod - public void incrementTraceMetric( - String identifier, - String metricName, - Integer incrementBy, - Promise promise - ) { - getOrCreateTrace(identifier).incrementMetric(metricName, incrementBy.longValue()); - promise.resolve(null); - } - - @ReactMethod - public void putTraceAttribute( - String identifier, - String attribute, - String value, - Promise promise - ) { - getOrCreateTrace(identifier).putAttribute(attribute, value); - // Docs say it returns a bool, actually void so we internally check attributes - Map attributes = getOrCreateTrace(identifier).getAttributes(); - if (attributes.containsKey(attribute)) { - promise.resolve(true); - } else { - promise.resolve(false); - } - } - - @ReactMethod - public void putTraceMetric(String identifier, String metricName, Integer value, Promise promise) { - getOrCreateTrace(identifier).putMetric(metricName, value.longValue()); - promise.resolve(null); - } - - @ReactMethod - public void removeTraceAttribute(String identifier, String attribute, Promise promise) { - getOrCreateTrace(identifier).removeAttribute(attribute); - promise.resolve(null); - } - - @ReactMethod - public void startTrace(String identifier, Promise promise) { - getOrCreateTrace(identifier).start(); - promise.resolve(null); - } - - @ReactMethod - public void stopTrace(String identifier, Promise promise) { - getOrCreateTrace(identifier).stop(); - traces.remove(identifier); - promise.resolve(null); - } - - @ReactMethod - public void incrementCounter(String identifier, String event) { - getOrCreateTrace(identifier).incrementCounter(event); - } - - /** - * Http Metric - */ - - @ReactMethod - public void getHttpMetricAttribute( - String url, - String httpMethod, - String attribute, - Promise promise - ) { - promise.resolve(getOrCreateHttpMetric(url, httpMethod).getAttribute(attribute)); - } - - @ReactMethod - public void getHttpMetricAttributes(String url, String httpMethod, Promise promise) { - Map attributes = getOrCreateHttpMetric(url, httpMethod).getAttributes(); - WritableMap map = Arguments.createMap(); - - for (Map.Entry entry : attributes.entrySet()) { - map.putString(entry.getKey(), entry.getValue()); - } - - promise.resolve(map); - } - - @ReactMethod - public void putHttpMetricAttribute( - String url, - String httpMethod, - String attribute, - String value, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).putAttribute(attribute, value); - // Docs say it returns a bool, actually void so we internally check attributes - Map attributes = getOrCreateHttpMetric(url, httpMethod).getAttributes(); - if (attributes.containsKey(attribute)) { - promise.resolve(true); - } else { - promise.resolve(false); - } - } - - @ReactMethod - public void removeHttpMetricAttribute( - String url, - String httpMethod, - String attribute, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).removeAttribute(attribute); - promise.resolve(null); - } - - @ReactMethod - public void setHttpMetricResponseCode( - String url, - String httpMethod, - Integer code, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).setHttpResponseCode(code); - promise.resolve(null); - } - - @ReactMethod - public void setHttpMetricRequestPayloadSize( - String url, - String httpMethod, - Integer bytes, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).setRequestPayloadSize(bytes.longValue()); - promise.resolve(null); - } - - @ReactMethod - public void setHttpMetricResponseContentType( - String url, - String httpMethod, - String type, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).setResponseContentType(type); - promise.resolve(null); - } - - @ReactMethod - public void setHttpMetricResponsePayloadSize( - String url, - String httpMethod, - Integer bytes, - Promise promise - ) { - getOrCreateHttpMetric(url, httpMethod).setResponsePayloadSize(bytes.longValue()); - promise.resolve(null); - } - - @ReactMethod - public void startHttpMetric(String url, String httpMethod, Promise promise) { - getOrCreateHttpMetric(url, httpMethod).start(); - promise.resolve(null); - } - - @ReactMethod - public void stopHttpMetric(String url, String httpMethod, Promise promise) { - getOrCreateHttpMetric(url, httpMethod).stop(); - httpMetrics.remove(url + httpMethod); - promise.resolve(null); - } - - /** - * Private - */ - - private Trace getOrCreateTrace(String identifier) { - if (traces.containsKey(identifier)) { - return traces.get(identifier); - } - Trace trace = FirebasePerformance.getInstance().newTrace(identifier); - traces.put(identifier, trace); - return trace; - } - - private HttpMetric getOrCreateHttpMetric(String url, String httpMethod) { - String identifier = url + httpMethod; - if (httpMetrics.containsKey(identifier)) { - return httpMetrics.get(identifier); - } - HttpMetric httpMetric = FirebasePerformance.getInstance().newHttpMetric( - url, - this.mapStringToMethod(httpMethod) - ); - httpMetrics.put(identifier, httpMetric); - return httpMetric; - } - - private String mapStringToMethod(String value) { - switch (value) { - case "CONNECT": - return FirebasePerformance.HttpMethod.CONNECT; - case "DELETE": - return FirebasePerformance.HttpMethod.DELETE; - case "GET": - return FirebasePerformance.HttpMethod.GET; - case "HEAD": - return FirebasePerformance.HttpMethod.HEAD; - case "OPTIONS": - return FirebasePerformance.HttpMethod.OPTIONS; - case "PATCH": - return FirebasePerformance.HttpMethod.PATCH; - case "POST": - return FirebasePerformance.HttpMethod.POST; - case "PUT": - return FirebasePerformance.HttpMethod.PUT; - case "TRACE": - return FirebasePerformance.HttpMethod.TRACE; - } - - return ""; - } -} diff --git a/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformancePackage.java b/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformancePackage.java deleted file mode 100644 index e0e6ee07..00000000 --- a/android/src/main/java/io/invertase/firebase/perf/RNFirebasePerformancePackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.invertase.firebase.perf; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebasePerformancePackage implements ReactPackage { - public RNFirebasePerformancePackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebasePerformance(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStorage.java b/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStorage.java deleted file mode 100644 index 792596e0..00000000 --- a/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStorage.java +++ /dev/null @@ -1,803 +0,0 @@ -package io.invertase.firebase.storage; - -import android.content.ContentResolver; -import android.net.Uri; -import android.os.Environment; -import android.util.Log; -import android.webkit.MimeTypeMap; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableMap; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.FirebaseApp; -import com.google.firebase.storage.FirebaseStorage; -import com.google.firebase.storage.OnPausedListener; -import com.google.firebase.storage.OnProgressListener; -import com.google.firebase.storage.StorageException; -import com.google.firebase.storage.StorageMetadata; -import com.google.firebase.storage.StorageReference; -import com.google.firebase.storage.StorageTask; -import com.google.firebase.storage.StreamDownloadTask; -import com.google.firebase.storage.UploadTask; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import io.invertase.firebase.Utils; - -@SuppressWarnings("WeakerAccess") -public class RNFirebaseStorage extends ReactContextBaseJavaModule { - - private static final String TAG = "RNFirebaseStorage"; - private static final String DocumentDirectoryPath = "DOCUMENT_DIRECTORY_PATH"; - private static final String ExternalDirectoryPath = "EXTERNAL_DIRECTORY_PATH"; - private static final String ExternalStorageDirectoryPath = "EXTERNAL_STORAGE_DIRECTORY_PATH"; - private static final String PicturesDirectoryPath = "PICTURES_DIRECTORY_PATH"; - private static final String TemporaryDirectoryPath = "TEMP_DIRECTORY_PATH"; - private static final String CachesDirectoryPath = "CACHES_DIRECTORY_PATH"; - - private static final String FileTypeRegular = "FILETYPE_REGULAR"; - private static final String FileTypeDirectory = "FILETYPE_DIRECTORY"; - - private static final String STORAGE_EVENT = "storage_event"; - private static final String STORAGE_STATE_CHANGED = "state_changed"; - private static final String STORAGE_UPLOAD_SUCCESS = "upload_success"; - private static final String STORAGE_UPLOAD_FAILURE = "upload_failure"; - private static final String STORAGE_DOWNLOAD_SUCCESS = "download_success"; - private static final String STORAGE_DOWNLOAD_FAILURE = "download_failure"; - - public RNFirebaseStorage(ReactApplicationContext reactContext) { - super(reactContext); - - Log.d(TAG, "New instance"); - } - - @Override - public String getName() { - return TAG; - } - - - /** - * Check if we can write to storage, usually false if no permission set on manifest - * - * @return - */ - public boolean isExternalStorageWritable() { - boolean mExternalStorageAvailable; - boolean mExternalStorageWritable; - String state = Environment.getExternalStorageState(); - - if (Environment.MEDIA_MOUNTED.equals(state)) { - // we can read and write the media - mExternalStorageAvailable = mExternalStorageWritable = true; - } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { - // we can only read the media - mExternalStorageAvailable = true; - mExternalStorageWritable = false; - } else { - // something else is wrong. It may be one of many other states, but all we need - // to know is we can neither read nor write - mExternalStorageAvailable = mExternalStorageWritable = false; - } - - return mExternalStorageAvailable && mExternalStorageWritable; - } - - /** - * delete - * - * @param path - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete - */ - @ReactMethod - public void delete(String appName, final String path, final Promise promise) { - StorageReference reference = this.getReference(path, appName); - reference - .delete() - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(Void aVoid) { - promise.resolve(null); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - promiseRejectStorageException(promise, exception); - } - }); - } - - /** - * getDownloadURL - * - * @param path - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL - */ - @ReactMethod - public void getDownloadURL(String appName, final String path, final Promise promise) { - Log.d(TAG, "getDownloadURL path " + path); - final StorageReference reference = this.getReference(path, appName); - - Task downloadTask = reference.getDownloadUrl(); - downloadTask - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(Uri uri) { - promise.resolve(uri.toString()); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - promiseRejectStorageException(promise, exception); - } - }); - } - - /** - * getMetadata - * - * @param path - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata - */ - @ReactMethod - public void getMetadata(String appName, final String path, final Promise promise) { - StorageReference reference = this.getReference(path, appName); - reference - .getMetadata() - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(StorageMetadata storageMetadata) { - promise.resolve(getMetadataAsMap(storageMetadata)); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - promiseRejectStorageException(promise, exception); - } - }); - } - - /** - * updateMetadata - * - * @param path - * @param metadata - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata - */ - @ReactMethod - public void updateMetadata( - String appName, - final String path, - final ReadableMap metadata, - final Promise promise - ) { - StorageReference reference = this.getReference(path, appName); - StorageMetadata md = buildMetadataFromMap(metadata, null); - - reference - .updateMetadata(md) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(StorageMetadata storageMetadata) { - WritableMap data = getMetadataAsMap(storageMetadata); - promise.resolve(data); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - promiseRejectStorageException(promise, exception); - } - }); - } - - - /** - * downloadFile - * - * @param path - * @param localPath - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#downloadFile - */ - @ReactMethod - public void downloadFile( - final String appName, - final String path, - final String localPath, - final Promise promise - ) { - if (!isExternalStorageWritable()) { - promise.reject( - "storage/invalid-device-file-path", - "The specified device file path is invalid or is restricted." - ); - - return; - } - - Log.d(TAG, "downloadFile path: " + path); - StorageReference reference = this.getReference(path, appName); - - reference - .getStream(new StreamDownloadTask.StreamProcessor() { - @Override - public void doInBackground( - StreamDownloadTask.TaskSnapshot taskSnapshot, - InputStream inputStream - ) throws IOException { - int indexOfLastSlash = localPath.lastIndexOf("/"); - String pathMinusFileName = indexOfLastSlash > 0 ? localPath.substring( - 0, - indexOfLastSlash - ) + "/" : "/"; - String filename = indexOfLastSlash > 0 ? localPath.substring(indexOfLastSlash + 1) : localPath; - File fileWithJustPath = new File(pathMinusFileName); - - // directoriesCreated assignment for not consumed warning - Boolean directoriesCreated = fileWithJustPath.mkdirs(); - File fileWithFullPath = new File(pathMinusFileName, filename); - FileOutputStream output = new FileOutputStream(fileWithFullPath); - int bufferSize = 1024; - byte[] buffer = new byte[bufferSize]; - - int len; - while ((len = inputStream.read(buffer)) != -1) { - output.write(buffer, 0, len); - } - - output.close(); - } - }) - .addOnProgressListener(new OnProgressListener() { - @Override - public void onProgress(StreamDownloadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "downloadFile progress " + taskSnapshot); - WritableMap event = getDownloadTaskAsMap(taskSnapshot); - sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event); - } - }) - .addOnPausedListener(new OnPausedListener() { - @Override - public void onPaused(StreamDownloadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "downloadFile paused " + taskSnapshot); - WritableMap event = getDownloadTaskAsMap(taskSnapshot); - sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event); - } - }) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(StreamDownloadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "downloadFile success" + taskSnapshot); - WritableMap resp = getDownloadTaskAsMap(taskSnapshot); - sendJSEvent(appName, STORAGE_DOWNLOAD_SUCCESS, path, resp); - resp = getDownloadTaskAsMap(taskSnapshot); - promise.resolve(resp); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - Log.e(TAG, "downloadFile failure " + exception.getMessage()); - // TODO sendJS error event - promiseRejectStorageException(promise, exception); - } - }); - } - - /** - * setMaxDownloadRetryTime - * - * @param milliseconds - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxDownloadRetryTime - */ - @ReactMethod - public void setMaxDownloadRetryTime(String appName, final double milliseconds) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp); - - firebaseStorage.setMaxDownloadRetryTimeMillis((long) milliseconds); - } - - /** - * setMaxOperationRetryTime - * - * @param milliseconds - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime - */ - @ReactMethod - public void setMaxOperationRetryTime(String appName, final double milliseconds) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp); - - firebaseStorage.setMaxOperationRetryTimeMillis((long) milliseconds); - } - - /** - * setMaxUploadRetryTime - * - * @param milliseconds - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime - */ - @ReactMethod - public void setMaxUploadRetryTime(String appName, final double milliseconds) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp); - - firebaseStorage.setMaxUploadRetryTimeMillis((long) milliseconds); - } - - /** - * putFile - * - * @param path - * @param localPath - * @param metadata - * @param promise - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putFile - */ - @ReactMethod - public void putFile( - final String appName, - final String path, - final String localPath, - final ReadableMap metadata, - final Promise promise - ) { - StorageReference reference = this.getReference(path, appName); - - Log.i(TAG, "putFile: " + localPath + " to " + path); - - try { - Uri file = getURI(localPath); - StorageMetadata md = buildMetadataFromMap(metadata, file); - UploadTask uploadTask = reference.putFile(file, md); - - // register observers to listen for when the download is done or if it fails - uploadTask - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception exception) { - // handle unsuccessful uploads - Log.e(TAG, "putFile failure " + exception.getMessage()); - // TODO sendJS error event - promiseRejectStorageException(promise, exception); - } - }) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "putFile success " + taskSnapshot); - // to avoid readable map already consumed errors we run this three times - getUploadTaskAsMap(taskSnapshot, new OnSuccessListener() { - @Override - public void onSuccess(WritableMap event) { - sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event); - } - }); - - getUploadTaskAsMap(taskSnapshot, new OnSuccessListener() { - @Override - public void onSuccess(WritableMap event) { - sendJSEvent(appName, STORAGE_UPLOAD_SUCCESS, path, event); - } - }); - - getUploadTaskAsMap(taskSnapshot, new OnSuccessListener() { - @Override - public void onSuccess(WritableMap event) { - promise.resolve(event); - } - }); - } - }) - .addOnProgressListener(new OnProgressListener() { - @Override - public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "putFile progress " + taskSnapshot); - getUploadTaskAsMap(taskSnapshot, new OnSuccessListener() { - @Override - public void onSuccess(WritableMap event) { - sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event); - } - }); - } - }) - .addOnPausedListener(new OnPausedListener() { - @Override - public void onPaused(UploadTask.TaskSnapshot taskSnapshot) { - Log.d(TAG, "putFile paused " + taskSnapshot); - getUploadTaskAsMap(taskSnapshot, new OnSuccessListener() { - @Override - public void onSuccess(WritableMap event) { - sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event); - } - }); - } - }); - } catch (Exception exception) { - promiseRejectStorageException(promise, exception); - } - } - - /** - * Internal helper to detect if ref is from url or a path. - * - * @param path - * @return - */ - private StorageReference getReference(String path, String appName) { - FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); - FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp); - - if (path.startsWith("url::")) { - String url = path.substring(5); - return firebaseStorage.getReferenceFromUrl(url); - } else { - return firebaseStorage.getReference(path); - } - } - - /** - * Create a Uri from the path, defaulting to file when there is no supplied scheme - * - * @param uri - * @return - */ - private Uri getURI(final String uri) { - Uri parsed = Uri.parse(uri); - - if (parsed.getScheme() == null || parsed - .getScheme() - .isEmpty()) { - return Uri.fromFile(new File(uri)); - } - return parsed; - } - - /** - * Converts a RN ReadableMap into a StorageMetadata instance - * - * @param metadata - * @return - */ - private StorageMetadata buildMetadataFromMap(ReadableMap metadata, @Nullable Uri file) { - StorageMetadata.Builder metadataBuilder = new StorageMetadata.Builder(); - - try { - Map m = Utils.recursivelyDeconstructReadableMap(metadata); - Map customMetadata = (Map) m.get("customMetadata"); - if (customMetadata != null) { - for (Map.Entry entry : customMetadata.entrySet()) { - metadataBuilder.setCustomMetadata(entry.getKey(), String.valueOf(entry.getValue())); - } - } - - metadataBuilder.setCacheControl((String) m.get("cacheControl")); - metadataBuilder.setContentDisposition((String) m.get("contentDisposition")); - metadataBuilder.setContentEncoding((String) m.get("contentEncoding")); - metadataBuilder.setContentLanguage((String) m.get("contentLanguage")); - - if (metadata.hasKey("contentType")) { - metadataBuilder.setContentType((String) m.get("contentType")); - } else if (file != null) { - String mimeType = null; - - if (file - .getScheme() - .equals(ContentResolver.SCHEME_CONTENT)) { - ContentResolver cr = getReactApplicationContext().getContentResolver(); - mimeType = cr.getType(file); - } else { - String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file - .toString()); - mimeType = MimeTypeMap - .getSingleton() - .getMimeTypeFromExtension( - fileExtension.toLowerCase()); - } - - if (mimeType != null) metadataBuilder.setContentType(mimeType); - } - } catch (Exception e) { - Log.e(TAG, "error while building meta data " + e.getMessage()); - } - - return metadataBuilder.build(); - } - - /** - * Convert an download task snapshot to a RN WritableMAP - * - * @param taskSnapshot - * @return - */ - private WritableMap getDownloadTaskAsMap(final StreamDownloadTask.TaskSnapshot taskSnapshot) { - WritableMap resp = Arguments.createMap(); - resp.putDouble("bytesTransferred", taskSnapshot.getBytesTransferred()); - resp.putString( - "ref", - taskSnapshot - .getStorage() - .getPath() - ); - resp.putString("state", this.getTaskStatus(taskSnapshot.getTask())); - resp.putDouble("totalBytes", taskSnapshot.getTotalByteCount()); - - return resp; - } - - - /** - * Convert an upload task snapshot to a RN WritableMAP - * - * @param taskSnapshot - * @return - */ - private void getUploadTaskAsMap( - final UploadTask.TaskSnapshot taskSnapshot, - final OnSuccessListener listener - ) { - if (taskSnapshot != null) { - taskSnapshot - .getStorage() - .getDownloadUrl() - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@Nonnull Exception e) { - int errorCode = ((StorageException) e).getErrorCode(); - if (errorCode == StorageException.ERROR_NOT_AUTHORIZED) { - WritableMap resp = getRespAsMap(taskSnapshot, null); - listener.onSuccess(resp); - } - } - }) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(Uri downloadUrl) { - WritableMap resp = getRespAsMap(taskSnapshot, downloadUrl.toString()); - listener.onSuccess(resp); - } - }); - } else { - listener.onSuccess(Arguments.createMap()); - } - } - - - private WritableMap getRespAsMap(final UploadTask.TaskSnapshot taskSnapshot, final String downloadUrl) { - WritableMap resp = Arguments.createMap(); - - resp.putDouble("bytesTransferred", taskSnapshot.getBytesTransferred()); - resp.putString("downloadURL", downloadUrl); - - StorageMetadata d = taskSnapshot.getMetadata(); - if (d != null) { - WritableMap metadata = getMetadataAsMap(d); - resp.putMap("metadata", metadata); - } - - resp.putString( - "ref", - taskSnapshot - .getStorage() - .getPath() - ); - resp.putString("state", RNFirebaseStorage.this.getTaskStatus(taskSnapshot.getTask())); - resp.putDouble("totalBytes", taskSnapshot.getTotalByteCount()); - return resp; - } - /** - * Converts storageMetadata into a map - * - * @param storageMetadata - * @return - */ - private WritableMap getMetadataAsMap(StorageMetadata storageMetadata) { - WritableMap metadata = Arguments.createMap(); - metadata.putString("bucket", storageMetadata.getBucket()); - metadata.putString("generation", storageMetadata.getGeneration()); - metadata.putString("metageneration", storageMetadata.getMetadataGeneration()); - metadata.putString("fullPath", storageMetadata.getPath()); - metadata.putString("name", storageMetadata.getName()); - metadata.putDouble("size", storageMetadata.getSizeBytes()); - metadata.putDouble("timeCreated", storageMetadata.getCreationTimeMillis()); - metadata.putDouble("updated", storageMetadata.getUpdatedTimeMillis()); - metadata.putString("md5hash", storageMetadata.getMd5Hash()); - metadata.putString("cacheControl", storageMetadata.getCacheControl()); - metadata.putString("contentDisposition", storageMetadata.getContentDisposition()); - metadata.putString("contentEncoding", storageMetadata.getContentEncoding()); - metadata.putString("contentLanguage", storageMetadata.getContentLanguage()); - metadata.putString("contentType", storageMetadata.getContentType()); - - WritableMap customMetadata = Arguments.createMap(); - for (String key : storageMetadata.getCustomMetadataKeys()) { - customMetadata.putString(key, storageMetadata.getCustomMetadata(key)); - } - metadata.putMap("customMetadata", customMetadata); - - return metadata; - } - - /** - * Returns the task status as string - * - * @param task - * @return - */ - private String getTaskStatus(StorageTask task) { - if (task.isInProgress()) { - return "running"; - } else if (task.isPaused()) { - return "paused"; - } else if (task.isSuccessful() || task.isComplete()) { - return "success"; - } else if (task.isCanceled()) { - return "cancelled"; - } else if (task.getException() != null) { - return "error"; - } else { - return "unknown"; - } - } - - /** - * @param name - * @param path - * @param body - */ - private void sendJSEvent(String appName, final String name, final String path, WritableMap body) { - WritableMap event = Arguments.createMap(); - event.putMap("body", body); - event.putString("path", path); - event.putString("eventName", name); - event.putString("appName", appName); - Utils.sendEvent(this.getReactApplicationContext(), STORAGE_EVENT, event); - } - - /** - * Reject a promise with a web sdk error code - * - * @param promise - * @param exception - */ - private void promiseRejectStorageException(Promise promise, Exception exception) { - String code = "storage/unknown"; - String message = exception.getMessage(); - - try { - if (exception instanceof StorageException) { - StorageException storageException = (StorageException) exception; - - switch (storageException.getErrorCode()) { - case StorageException.ERROR_UNKNOWN: - code = "storage/unknown"; - message = "An unknown error has occurred."; - break; - case StorageException.ERROR_OBJECT_NOT_FOUND: - code = "storage/object-not-found"; - message = "No object exists at the desired reference."; - break; - case StorageException.ERROR_BUCKET_NOT_FOUND: - code = "storage/bucket-not-found"; - message = "No bucket is configured for Firebase Storage."; - break; - case StorageException.ERROR_PROJECT_NOT_FOUND: - code = "storage/project-not-found"; - message = "No project is configured for Firebase Storage."; - break; - case StorageException.ERROR_QUOTA_EXCEEDED: - code = "storage/quota-exceeded"; - message = "Quota on your Firebase Storage bucket has been exceeded."; - break; - case StorageException.ERROR_NOT_AUTHENTICATED: - code = "storage/unauthenticated"; - message = "User is unauthenticated. Authenticate and try again."; - break; - case StorageException.ERROR_NOT_AUTHORIZED: - code = "storage/unauthorized"; - message = "User is not authorized to perform the desired action."; - break; - case StorageException.ERROR_RETRY_LIMIT_EXCEEDED: - code = "storage/retry-limit-exceeded"; - message = "The maximum time limit on an operation (upload, download, delete, etc.) has been exceeded."; - break; - case StorageException.ERROR_INVALID_CHECKSUM: - code = "storage/non-matching-checksum"; - message = "File on the client does not match the checksum of the file received by the server."; - break; - case StorageException.ERROR_CANCELED: - code = "storage/cancelled"; - message = "User cancelled the operation."; - break; - } - } else { - code = "storage/unknown"; - message = "An unknown error has occurred."; - } - } finally { - promise.reject(code, message, exception); - } - } - - /** - * Constants bootstrapped on react native app boot - * e.g. firebase.storage.Native.DOCUMENT_DIRECTORY_PATH - * - * @return - */ - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - - constants.put( - DocumentDirectoryPath, - this - .getReactApplicationContext() - .getFilesDir() - .getAbsolutePath() - ); - constants.put( - TemporaryDirectoryPath, - this - .getReactApplicationContext() - .getCacheDir() - .getAbsolutePath() - ); - constants.put( - PicturesDirectoryPath, - Environment - .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) - .getAbsolutePath() - ); - constants.put( - CachesDirectoryPath, - this - .getReactApplicationContext() - .getCacheDir() - .getAbsolutePath() - ); - constants.put(FileTypeRegular, 0); - constants.put(FileTypeDirectory, 1); - - File externalStorageDirectory = Environment.getExternalStorageDirectory(); - if (externalStorageDirectory != null) { - constants.put(ExternalStorageDirectoryPath, externalStorageDirectory.getAbsolutePath()); - } else { - constants.put(ExternalStorageDirectoryPath, null); - } - - File externalDirectory = this - .getReactApplicationContext() - .getExternalFilesDir(null); - if (externalDirectory != null) { - constants.put(ExternalDirectoryPath, externalDirectory.getAbsolutePath()); - } else { - constants.put(ExternalDirectoryPath, null); - } - - return constants; - } -} diff --git a/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStoragePackage.java b/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStoragePackage.java deleted file mode 100644 index 56241059..00000000 --- a/android/src/main/java/io/invertase/firebase/storage/RNFirebaseStoragePackage.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.invertase.firebase.storage; - -import android.support.annotation.RequiresPermission; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("unused") -public class RNFirebaseStoragePackage implements ReactPackage { - @RequiresPermission( - allOf = {"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"} - ) - public RNFirebaseStoragePackage() { - } - - /** - * @param reactContext react application context that can be used to create modules - * @return list of native modules to register with the newly created catalyst instance - */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new RNFirebaseStorage(reactContext)); - - return modules; - } - - /** - * @param reactContext - * @return a list of view managers that should be registered with {@link UIManagerModule} - */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } -} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..adedacd4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,2 @@ +# React Native Firebase Documentation + diff --git a/docs/pages/contributing/index.mdx b/docs/pages/contributing/index.mdx new file mode 100644 index 00000000..51beddbe --- /dev/null +++ b/docs/pages/contributing/index.mdx @@ -0,0 +1,165 @@ +# Contributing + +Thank you for considering to contribute to React Native Firebase! With your help we can ensure the library is maintained and supported. It's people like you that make the open source community such a great community! 😊 + + +We welcome any type of contribution, not just code contributions: + + + + A great place to start contributing is helping other users with issues or reviewing pull requests. Ensuring users have provided enough details (platform versions, screenshots, SDK versions etc) or highlighting duplicate issues ensures users quickly find a solution to their issue/questions. + + + Our documentation includes guides, FAQs, release change logs, full API reference, examples and more. Contributions to documentation can include fixing spelling mistakes, providing more examples, writing your own guides and ensuring any pull requests have full documentation coverage for any changes. + + + Writing your own blog posts or tutorials about React Native Firebase? We'd love to promote it. Reach out on our Discord server to an admin and we'll add it to our collection. + + + We love getting involved with the community! Are you hosting or presenting at a meetup about React Native Firebase? Let us know, we may be able to provide sponsorship or attend ourselves. + + + Donating is a simple way of ensuring the future maintenance and upkeep of the library is continued. Any amount is greatly appriciated. All contributions are made via Open Collective with full transparency. + + + +### Ownership + +If you get a merged Pull Request, regardless of content (typos, code, doc fixes), then you'll most likely receive push access to this repository. This is checked for on pull request merges and an invite is sent to you via GitHub. + +Offhand, it is easy to imagine that this would make code quality suffer, but in reality it offers fresh perspectives to the codebase and encourages ownership from people who are depending on the project. If you are building a project that relies on this codebase, then you probably have the skills to improve it and offer valuable feedback. + +Everyone comes in with their own perspective on what a project could/should look like, and encouraging discussion can help expose good ideas sooner. + +### Why do we give out push access? + +It can be overwhelming to be offered the chance to wipe the source code for a project. + +Do not worry, we do not let you push directly to master or any of the version (e.g. v4.x.x) branches, these branches are protected by the review process. We have the convention that someone other than the submitter should merge non-trivial pull requests. + +As an organization contributor, you can merge other people's pull requests, or other contributors can merge yours. You will not be assigned a pull request, but you are welcome to jump in and take a code review on topics that interest you - just let others know you're picking up something by tagging in on an existing issue or creating a new one and assigning it to yourself. + +This project is **not** continuously deployed, this leaves space for debate after review and offering everyone the chance to revert, or make an amending pull request. If it feels right and follows the guidelines, then merge. + +### How can we help you get comfortable contributing? + +It is normal for a first pull request to be a potential fix for a problem but moving on from there to helping the project's direction can be difficult. + +We try to help contributors cross that barrier by offering good first step issues (labelled `good-first-issue`). These issues can be fixed without feeling like you are stepping on toes. Ideally, these are non-critical issues that are well defined. They will be purposely avoided by mature contributors to the project, to make space for others. + +Additionally issues labelled `needs-triage` or `help-wanted` can also be picked up, these may not necessarily require code changes but rather help with debugging and finding the cause of the issue whether it's a bug or an users incorrect setup of the library or project. + +We aim to keep all project discussion inside GitHub issues. This is to make sure valuable discussion is accessible via search. If you have questions about how to use the library, or how the project is running - GitHub issues are the goto tool for this project. + +### What if you only know how to develop for one platform? + +This is normal don't worry - not everyone can develop native code for Obj-C and Java, we understand that. + +Although we won't merge Pull Requests unless they support all applicable platforms, we do however recommend that you still submit a PR for the Platform that you do know and then label it as either `ios-help-wanted` or `android-help-wanted` (or post a comment requesting it to be labelled). + +This will allow other contributors to help add the missing platform support by making changes to your existing PR. + +### Our expectations on you as a contributor + +To quote [@alloy](https://github.com/alloy) from [this issue](https://github.com/Moya/Moya/issues/135); "Do not ever feel bad for not contributing to open source". + +We want contributors to provide ideas, keep the ship shipping and to take some of the load from others. It is non-obligatory; we’re here to get things done in an enjoyable way. :trophy: + +The fact that you will have push access will allow you to: + +- Avoid having to fork the project if you want to submit other pull requests as you will be able to create branches directly on the project. +- Help triage issues and merge pull requests. +- Pick up the project if other maintainers move their focus elsewhere. + +It is up to you to use those superpowers or not though 😉 + +We ask though that you follow the conduct guidelines set out in our [Code of Conduct](/CODE_OF_CONDUCT.md) throughout your contribution journey. + +### What about if you have problems that cannot be discussed in a public issue? + +You can reach out to us directly via Discord direct messages or Twitter if you'd like to discuss something privately, alternatively you can also email us at oss@invertase.io + +#### Project Owners + +- [Salakar](https://github.com/Salakar) + - Twitter: [@mikediarmid](https://twitter.com/mikediarmid) + - Discord: `Salakar#1337` + +- [Ehesp](https://github.com/Ehesp) + - Twitter: [@elliothesp](https://twitter.com/elliothesp) + - Discord: `Alias#3980` + +## Code Guidelines + +### Your First Contribution + +Working on your first Pull Request? You can learn how from this _free_ series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). + +### Implementation Guidelines + +- Ensure any new JS implementations match the official Firebase JS SDK implementation + - This includes matching up with the same method names, types, usages, inputs and outputs + - In some instances this is not always possible e.g. a Firebase Module that does not exist in the Web SDK, such as `crashlytics()` or the implementation can't work (or not performant) in the React Native environment, such as `storage().putString()` +- Methods/Features that are specific to a single platform only should be namespaced as such in your implementation + - For example when implementing an iOS **only** method: + - [❌] `firebase.crashlytics().someNewMethodForIos()` + - [✅] `firebase.crashlytics().ios.someNewMethod()` + - If a method works on both platforms then there's no need to namespace it +- Name your native code methods the same as the JS method name + - e.g. the Android (`@ReactMethod`) implementation of `firebase.auth().signInWithEmailAndPassword()` is named `signInWithEmailAndPassword` + +### Testing + + + Our library is fully tested using our own Jet library. To find out more, read our + documentation on how to test the React Native Firebase module. + + +### Submitting code for review + +Any code changes that are ready to be merged for release should be submitted as a pull request to the relevant branch, for upcoming / in-development releases this branch would be the `master` branch, for historic/old releases (e.g. patching a bug on an older version) this would be the versions parked branch e.g. `v4.x.x`. + +The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge. It is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you? Tag in any linked issues. + +To aid review we also ask that you fill out the PR template as much as possible. + +> Please include `[WIP]` at the start of your pull request title if the pull request is not yet complete. + +### Code review process + +Pull Requests to the protected branches require two or more peer-review approvals and passing status checks to be able to be merged. + +When reviewing a Pull Request please check the following: + +- Does the PR provide cross-platform support? + - i.e. adding a new feature then does the implementation provide iOS and Android support. + - Pull Requests should not be merged or approved unless both platforms are supported (unless the feature is specific to one platform only) +- Pull Request is not still tagged as `WIP` if it's ready to be merged/reviewed +- Pull Request follows the Firebase Web SDKs API/implementation + - In some instances this is not always possible e.g. Firebase Module does not exist in the Web SDK, such as `crashlytics()` or the implementation can't work (or not performant) in the React Native environment, such as `storage().putString()` +- Types + - Have flow types been added? + - Have Typescript types been added? +- Does the PR provide docs (e.g. links to a separate docs PR on the docs repo) +- Have `e2e` tests been updated or new tests been added to test newly implemented or changed functionality. +- Does the PR provide valid change log entries + +If you made it all the way to the end, bravo dear user, we love you. You can include the 🔥 emoji at the bottom of your ticket to signal to us that you did in fact read this file and are trying to conform to it as best as possible: `:fire:`. diff --git a/docs/pages/contributing/testing.mdx b/docs/pages/contributing/testing.mdx new file mode 100644 index 00000000..3ab39bac --- /dev/null +++ b/docs/pages/contributing/testing.mdx @@ -0,0 +1,109 @@ +# Testing + +> The tests project is located on the main repository in [/tests](https://github.com/invertase/react-native-firebase/tree/master/tests). + +Our tests are powered by [Jet ✈️](https://github.com/invertase/jet). + +> **Note**: instructions in this file assume you're running terminal commands from the root of the project and not from inside the tests directory. + +## Requirements + +- Make sure you have Xcode installed (tested with Xcode 9.2+). +- Make sure you have NodeJS installed (Node 8.4.0 and up is required). +- Make sure you have all required dependencies installed: + - [Apple Sim Utils](https://github.com/wix/AppleSimulatorUtils): + + ```bash + brew tap wix/brew + brew install wix/brew/applesimutils + ``` + +### Step 1: Install test project dependencies + +Yarn install at project root and also inside tests directory. + +Also install tests project iOS Pods. + +```bash +yarn +cd tests/ && yarn +cd tests/ios && pod install --repo-update +``` + +### Step 2: Start Packager Script + +Start the React Native packager using the script provided; + +```bash +cd tests/ && yarn run packager-jet +``` + +> ⚠️ It must be this script only that starts the RN Packager, using the default RN packager command will not work. + +> ⚠️ Also ensure that all existing packagers are terminated and that you have no React Native debugger tabs open on your browsers. + +> This packager will automatically rebuild on any JS changes to the library code. You don't need to restart this, leave it running whilst developing. + +--- + +### Step 3: Build Native App + +As always; the first build for each platform will take a while. Subsequent builds are much much quicker ⚡️ + +> ⚠️ You must rebuild native every time you make changes to native code (anything in /android /ios directories). + +#### Android + +```bash +cd tests/ && yarn run build-android +``` + +#### iOS + +```bash +cd tests/ && yarn run build-ios +``` + +### Step 4: Finally, run the tests + +This action will launch a new simulator (if not already open) and run the tests on it. + +> 💡 iOS by default will background launch the simulator - to have +> it launch in the foreground make sure any simulator is currently open, `Finder -> Simulator.app`. + +> 💡 Android by default looks for a pre-defined emulator named `TestingAVD` - make sure you have one named the same setup on Android Studio. +> Or you can change this name in the `package.json` of the tests project (don't commit the change though please). +> **DO NOT** rename an existing AVD to this name - it will not work, rename does not change the file path currently so Detox will +> fail to find the AVD in the correct directory. Create a new one with Google Play Services. + +#### Android + +```bash +cd tests/ && yarn run test-android +``` + +#### iOS + +```bash +cd tests/ && yarn run test-ios +``` + +The `test-${platform}` commands uninstall any existing app and installs a fresh copy. You can +run `test-${platform}-reuse` instead if you don't need to re-install the app (i.e only making JS code changes). +Just remember to use `test-${platform}` if you made native code changes and rebuilt - after installing once you can +go back to using the `reuse` variant. + +The `cover` variant of the yarn scripts will additionally run tests with coverage. +Coverage is output to the root directory of the project: `react-native-firebase/coverage`, +open `react-native-firebase/coverage/lcov-report/index.html` in your browser after running tests +to view detailed coverage output. + +### Running specific tests + +Mocha supports the `.only` syntax, e.g. instead of `describe(...) || it(...)` you can use `describe.only(...) || it.only(...)` to only run that specific context or test. + +Another way to do this is via adding a `--grep` option to e2e/mocha.opts file, e.g. `--grep auth` for all tests that have auth in the file path or tests descriptions. + +> 💡 Don't forget to remove these before committing your code and submitting a pull request + +For more Mocha options see https://mochajs.org/#usage diff --git a/docs/pages/faqs/duplicate-undefined-symbols.mdx b/docs/pages/faqs/duplicate-undefined-symbols.mdx new file mode 100644 index 00000000..b02111e2 --- /dev/null +++ b/docs/pages/faqs/duplicate-undefined-symbols.mdx @@ -0,0 +1,23 @@ +--- +title: Duplicate/Undefined Symbols +description: This error occurs during iOS build time. Fixing this error requires a clean of your project. +tags: + - build + - ios +--- + +# Duplicate Symbols / Undefined Symbols + +Running updates to your project with multiple and/or changing versions can cause XCode to become +confused about the expected version required to build your project. The can happen when updating to a +new version of React Native Firebase, or updating another projects pods. + +Fixing the error requires the project to be cleaned and the projects dependancies to be re-installed: + +1. Open the `/ios/.xcworkspace` file using XCode. +2. Select Product > Clean Build Folder. +3. Close XCode fully. +4. From your terminal, run `pod install` from the project `/ios` directory. +5. Reopen the `/ios/.xcworkspace` file using XCode. +6. Rerun Product > Clean Build Folder. +7. Rerun your iOS build. diff --git a/docs/pages/faqs/enabling-database-persistence.mdx b/docs/pages/faqs/enabling-database-persistence.mdx new file mode 100644 index 00000000..ab272fc1 --- /dev/null +++ b/docs/pages/faqs/enabling-database-persistence.mdx @@ -0,0 +1,58 @@ +--- +title: Enabling Database Persistence +description: Database persistence is disabled by default. Learn how to enable it for your application. +tags: + - android + - ios + - database +--- + +# Enabling Database Persistence + +To avoid race conditions between native modules and React Native, setting the database persistence +option via the `firebase.database.setPersistence()` method was deprecated from version 3.0.0 of +React Native Firebase. + +To enable persistence, changes must be made to the native code on both Android and iOS. + +## Android + +1. Open your projects `android/app/src/main/java/com/[project]/MainActivity.java` file. +2. Import the `FirebaseDatabase` module, by adding the following import at the top of your file: + +```java{4} +package com.mypackage; + +... +import com.google.firebase.database.FirebaseDatabase; +... +``` + +3. Add the `setPersistenceEnabled` method to your `onCreate` method: + +```java{4} + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + FirebaseDatabase.getInstance().setPersistenceEnabled(true); + ... + } +``` + +Rebuild your Android project. + +## iOS + +1. Open your projects `ios/[project].xcworkspace`. +2. Within the `didFinishLaunchingWithOptions` method, add the following line after `[FIRApp configure]`: + +```objectivec{5} +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + ... + [FIRApp configure]; + [FIRDatabase database].persistenceEnabled = YES; +} +``` + +Rebuild your iOS project. diff --git a/docs/pages/faqs/failed-to-recognize-googleservice-info-plist.mdx b/docs/pages/faqs/failed-to-recognize-googleservice-info-plist.mdx new file mode 100644 index 00000000..d2837388 --- /dev/null +++ b/docs/pages/faqs/failed-to-recognize-googleservice-info-plist.mdx @@ -0,0 +1,29 @@ +--- +title: GoogleService-Info.plist was not recognized +description: Your GoogleService-Info.plist file needs to be registered within XCode before using React Native Firebase with iOS. +tags: + - build + - ios +--- + +# GoogleService-Info.plist was not recognized + +The GoogleService-Info.plist file provides Firebase with your projects credentials to connect +to your Firebase Project. Without this file, your app will crash right after booting. + +Unfortunatly, the file needs to be registered with XCode in order to be recognised. Even with the file +present within your projects `/ios` directory, XCode will ignore it if it has not been registered. + +## Registering the plist file + +To register the file, open XCode and select your projects `/ios` directory. Ensure your GoogleService-Info.plist +file has been downloaded and added to this directory. + +> Can't find the plist file? Follow the [iOS installation guide](/{{ latest_version }}/installation/ios). + +- At the top left of Xcode,select the directory listing icon (folder icon). +- Right click on your project name and select `Add files to [project]`. +- Select the GoogleService-Info.plist file. +- Click "Add". + +Now rebuild your project, XCode should successfully recognise the file. diff --git a/docs/pages/faqs/flow.mdx b/docs/pages/faqs/flow.mdx new file mode 100644 index 00000000..70ff5d77 --- /dev/null +++ b/docs/pages/faqs/flow.mdx @@ -0,0 +1,6 @@ +--- +title: Using Flow +description: Flow is a static type checker for JavaScript. Learn how you can use it with React Native Firebase. +--- + +# Flow diff --git a/docs/pages/faqs/index.mdx b/docs/pages/faqs/index.mdx new file mode 100644 index 00000000..a5735c8f --- /dev/null +++ b/docs/pages/faqs/index.mdx @@ -0,0 +1,11 @@ +--- +paginate: faqs +title: Frequently Asked Questions +description: Running into an issue or have a question? It may be something which we have added to our Frequently Asked Questions +--- + +# Frequently Asked Questions + +Do you have a question or issue about React Native, Firebase or your build? It may be one of our Frequently Asked Questions! + + diff --git a/docs/pages/faqs/missing-byte-code.mdx b/docs/pages/faqs/missing-byte-code.mdx new file mode 100644 index 00000000..81e4004f --- /dev/null +++ b/docs/pages/faqs/missing-byte-code.mdx @@ -0,0 +1,26 @@ +--- +title: Missing Byte Code Error +description: The 'Missing Byte Code' error occurs during Android Build time due to a known issue with the Android Tools Plugin. +tags: + - build + - android +--- + +# Missing Byte Code (build time error) + +The Missing Byte Code error is a known issue which is triggered when running apps from within Android Studio, +whilst using the 3.1.x version of the Android tools plugin. + +The issue can be tracked here: https://issuetracker.google.com/issues/72811718 + +To fix this issue, you need to disable Instant Run within Android Studio. + +> Instant Run is an Android Studio 2.3+ feature which helps to significantly reduce the time it takes to update the APK with code and resources changes. + +## Disabling Instant Run + +To [disable Instant Run](https://developer.android.com/studio/run/#disable-ir), follow the below steps with Android Studio: + +1. Open the **Settings** or **Preferences** dialog. +2. Navigate to **Build, Execution, Deployment > Instant Run**. +3. Uncheck the box next to **Enable Instant Run**. diff --git a/docs/pages/faqs/multiple-dex-files.mdx b/docs/pages/faqs/multiple-dex-files.mdx new file mode 100644 index 00000000..2590c63b --- /dev/null +++ b/docs/pages/faqs/multiple-dex-files.mdx @@ -0,0 +1,63 @@ +--- +title: Multiple Dex Files Error +description: The 'Multiple dex files' error is common when dealing with multiple libraries which use Google Play Services when building for Android. +tags: + - build + - android +--- + +# Multiple Dex Files error (build time error) + +The Multiple Dex Files error is a common error which occurs in Android projects which use +libaries which require Google Play Services. When libaries require different versions of +Google Play Services, the following error is thrown when building the Android APK: + +``` +Failed on android with com.android.dex.DexException: Multiple dex files... +``` + +The process for fixing the error requires manual checking of your installed native libaries, +then updating your `android/app/build.gradle` file to force those libaries to use a specific version +of Google Play Services. + +> Check out [this blog post](https://medium.com/@suchydan/how-to-solve-google-play-services-version-collision-in-gradle-dependencies-ef086ae5c75f) for a full explanation of the issue. + +To identify libaries which use Google Play Services, search your projects `node_modules` directory +for any native React Native module you have installed. Within those projects, open the `android/build.gradle` +file, and within the `dependencies` block, identify any which start with: + +- `com.google.android.gms` +- `com.google.firebase` + +Once identified, open your own `android/app/build.gradle` file, and within the `dependencies` block exclude +the service using the following syntax: + +```groovy:title=react-native-device-info example +dependencies { + ... + compile (project(':react-native-device-info')){ + exclude group: "com.google.android.gms" + } +} +``` + +The next step is to then lock a specific version fo the Google Play Service package which the module uses: + +```groovy:title=react-native-device-info example +dependencies { + ... + compile (project(':react-native-device-info')){ + exclude group: "com.google.android.gms" + } + + ... + compile ("com.google.android.gms:play-services-base:10.0.1") { + force = true; + } +} +``` + +Repeat this process for each conflicting Google Play Services module. + +Once complete, run `./gradlew clean` within the `android` directory of your project and rebuild +your android project. diff --git a/docs/pages/faqs/rnfb-vs-web-sdk.mdx b/docs/pages/faqs/rnfb-vs-web-sdk.mdx new file mode 100644 index 00000000..b133b8fe --- /dev/null +++ b/docs/pages/faqs/rnfb-vs-web-sdk.mdx @@ -0,0 +1,70 @@ +--- +title: React Native Firebase vs Firebase Web SDK +description: Using React Native Firebase enables you to utilise native features which are not available when using the Firebase Web SDK. +--- + +# React Native Firebase vs Firebase Web SDK + +The [Firebase web SDK](https://www.npmjs.com/package/firebase) is a JavaScript +package available on Node Package Manager (NPM), supporting both the web (browser) and +server (Node.js) clients. Firebase offers a magnitude of services for your application, however, some of these +some services are tailored towards native Android & iOS devices. + +React Native Firebase (RNF) provides a JavaScript interface into the native Firebase +[Android](https://firebase.google.com/docs/android/setup) and +[iOS](https://firebase.google.com/docs/ios/setup) SDKs. For added benefit, we've +tried to ensure that our library mimics that of the web SDK where possible. + +There are both advantages and disadvantages to using React Native Firebase over the Firebase +web SDK. + +## Advantages + +### Native modules + +In the React Native ecosystem, native modules are referred to when the module in question utilises the +underlying device APIs. React Native provides native access to both Android and iOS devices, +allowing developers to create JavaScript modules which interface with native APIs. + +With the native Firebase SDKs installed, React Native Firebase provides a JavaScript module which allows +developers to interface with the native modules which wouldn't otherwise be available via the web SDK. +For example, the Firebase Analytics module logs advanced information such as the users device Android/iOS +version with every event, something which is only possible with the use of native modules. + +### Performance + +Performance is prehaps the most important aspect of any production application. The [React Native documentation](https://facebook.github.io/react-native/docs/performance) does a great +job of explaining performance within React Native. + +RNF performs all resource intenstive tasks using native APIs, taking advantage of complex concepts +such as [threading](https://developer.android.com/guide/components/processes-and-threads). Keeping these tasks +native ensures that the UI or JavaScript threads are kept free for critial user actions such as touch +events or scrolling, helping remove [jank](http://jankfree.org/). + +## Disadvantages + +### Initial setup + +Installing a React Native module which uses native modules requires knowledge of the Android +and iOS environments. Developers with little or no experience of these environements may find +the initial installation process complex and daunting, or encounter issues with process due to their +local environment setup. + +To help overcome this process, the following list of resources are worth bookmarking and understanding +before diving into native modules: + +- [Frequently Asked Questions](/faqs) - your issue or question may already be answered in our list of FAQs. +- Native modules: [iOS](https://facebook.github.io/react-native/docs/native-modules-ios) and [Android](https://facebook.github.io/react-native/docs/native-modules-android). +- [Understanding Gradle](https://medium.com/@Miqubel/understanding-gradle-db402d003ae8) - Android equivilent of JavaScripts NPM. +- [Understanding CocoaPods](https://www.objc.io/issues/6-build-tools/cocoapods-under-the-hood/) - iOS equivilent of JavaScripts NPM. +- [Firebase Android SDK Documentation](https://firebase.google.com/docs/android/setup) - understand the native SDK for Firebase Android. +- [Firebase iOS SDK Documentation](https://firebase.google.com/docs/ios/setup) - understand the native SDK for Firebase iOS. +- [Android Studio](https://developer.android.com/studio/) - The IDE for Android development. +- [XCode](https://developer.apple.com/xcode/) - The Mac IDE for Apple development. + +### Firebase changes + +Firebase are constantly improving their service with regular [updates and changes](https://firebase.google.com/support/releases?authuser=0). + +Although the developers here at Invertase strive to keep the library inline with the web SDK, +there may be times where the implememtation of new feaatures and changes lag behind the offical SDK. diff --git a/docs/pages/faqs/typescript.mdx b/docs/pages/faqs/typescript.mdx new file mode 100644 index 00000000..965bdeca --- /dev/null +++ b/docs/pages/faqs/typescript.mdx @@ -0,0 +1,8 @@ +--- +title: Using Typescript +description: React Native Firebase is fully compatible with TypeScript. Learn how to use it in your existing React Native project. +--- + +# TypeScript + +TODO diff --git a/docs/pages/feedback/index.mdx b/docs/pages/feedback/index.mdx new file mode 100644 index 00000000..80008800 --- /dev/null +++ b/docs/pages/feedback/index.mdx @@ -0,0 +1,6 @@ +--- +layout: blank +title: Feedback +--- + + diff --git a/docs/pages/guides/getting-started-with-rnfb.mdx b/docs/pages/guides/getting-started-with-rnfb.mdx new file mode 100644 index 00000000..48aa96c0 --- /dev/null +++ b/docs/pages/guides/getting-started-with-rnfb.mdx @@ -0,0 +1,8 @@ +--- +title: Getting Started with React Native Firebase +description: Learn how to integrate React Native Firebase into your React Native project. This guide covers installation for both Android & iOS, and integration with additional Firebase services. +--- + +# Getting Started + +TODO diff --git a/docs/pages/guides/index.mdx b/docs/pages/guides/index.mdx new file mode 100644 index 00000000..829cab3b --- /dev/null +++ b/docs/pages/guides/index.mdx @@ -0,0 +1,9 @@ +--- +paginate: guides +title: Guides +description: Our indepth guides cover the basics to advanced topics to help you get the most our of your application. +--- + +# Guides + + diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx new file mode 100644 index 00000000..7a5a0705 --- /dev/null +++ b/docs/pages/index.mdx @@ -0,0 +1,105 @@ +--- +title: Overview +layout: overview +--- + + + + Install React Native Firebase with our step by step guide for + JavaScript, Android & iOS. + + + Getting started with React Native Firebase, or looking for + advanced topics? Our guides are a great place to start. + + + Start your next project with full module API reference, + descriptions and examples. + + + +## Supported Firebase Products + + + + + + Resources + + + Keep up to date with the features an fixes in our versioned release guides. The latest version is v5.x.x. + + + Have a question? It may be answered in our of our Frequently Asked Questions. + + + Found a bug or need further help with the library - find out how and where you can get support. + + + Interested in contributing to the library but don't know where to start? + + + Do you have a feature request or would like to provide constructive feedback to the libary? + Add a request to our Canny board. + + + Our active and helpful community chat can be found on our Discord server. + + + + + + ]} + > + Github + + + + diff --git a/docs/pages/releases/index.mdx b/docs/pages/releases/index.mdx new file mode 100644 index 00000000..324733ad --- /dev/null +++ b/docs/pages/releases/index.mdx @@ -0,0 +1,9 @@ +--- +paginate: releases +title: Releases +description: Keep up to date with the lastest release change logs! +--- + +# Releases + + diff --git a/docs/pages/releases/v5.1.x.mdx b/docs/pages/releases/v5.1.x.mdx new file mode 100644 index 00000000..9e326145 --- /dev/null +++ b/docs/pages/releases/v5.1.x.mdx @@ -0,0 +1,8 @@ +--- +title: Version 5.1.x +description: v5.1.x +--- + +# Version 5.1.x + +TODO diff --git a/docs/pages/releases/v5.2.x.mdx b/docs/pages/releases/v5.2.x.mdx new file mode 100644 index 00000000..8e4971ef --- /dev/null +++ b/docs/pages/releases/v5.2.x.mdx @@ -0,0 +1,118 @@ +--- +title: Version 5.2.x +description: Version 5.2.0 includes bug fixes for Messaging, TypeScript, Flow and enhancements for Notifications, Firestore and Crashlytics. +--- + +# Version 5.2.x + +Install using: + +```bash +npm install --save react-native-firebase@latest +``` + +This is mainly a bug fix and Firebase SDK versions update release. + +> This release added quite a few new tests to further ensure future stability, we're now at [480 tests](https://github.com/invertase/react-native-firebase/tree/master/tests/e2e) 🤯 and ~80% overall coverage 🎉 + +> Check out our [upcoming plans for React Native Firebase blog post](https://blog.invertase.io/react-native-firebase-2019-7e334ca9bcc6). + +## Bug Fixes + + - [IOS] [BUGFIX] [MESSAGING] Fix getToken() always returning initialToken (Fixes #1510) + - [IOS] [BUGFIX] [MESSAGING] Fix `backgroundFetchResult` typo for failure (Fixes #1772) + - [IOS] [BUGFIX] [MESSAGING] `hasPermission` now correctly resolves a boolean value instead of `1` or `0` (Fixes #1547) + - [IOS] [BUGFIX] [FIRESTORE] Fix "Unsupported value sent to buildTypeMap" error. Firestore nulls had changed type on the iOS SDK from nil to NSNull. (Fixes #1788) (PR #1790) + - [JS] [BUGFIX] [CORE] - App names now correctly uppercased on all environments (js, ios & android) - fixes a bug where getting a Firebase app by name would sometimes not find the app. + - [TYPES] [TS] [BUGFIX] [FIRESTORE] Fix incorrect `toUint8Array` definition (Fixes #1715) + - [TYPES] [FLOW] [BUGFIX] [FIRESTORE] Update `id` getter to return `string` only (removed `| null`) (Fixes #1205) + - [TYPES] [TS] [BUGFIX] [MESSAGING] Fix Messaging requestPermission return type (PR #1513) + - [TYPES] [TS] [BUGFIX] [MESSAGING] Fix Messaging interface and MessagingStatic's ios property (PR #1800) + - [TYPES] [FLOW] [BUGFIX] [MESSAGING] Notification `notifications` arg incorrectly annotated as required (Fixes #1558) + - [TYPES] [TS] [BUGFIX] [DATABASE] Use correct `DataSnapshot` definition for `.once()` return value (Fixes #1515) + +## Enhancements + + - [IOS] [ENHANCEMENT] [NOTIFICATIONS] Allow handling `NSUserNotificationCenter` completion handlers (PR #1803) + - [IOS] [ANDROID] [ENHANCEMENT] [FIRESTORE] `arrayUnion` & `arrayRemove` now also accept `DocumentReference`s & JS objects + - [IOS] [ANDROID] [ENHANCEMENT] [CRASHLYTICS] Added support for `firebase.crashlytics().enableCrashlyticsCollection()` (PR #1718) + +## Misc + + - [IOS] [INTERNAL] Library Xcode Project set deployment to iOS 9 and above, formally 8. (RN is 9+ so this shouldn't be an issue for anyone) (PR #1784) + - [IOS] [ANDROID] [INTERNAL] [MESSAGING] `getToken` & `deleteToken` now use Firebase `InstanceID` token management apis (with an FCM scope) + - [ANDROID] [DEPRECATION] [MESSAGING] Deprecate `RNFirebaseInstanceIdService` in favour of `FirebaseMessagingService`'s `onNewToken` event. Remove this service from your `AndroidManifest.xml` + +---- + +## Upgrade instructions + +``` +npm install --save react-native-firebase@latest +``` + +---- +### Android - Messaging + +Remove the following deprecated service from your AndroidManifest if you have it; + +```xml + + + + + +``` + +This functionality is now covered by the `RNFirebaseMessagingService` service which should already be in your AndroidManifest if you had the service above. + +### Android - Update Firebase SDKs + +1) In `android/app/build.gradle`, update all the firebase and gms dependencies to the following versions: + +- **com.google.android.gms:play-services-base**:16.0.1 +- **com.google.firebase:firebase-core**:16.0.6 +- **com.google.firebase:firebase-ads**:15.0.1 +- **com.google.firebase:firebase-auth**:16.1.0 +- **com.google.firebase:firebase-config**:16.1.2 +- **com.google.firebase:firebase-database**:16.0.5 +- **com.google.firebase:firebase-functions**:16.1.3 +- **com.google.firebase:firebase-invites**:16.0.6 +- **com.google.firebase:firebase-firestore**:17.1.5 +- **com.google.firebase:firebase-messaging**:17.3.4 +- **com.google.firebase:firebase-perf**:16.2.3 +- **com.google.firebase:firebase-storage**:16.0.5 +- **com.crashlytics.sdk.android:crashlytics**:2.9.5 + +--- + +### iOS - Update Firebase SDKs + +v5.2.0 supports iOS SDK version `5.10.0` and above; however it's recommended to update to `v5.15.0` and set the versions specifically in your `Podfile`: + +```ruby + pod 'Firebase/AdMob', '~> 5.15.0' + pod 'Firebase/Auth', '~> 5.15.0' + pod 'Firebase/Core', '~> 5.15.0' + pod 'Firebase/Database', '~> 5.15.0' + pod 'Firebase/Functions', '~> 5.15.0' + pod 'Firebase/DynamicLinks', '~> 5.15.0' + pod 'Firebase/Firestore', '~> 5.15.0' + pod 'Firebase/Invites', '~> 5.15.0' + pod 'Firebase/Messaging', '~> 5.15.0' + pod 'Firebase/RemoteConfig', '~> 5.15.0' + pod 'Firebase/Storage', '~> 5.15.0' + pod 'Firebase/Performance', '~> 5.15.0' + + # Crashlytics + pod 'Fabric', '~> 1.7.11' + pod 'Crashlytics', '~> 3.10.7' +``` + +## Feedback + +We want your feedback! + +If you have any comments and suggestions or want to report an issue, come find us on [Discord](https://discord.gg/C9aK28N), [Twitter](https://twitter.com/rnfirebase) or [GitHub](https://github.com/invertase/react-native-firebase). + +Thank to [all the contributors](https://github.com/invertase/react-native-firebase/graphs/contributors?from=2018-06-28&to=2020-01-01&type=c) that made this release happen 💛. diff --git a/docs/project.yaml b/docs/project.yaml new file mode 100644 index 00000000..7658a79e --- /dev/null +++ b/docs/project.yaml @@ -0,0 +1,14 @@ +--- +name: React Native Firebase +npm: react-native-firebase +repository: invertase/react-native-firebase +description: React Native Firebase is a light-weight javascript layer connecting you + to the native Firebase SDKs for both iOS and Android which mirrors the official + Firebase Web SDK as closely as possible. +theme: + logo: "//static.invertase.io/assets/React-Native-Firebase.svg" + primary: "#E57A2E" + secondary: '#F8C449' +social: + twitter: 'https://twitter.com/rnfirebase' + discord: 'https://discordapp.com/invite/XsKpw4' diff --git a/docs/v5.x.x/index.mdx b/docs/v5.x.x/index.mdx new file mode 100644 index 00000000..8d93aa7d --- /dev/null +++ b/docs/v5.x.x/index.mdx @@ -0,0 +1,3 @@ +--- +redirect: /{{ version }}/installation +--- diff --git a/docs/v5.x.x/variables.yaml b/docs/v5.x.x/variables.yaml new file mode 100644 index 00000000..2daf8cc4 --- /dev/null +++ b/docs/v5.x.x/variables.yaml @@ -0,0 +1,45 @@ +android: + build: + tools: 3.1.3 + fabric: + tools: 1.25.4 + version: 2.9.4 + firebase: + version: 16.0.3 + ads: 15.0.1 + analytics: 16.0.3 + auth: 16.0.3 + config: 16.0.0 + core: 16.0.3 + crash: 16.0.1 + crashlytics: 2.9.5 + database: 16.0.2 + firestore: 17.1.0 + functions: 16.1.0 + invites: 16.0.3 + messaging: 17.3.2 + perf: 16.1.0 + storage: 16.0.2 + plugins: 1.1.1 + gms: + google-services: 4.0.1 + play-services-base: 15.0.1 +ios: + fabric: + tools: 1.7.11 + version: 3.10.7 + firebase: + ads: 5.9.0 + auth: 5.9.0 + config: 5.9.0 + core: 5.9.0 + crash: 5.9.0 + crashlytics: 3.10.7 + database: 5.9.0 + firestore: 5.9.0 + functions: 5.9.0 + invites: 5.9.0 + links: 5.9.0 + messaging: 5.9.0 + perf: 5.9.0 + storage: 5.9.0 diff --git a/docs/v6.x.x/.gitkeep b/docs/v6.x.x/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/v6.x.x/typedoc.json b/docs/v6.x.x/typedoc.json new file mode 100644 index 00000000..7237f23e --- /dev/null +++ b/docs/v6.x.x/typedoc.json @@ -0,0 +1 @@ +[{"namespace":"firebase\n","description":"","properties":[],"methods":[],"statics":[],"classes":[]},{"namespace":"analytics\n","description":"Analytics integrates across Firebase features and provides\nyou with unlimited reporting for up to 500 distinct events\nthat you can define using the Firebase SDK. Analytics reports\nhelp you understand clearly how your users behave, which enables\nyou to make informed decisions regarding app marketing and\nperformance optimizations.","properties":[{"kind":"Property","id":40,"name":"app","inherited":"TODO","returns":"TODO"}],"methods":[{"kind":"Method","id":7,"name":"logEvent","signatures":[{"kind":"Signature","id":8,"name":"logEvent","parameters":[{"kind":"Parameter","id":9,"name":"name","optional":false,"type":{"type":"intrinsic","name":"string"}},{"kind":"Parameter","id":10,"name":"params","optional":false,"description":"\n","type":{"type":"reflection","declaration":{"id":11,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"indexSignature":[{"id":12,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":13,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"intrinsic","name":"string"}}],"sources":[{"fileName":"analytics/lib/index.d.ts","line":52,"character":34}]}}}],"description":"","tags":[]}]},{"kind":"Method","id":14,"name":"setAnalyticsCollectionEnabled","signatures":[{"kind":"Signature","id":15,"name":"setAnalyticsCollectionEnabled","parameters":[{"kind":"Parameter","id":16,"name":"enabled","optional":false,"description":"\n","type":{"type":"intrinsic","name":"boolean"}}],"description":"","tags":[]}]},{"kind":"Method","id":17,"name":"setCurrentScreen","signatures":[{"kind":"Signature","id":18,"name":"setCurrentScreen","parameters":[{"kind":"Parameter","id":19,"name":"screenName","optional":false,"type":{"type":"intrinsic","name":"string"}},{"kind":"Parameter","id":20,"name":"screenClassOverride","optional":false,"description":"\n","type":{"type":"intrinsic","name":"string"}}],"description":"","tags":[]}]},{"kind":"Method","id":21,"name":"setMinimumSessionDuration","signatures":[{"kind":"Signature","id":22,"name":"setMinimumSessionDuration","parameters":[{"kind":"Parameter","id":23,"name":"milliseconds","optional":false,"description":"The default value is 10000 (10 seconds).\n","type":{"type":"intrinsic","name":"number"}}],"description":"","tags":[]}]},{"kind":"Method","id":24,"name":"setSessionTimeoutDuration","signatures":[{"kind":"Signature","id":25,"name":"setSessionTimeoutDuration","parameters":[{"kind":"Parameter","id":26,"name":"milliseconds","optional":false,"description":"The default value is 1800000 (30 minutes).\n","type":{"type":"intrinsic","name":"number"}}],"description":"","tags":[]}]},{"kind":"Method","id":27,"name":"setUserId","signatures":[{"kind":"Signature","id":28,"name":"setUserId","parameters":[{"kind":"Parameter","id":29,"name":"id","optional":false,"description":"Set to null to remove a previously assigned id from analytics events\n","type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"description":"","tags":[]}]},{"kind":"Method","id":34,"name":"setUserProperties","signatures":[{"kind":"Signature","id":35,"name":"setUserProperties","parameters":[{"kind":"Parameter","id":36,"name":"properties","optional":false,"description":"Set a property value to null to remove it.\n","type":{"type":"reflection","declaration":{"id":37,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"indexSignature":[{"id":38,"name":"__index","kind":8192,"kindString":"Index signature","flags":{},"parameters":[{"id":39,"name":"key","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}}],"type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"sources":[{"fileName":"analytics/lib/index.d.ts","line":110,"character":33}]}}}],"description":"","tags":[]}]},{"kind":"Method","id":30,"name":"setUserProperty","signatures":[{"kind":"Signature","id":31,"name":"setUserProperty","parameters":[{"kind":"Parameter","id":32,"name":"name","optional":false,"type":{"type":"intrinsic","name":"string"}},{"kind":"Parameter","id":33,"name":"value","optional":false,"description":"Set to null to remove a previously assigned id from analytics events.\n","type":{"type":"union","types":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"null"}]}}],"description":"","tags":[]}]}],"statics":[],"classes":[{"id":3,"name":"Testy","properties":[],"methods":[{"kind":"Method","id":4,"name":"val","signatures":[{"kind":"Signature","id":5,"name":"val","parameters":[]}]}]}]},{"namespace":"utils\n","description":"Provides various helpers for using Firebase in React Native.","properties":[],"methods":[],"statics":[],"classes":[]}] diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj deleted file mode 100644 index b05e6435..00000000 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ /dev/null @@ -1,618 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 168785AD210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 168785AB210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.m */; }; - 17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = 17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */; }; - 27540F9A209F3641001F4AF4 /* RNFirebaseFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 27540F99209F3641001F4AF4 /* RNFirebaseFunctions.m */; }; - 8300A7AE1F31E143001B16AB /* RNFirebaseDatabaseReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */; }; - 8323CF061F6FBD870071420B /* BannerComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CEFF1F6FBD870071420B /* BannerComponent.m */; }; - 8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF011F6FBD870071420B /* NativeExpressComponent.m */; }; - 8323CF081F6FBD870071420B /* RNFirebaseAdMobBannerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */; }; - 8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */; }; - 833693131FD824EF00AA806B /* RNFirebaseCrashlytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */; }; - 8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */; }; - 8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */; }; - 8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */; }; - 838E36FE201B9169004DCD3A /* RNFirebaseMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */; }; - 838E372320231DF0004DCD3A /* RNFirebaseInstanceId.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */; }; - 838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E372520231E15004DCD3A /* RNFirebaseNotifications.m */; }; - 839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; }; - 839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; }; - 839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; }; - 839D916F1EF3E20B0077C7C8 /* RNFirebaseAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91561EF3E20A0077C7C8 /* RNFirebaseAnalytics.m */; }; - 839D91701EF3E20B0077C7C8 /* RNFirebaseAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91591EF3E20A0077C7C8 /* RNFirebaseAuth.m */; }; - 839D91711EF3E20B0077C7C8 /* RNFirebaseRemoteConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915C1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.m */; }; - 839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */; }; - 839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */; }; - 83AAA0792063DEC2007EC5F7 /* RNFirebaseInvites.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */; }; - 83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */; }; - BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */; }; - D950369E1D19C77400F7094D /* RNFirebase.m in Sources */ = {isa = PBXBuildFile; fileRef = D950369D1D19C77400F7094D /* RNFirebase.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 58B511D91A9E6C8500147676 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 134814201AA4EA6300B7C361 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 168785AB210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+UIBackgroundFetchResult.m"; sourceTree = ""; }; - 168785AC210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+UIBackgroundFetchResult.h"; sourceTree = ""; }; - 17AF4F691F59CDBF00C02336 /* RNFirebaseLinks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseLinks.h; sourceTree = ""; }; - 17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseLinks.m; sourceTree = ""; }; - 27540F98209F361B001F4AF4 /* RNFirebaseFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFunctions.h; sourceTree = ""; }; - 27540F99209F3641001F4AF4 /* RNFirebaseFunctions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFunctions.m; sourceTree = ""; }; - 8300A7AC1F31E143001B16AB /* RNFirebaseDatabaseReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseDatabaseReference.h; sourceTree = ""; }; - 8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseDatabaseReference.m; sourceTree = ""; }; - 8323CEFE1F6FBD870071420B /* BannerComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerComponent.h; sourceTree = ""; }; - 8323CEFF1F6FBD870071420B /* BannerComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BannerComponent.m; sourceTree = ""; }; - 8323CF001F6FBD870071420B /* NativeExpressComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeExpressComponent.h; sourceTree = ""; }; - 8323CF011F6FBD870071420B /* NativeExpressComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeExpressComponent.m; sourceTree = ""; }; - 8323CF021F6FBD870071420B /* RNFirebaseAdMobBannerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobBannerManager.h; sourceTree = ""; }; - 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobBannerManager.m; sourceTree = ""; }; - 8323CF041F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobNativeExpressManager.h; sourceTree = ""; }; - 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobNativeExpressManager.m; sourceTree = ""; }; - 833693111FD824EF00AA806B /* RNFirebaseCrashlytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseCrashlytics.h; path = RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h; sourceTree = SOURCE_ROOT; }; - 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseCrashlytics.m; path = RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m; sourceTree = SOURCE_ROOT; }; - 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreDocumentReference.m; sourceTree = ""; }; - 8376F70F1F7C149000D45A85 /* RNFirebaseFirestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestore.h; sourceTree = ""; }; - 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestore.m; sourceTree = ""; }; - 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreCollectionReference.m; sourceTree = ""; }; - 8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreDocumentReference.h; sourceTree = ""; }; - 8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreCollectionReference.h; sourceTree = ""; }; - 838E36FC201B9169004DCD3A /* RNFirebaseMessaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseMessaging.h; sourceTree = ""; }; - 838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseMessaging.m; sourceTree = ""; }; - 838E372120231DF0004DCD3A /* RNFirebaseInstanceId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseInstanceId.h; sourceTree = ""; }; - 838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseInstanceId.m; sourceTree = ""; }; - 838E372520231E15004DCD3A /* RNFirebaseNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseNotifications.m; sourceTree = ""; }; - 838E372620231E15004DCD3A /* RNFirebaseNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseNotifications.h; sourceTree = ""; }; - 839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMob.h; sourceTree = ""; }; - 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMob.m; sourceTree = ""; }; - 839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = ""; }; - 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobInterstitial.m; sourceTree = ""; }; - 839D91521EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobRewardedVideo.h; sourceTree = ""; }; - 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobRewardedVideo.m; sourceTree = ""; }; - 839D91551EF3E20A0077C7C8 /* RNFirebaseAnalytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAnalytics.h; sourceTree = ""; }; - 839D91561EF3E20A0077C7C8 /* RNFirebaseAnalytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAnalytics.m; sourceTree = ""; }; - 839D91581EF3E20A0077C7C8 /* RNFirebaseAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAuth.h; sourceTree = ""; }; - 839D91591EF3E20A0077C7C8 /* RNFirebaseAuth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAuth.m; sourceTree = ""; }; - 839D915B1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseRemoteConfig.h; sourceTree = ""; }; - 839D915C1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseRemoteConfig.m; sourceTree = ""; }; - 839D91611EF3E20A0077C7C8 /* RNFirebaseDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseDatabase.h; sourceTree = ""; }; - 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseDatabase.m; sourceTree = ""; }; - 839D91671EF3E20A0077C7C8 /* RNFirebasePerformance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebasePerformance.h; sourceTree = ""; }; - 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebasePerformance.m; sourceTree = ""; }; - 839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseEvents.h; path = RNFirebase/RNFirebaseEvents.h; sourceTree = ""; }; - 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseInvites.m; sourceTree = ""; }; - 83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseInvites.h; sourceTree = ""; }; - 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseUtil.m; path = RNFirebase/RNFirebaseUtil.m; sourceTree = ""; }; - 83C3EEED1FA1EACC00B64D3C /* RNFirebaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseUtil.h; path = RNFirebase/RNFirebaseUtil.h; sourceTree = ""; }; - BA84AE551FA9E59800E79390 /* RNFirebaseStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseStorage.h; sourceTree = ""; }; - BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseStorage.m; sourceTree = ""; }; - D950369C1D19C77400F7094D /* RNFirebase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebase.h; path = RNFirebase/RNFirebase.h; sourceTree = ""; }; - D950369D1D19C77400F7094D /* RNFirebase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebase.m; path = RNFirebase/RNFirebase.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 58B511D81A9E6C8500147676 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 134814211AA4EA7D00B7C361 /* Products */ = { - isa = PBXGroup; - children = ( - 134814201AA4EA6300B7C361 /* libRNFirebase.a */, - ); - name = Products; - sourceTree = ""; - }; - 168785A0210B50AA00E4BD57 /* converters */ = { - isa = PBXGroup; - children = ( - 168785AC210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.h */, - 168785AB210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.m */, - ); - name = converters; - path = RNFirebase/converters; - sourceTree = ""; - }; - 17AF4F681F59CDBF00C02336 /* links */ = { - isa = PBXGroup; - children = ( - 17AF4F691F59CDBF00C02336 /* RNFirebaseLinks.h */, - 17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */, - ); - name = links; - path = RNFirebase/links; - sourceTree = ""; - }; - 27540F97209F35DF001F4AF4 /* functions */ = { - isa = PBXGroup; - children = ( - 27540F98209F361B001F4AF4 /* RNFirebaseFunctions.h */, - 27540F99209F3641001F4AF4 /* RNFirebaseFunctions.m */, - ); - name = functions; - path = RNFirebase/functions; - sourceTree = ""; - }; - 58B511D21A9E6C8500147676 = { - isa = PBXGroup; - children = ( - 168785A0210B50AA00E4BD57 /* converters */, - 27540F97209F35DF001F4AF4 /* functions */, - 83AAA0762063DEC2007EC5F7 /* invites */, - 838E372420231E15004DCD3A /* notifications */, - 838E372020231DF0004DCD3A /* instanceid */, - 8336930F1FD80DE800AA806B /* fabric */, - BA84AE541FA9E59800E79390 /* storage */, - 17AF4F681F59CDBF00C02336 /* links */, - 839D914D1EF3E20A0077C7C8 /* admob */, - 839D91541EF3E20A0077C7C8 /* analytics */, - 839D91571EF3E20A0077C7C8 /* auth */, - 839D915A1EF3E20A0077C7C8 /* config */, - 839D91601EF3E20A0077C7C8 /* database */, - 8376F70D1F7C141500D45A85 /* firestore */, - 839D91631EF3E20A0077C7C8 /* messaging */, - 839D91661EF3E20A0077C7C8 /* perf */, - D950369C1D19C77400F7094D /* RNFirebase.h */, - D950369D1D19C77400F7094D /* RNFirebase.m */, - 839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */, - 83C3EEED1FA1EACC00B64D3C /* RNFirebaseUtil.h */, - 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */, - 134814211AA4EA7D00B7C361 /* Products */, - ); - sourceTree = ""; - }; - 8336930F1FD80DE800AA806B /* fabric */ = { - isa = PBXGroup; - children = ( - 833693101FD80DF500AA806B /* crashlytics */, - ); - path = fabric; - sourceTree = ""; - }; - 833693101FD80DF500AA806B /* crashlytics */ = { - isa = PBXGroup; - children = ( - 833693111FD824EF00AA806B /* RNFirebaseCrashlytics.h */, - 833693121FD824EF00AA806B /* RNFirebaseCrashlytics.m */, - ); - path = crashlytics; - sourceTree = ""; - }; - 8376F70D1F7C141500D45A85 /* firestore */ = { - isa = PBXGroup; - children = ( - 8376F70F1F7C149000D45A85 /* RNFirebaseFirestore.h */, - 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */, - 8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */, - 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */, - 8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */, - 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */, - ); - name = firestore; - path = RNFirebase/firestore; - sourceTree = ""; - }; - 838E372020231DF0004DCD3A /* instanceid */ = { - isa = PBXGroup; - children = ( - 838E372120231DF0004DCD3A /* RNFirebaseInstanceId.h */, - 838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */, - ); - name = instanceid; - path = RNFirebase/instanceid; - sourceTree = ""; - }; - 838E372420231E15004DCD3A /* notifications */ = { - isa = PBXGroup; - children = ( - 838E372520231E15004DCD3A /* RNFirebaseNotifications.m */, - 838E372620231E15004DCD3A /* RNFirebaseNotifications.h */, - ); - name = notifications; - path = RNFirebase/notifications; - sourceTree = ""; - }; - 839D914D1EF3E20A0077C7C8 /* admob */ = { - isa = PBXGroup; - children = ( - 8323CEFE1F6FBD870071420B /* BannerComponent.h */, - 8323CEFF1F6FBD870071420B /* BannerComponent.m */, - 8323CF001F6FBD870071420B /* NativeExpressComponent.h */, - 8323CF011F6FBD870071420B /* NativeExpressComponent.m */, - 8323CF021F6FBD870071420B /* RNFirebaseAdMobBannerManager.h */, - 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */, - 8323CF041F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.h */, - 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */, - 839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */, - 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */, - 839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */, - 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */, - 839D91521EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.h */, - 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */, - ); - name = admob; - path = RNFirebase/admob; - sourceTree = ""; - }; - 839D91541EF3E20A0077C7C8 /* analytics */ = { - isa = PBXGroup; - children = ( - 839D91551EF3E20A0077C7C8 /* RNFirebaseAnalytics.h */, - 839D91561EF3E20A0077C7C8 /* RNFirebaseAnalytics.m */, - ); - name = analytics; - path = RNFirebase/analytics; - sourceTree = ""; - }; - 839D91571EF3E20A0077C7C8 /* auth */ = { - isa = PBXGroup; - children = ( - 839D91581EF3E20A0077C7C8 /* RNFirebaseAuth.h */, - 839D91591EF3E20A0077C7C8 /* RNFirebaseAuth.m */, - ); - name = auth; - path = RNFirebase/auth; - sourceTree = ""; - }; - 839D915A1EF3E20A0077C7C8 /* config */ = { - isa = PBXGroup; - children = ( - 839D915B1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.h */, - 839D915C1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.m */, - ); - name = config; - path = RNFirebase/config; - sourceTree = ""; - }; - 839D91601EF3E20A0077C7C8 /* database */ = { - isa = PBXGroup; - children = ( - 8300A7AC1F31E143001B16AB /* RNFirebaseDatabaseReference.h */, - 8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */, - 839D91611EF3E20A0077C7C8 /* RNFirebaseDatabase.h */, - 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */, - ); - name = database; - path = RNFirebase/database; - sourceTree = ""; - }; - 839D91631EF3E20A0077C7C8 /* messaging */ = { - isa = PBXGroup; - children = ( - 838E36FC201B9169004DCD3A /* RNFirebaseMessaging.h */, - 838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */, - ); - name = messaging; - path = RNFirebase/messaging; - sourceTree = ""; - }; - 839D91661EF3E20A0077C7C8 /* perf */ = { - isa = PBXGroup; - children = ( - 839D91671EF3E20A0077C7C8 /* RNFirebasePerformance.h */, - 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */, - ); - name = perf; - path = RNFirebase/perf; - sourceTree = ""; - }; - 83AAA0762063DEC2007EC5F7 /* invites */ = { - isa = PBXGroup; - children = ( - 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */, - 83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */, - ); - name = invites; - path = RNFirebase/invites; - sourceTree = ""; - }; - BA84AE541FA9E59800E79390 /* storage */ = { - isa = PBXGroup; - children = ( - BA84AE551FA9E59800E79390 /* RNFirebaseStorage.h */, - BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */, - ); - name = storage; - path = RNFirebase/storage; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 58B511DA1A9E6C8500147676 /* RNFirebase */ = { - isa = PBXNativeTarget; - buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNFirebase" */; - buildPhases = ( - 58B511D71A9E6C8500147676 /* Sources */, - 58B511D81A9E6C8500147676 /* Frameworks */, - 58B511D91A9E6C8500147676 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RNFirebase; - productName = RCTDataManager; - productReference = 134814201AA4EA6300B7C361 /* libRNFirebase.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 58B511D31A9E6C8500147676 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1000; - ORGANIZATIONNAME = Invertase; - TargetAttributes = { - 58B511DA1A9E6C8500147676 = { - CreatedOnToolsVersion = 6.1.1; - }; - }; - }; - buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNFirebase" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 58B511D21A9E6C8500147676; - productRefGroup = 58B511D21A9E6C8500147676; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 58B511DA1A9E6C8500147676 /* RNFirebase */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 58B511D71A9E6C8500147676 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 27540F9A209F3641001F4AF4 /* RNFirebaseFunctions.m in Sources */, - 838E372320231DF0004DCD3A /* RNFirebaseInstanceId.m in Sources */, - 839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */, - 168785AD210B584E00E4BD57 /* RCTConvert+UIBackgroundFetchResult.m in Sources */, - 839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */, - 17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */, - 8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */, - 838E36FE201B9169004DCD3A /* RNFirebaseMessaging.m in Sources */, - 8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */, - 839D91701EF3E20B0077C7C8 /* RNFirebaseAuth.m in Sources */, - 8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */, - 8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */, - 839D916F1EF3E20B0077C7C8 /* RNFirebaseAnalytics.m in Sources */, - 839D91711EF3E20B0077C7C8 /* RNFirebaseRemoteConfig.m in Sources */, - 833693131FD824EF00AA806B /* RNFirebaseCrashlytics.m in Sources */, - D950369E1D19C77400F7094D /* RNFirebase.m in Sources */, - 839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */, - 838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */, - BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */, - 83AAA0792063DEC2007EC5F7 /* RNFirebaseInvites.m in Sources */, - 8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */, - 83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */, - 839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */, - 8323CF061F6FBD870071420B /* BannerComponent.m in Sources */, - 839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */, - 8323CF081F6FBD870071420B /* RNFirebaseAdMobBannerManager.m in Sources */, - 8300A7AE1F31E143001B16AB /* RNFirebaseDatabaseReference.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 58B511ED1A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_BITCODE = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 58B511EE1A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_BITCODE = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 58B511F01A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - DEFINES_MODULE = NO; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "${BUILT_PRODUCTS_DIR}/**", - "${SRCROOT}/../../../ios/Firebase/**", - "$(SRCROOT)/../../../ios/Pods/Crashlytics/iOS", - "$(SRCROOT)/../../../ios/Pods/Fabric/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseAnalytics/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseAuth/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseCore/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseDatabase/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseDynamicLinks/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseFirestore/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseFunctions/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseInstanceID/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseInvites/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseMessaging/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebasePerformance/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseRemoteConfig/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseStorage/Frameworks", - "$(SRCROOT)/../../../ios/Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../../react-native/React/**", - "${SRCROOT}/../../../ios/Firebase/**", - "${SRCROOT}/../../../ios/Pods/Headers/Public/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACH_O_TYPE = staticlib; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "$(inherited)"; - PRODUCT_NAME = RNFirebase; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 58B511F11A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - DEFINES_MODULE = NO; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "${BUILT_PRODUCTS_DIR}/**", - "${SRCROOT}/../../../ios/Firebase/**", - "$(SRCROOT)/../../../ios/Pods/Crashlytics/iOS", - "$(SRCROOT)/../../../ios/Pods/Fabric/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseAnalytics/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseAuth/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseCore/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseDatabase/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseDynamicLinks/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseFirestore/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseFunctions/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseInstanceID/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseInvites/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseMessaging/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebasePerformance/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseRemoteConfig/Frameworks", - "$(SRCROOT)/../../../ios/Pods/FirebaseStorage/Frameworks", - "$(SRCROOT)/../../../ios/Pods/Google-Mobile-Ads-SDK/Frameworks/frameworks", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../../react-native/React/**", - "${SRCROOT}/../../../ios/Firebase/**", - "${SRCROOT}/../../../ios/Pods/Headers/Public/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACH_O_TYPE = staticlib; - OTHER_LDFLAGS = "$(inherited)"; - PRODUCT_NAME = RNFirebase; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNFirebase" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511ED1A9E6C8500147676 /* Debug */, - 58B511EE1A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNFirebase" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511F01A9E6C8500147676 /* Debug */, - 58B511F11A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 58B511D31A9E6C8500147676 /* Project object */; -} diff --git a/ios/RNFirebase/RNFirebase.h b/ios/RNFirebase/RNFirebase.h deleted file mode 100644 index 58d7ed42..00000000 --- a/ios/RNFirebase/RNFirebase.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef RNFirebase_h -#define RNFirebase_h -#import - -#import -#import - -@interface RNFirebase : RCTEventEmitter { -} - -@end - -#endif diff --git a/ios/RNFirebase/RNFirebase.m b/ios/RNFirebase/RNFirebase.m deleted file mode 100644 index af9898e1..00000000 --- a/ios/RNFirebase/RNFirebase.m +++ /dev/null @@ -1,122 +0,0 @@ -#import "RNFirebase.h" -#import "RNFirebaseUtil.h" -#import -#import - -@implementation RNFirebase -RCT_EXPORT_MODULE(RNFirebase); - -- (id)init { - self = [super init]; - if (self != nil) { - DLog(@"Setting up RNFirebase instance"); - } - return self; -} - -- (NSArray *)supportedEvents { - return @[]; -} - -/** - * Initialize a new firebase app instance or ignore if currently exists. - * @return - */ -RCT_EXPORT_METHOD(initializeApp: - (NSString *) appDisplayName - options: - (NSDictionary *) options - callback: - (RCTResponseSenderBlock) callback) { - - RCTUnsafeExecuteOnMainQueueSync(^{ - FIRApp *existingApp = [RNFirebaseUtil getApp:appDisplayName]; - - if (!existingApp) { - FIROptions *firOptions = [[FIROptions alloc] initWithGoogleAppID:[options valueForKey:@"appId"] GCMSenderID:[options valueForKey:@"messagingSenderId"]]; - - firOptions.APIKey = [options valueForKey:@"apiKey"]; - firOptions.projectID = [options valueForKey:@"projectId"]; - firOptions.clientID = [options valueForKey:@"clientId"]; - firOptions.trackingID = [options valueForKey:@"trackingId"]; - firOptions.databaseURL = [options valueForKey:@"databaseURL"]; - firOptions.storageBucket = [options valueForKey:@"storageBucket"]; - firOptions.androidClientID = [options valueForKey:@"androidClientId"]; - firOptions.deepLinkURLScheme = [options valueForKey:@"deepLinkURLScheme"]; - firOptions.bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; - - NSString *appName = [RNFirebaseUtil getAppName:appDisplayName]; - [FIRApp configureWithName:appName options:firOptions]; - } - - callback(@[[NSNull null], @{@"result": @"success"}]); - }); -} - -/** - * Delete a firebase app - * @return - */ -RCT_EXPORT_METHOD(deleteApp: - (NSString *) appDisplayName - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - - FIRApp *existingApp = [RNFirebaseUtil getApp:appDisplayName]; - - if (!existingApp) { - return resolve([NSNull null]); - } - - [existingApp deleteApp:^(BOOL success) { - if (success) { - resolve([NSNull null]); - } else { - reject(@"app/delete-app-failed", @"Failed to delete the specified app.", nil); - } - }]; - -} - -/** - * React native constant exports - exports native firebase apps mainly - * @return NSDictionary - */ -- (NSDictionary *)constantsToExport { - NSMutableDictionary *constants = [NSMutableDictionary new]; - NSDictionary *firApps = [FIRApp allApps]; - NSMutableArray *appsArray = [NSMutableArray new]; - - for (id key in firApps) { - NSMutableDictionary *appOptions = [NSMutableDictionary new]; - FIRApp *firApp = firApps[key]; - FIROptions *firOptions = [firApp options]; - appOptions[@"name"] = [RNFirebaseUtil getAppDisplayName:firApp.name]; - appOptions[@"apiKey"] = firOptions.APIKey; - appOptions[@"appId"] = firOptions.googleAppID; - appOptions[@"databaseURL"] = firOptions.databaseURL; - appOptions[@"messagingSenderId"] = firOptions.GCMSenderID; - appOptions[@"projectId"] = firOptions.projectID; - appOptions[@"storageBucket"] = firOptions.storageBucket; - - // missing from android sdk / ios only: - appOptions[@"clientId"] = firOptions.clientID; - appOptions[@"trackingId"] = firOptions.trackingID; - appOptions[@"androidClientID"] = firOptions.androidClientID; - appOptions[@"deepLinkUrlScheme"] = firOptions.deepLinkURLScheme; - - [appsArray addObject:appOptions]; - } - - constants[@"apps"] = appsArray; - return constants; -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end diff --git a/ios/RNFirebase/RNFirebaseEvents.h b/ios/RNFirebase/RNFirebaseEvents.h deleted file mode 100644 index ef8b7c79..00000000 --- a/ios/RNFirebase/RNFirebaseEvents.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef RNFirebaseEvents_h -#define RNFirebaseEvents_h - -#import - -static NSString *const AUTH_STATE_CHANGED_EVENT = @"auth_state_changed"; -static NSString *const AUTH_ID_TOKEN_CHANGED_EVENT = @"auth_id_token_changed"; -static NSString *const PHONE_AUTH_STATE_CHANGED_EVENT = @"phone_auth_state_changed"; - -// Database -static NSString *const DATABASE_SYNC_EVENT = @"database_sync_event"; -static NSString *const DATABASE_TRANSACTION_EVENT = @"database_transaction_event"; - -static NSString *const DATABASE_VALUE_EVENT = @"value"; -static NSString *const DATABASE_CHILD_ADDED_EVENT = @"child_added"; -static NSString *const DATABASE_CHILD_MODIFIED_EVENT = @"child_changed"; -static NSString *const DATABASE_CHILD_REMOVED_EVENT = @"child_removed"; -static NSString *const DATABASE_CHILD_MOVED_EVENT = @"child_moved"; - -// Firestore -static NSString *const FIRESTORE_TRANSACTION_EVENT = @"firestore_transaction_event"; -static NSString *const FIRESTORE_COLLECTION_SYNC_EVENT = @"firestore_collection_sync_event"; -static NSString *const FIRESTORE_DOCUMENT_SYNC_EVENT = @"firestore_document_sync_event"; - -// Storage -static NSString *const STORAGE_EVENT = @"storage_event"; -static NSString *const STORAGE_ERROR = @"storage_error"; - -static NSString *const STORAGE_STATE_CHANGED = @"state_changed"; -static NSString *const STORAGE_UPLOAD_SUCCESS = @"upload_success"; -static NSString *const STORAGE_UPLOAD_FAILURE = @"upload_failure"; -static NSString *const STORAGE_DOWNLOAD_SUCCESS = @"download_success"; -static NSString *const STORAGE_DOWNLOAD_FAILURE = @"download_failure"; - -// Messaging -static NSString *const MESSAGING_MESSAGE_RECEIVED = @"messaging_message_received"; -static NSString *const MESSAGING_TOKEN_REFRESHED = @"messaging_token_refreshed"; - -// Notifications -static NSString *const NOTIFICATIONS_NOTIFICATION_DISPLAYED = @"notifications_notification_displayed"; -static NSString *const NOTIFICATIONS_NOTIFICATION_OPENED = @"notifications_notification_opened"; -static NSString *const NOTIFICATIONS_NOTIFICATION_RECEIVED = @"notifications_notification_received"; - -// AdMob -static NSString *const ADMOB_INTERSTITIAL_EVENT = @"interstitial_event"; -static NSString *const ADMOB_REWARDED_VIDEO_EVENT = @"rewarded_video_event"; - -// Links -static NSString *const LINKS_LINK_RECEIVED = @"links_link_received"; - -// Invites -static NSString *const INVITES_INVITATION_RECEIVED = @"invites_invitation_received"; - -#endif diff --git a/ios/RNFirebase/RNFirebaseUtil.h b/ios/RNFirebase/RNFirebaseUtil.h deleted file mode 100644 index bbc1636c..00000000 --- a/ios/RNFirebase/RNFirebaseUtil.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef RNFirebaseUtil_h -#define RNFirebaseUtil_h - -#import -#import -#import - -#ifdef DEBUG -#define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); -#else -#define DLog(...) -#endif - -@interface RNFirebaseUtil : NSObject - -+ (NSString *)getISO8601String:(NSDate *)date; -+ (FIRApp *)getApp:(NSString *)appDisplayName; -+ (NSString *)getAppName:(NSString *)appDisplayName; -+ (NSString *)getAppDisplayName:(NSString *)appName; -+ (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body; -+ (void)sendJSEventWithAppName:(RCTEventEmitter *)emitter app:(FIRApp *)app name:(NSString *)name body:(id)body; - -@end - -#endif diff --git a/ios/RNFirebase/RNFirebaseUtil.m b/ios/RNFirebase/RNFirebaseUtil.m deleted file mode 100644 index d0964b1a..00000000 --- a/ios/RNFirebase/RNFirebaseUtil.m +++ /dev/null @@ -1,62 +0,0 @@ -#import "RNFirebaseUtil.h" - -@implementation RNFirebaseUtil - -static NSString *const DEFAULT_APP_DISPLAY_NAME = @"[DEFAULT]"; -static NSString *const DEFAULT_APP_NAME = @"__FIRAPP_DEFAULT"; - -+ (NSString *)getISO8601String:(NSDate *)date { - static NSDateFormatter *formatter = nil; - - if (!formatter) { - formatter = [[NSDateFormatter alloc] init]; - [formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; - formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; - [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; - } - - NSString *iso8601String = [formatter stringFromDate:date]; - - return [iso8601String stringByAppendingString:@"Z"]; -} - -+ (FIRApp *)getApp:(NSString *)appDisplayName { - NSString *appName = [RNFirebaseUtil getAppName:appDisplayName]; - return [FIRApp appNamed:appName]; -} - -+ (NSString *)getAppName:(NSString *)appDisplayName { - if ([appDisplayName isEqualToString:DEFAULT_APP_DISPLAY_NAME]) { - return DEFAULT_APP_NAME; - } - return appDisplayName; -} - -+ (NSString *)getAppDisplayName:(NSString *)appName { - if ([appName isEqualToString:DEFAULT_APP_NAME]) { - return DEFAULT_APP_DISPLAY_NAME; - } - return appName; -} - -+ (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { - @try { - // TODO: Temporary fix for https://github.com/invertase/react-native-firebase/issues/233 - // until a better solution comes around - if (emitter.bridge) { - [emitter sendEventWithName:name body:body]; - } - } @catch (NSException *error) { - DLog(@"An error occurred in sendJSEvent: %@", [error debugDescription]); - } -} - -+ (void)sendJSEventWithAppName:(RCTEventEmitter *)emitter app:(FIRApp *)app name:(NSString *)name body:(id)body { - // Add the appName to the body - NSMutableDictionary *newBody = [body mutableCopy]; - newBody[@"appName"] = [RNFirebaseUtil getAppDisplayName:app.name]; - - [RNFirebaseUtil sendJSEvent:emitter name:name body:newBody]; -} - -@end diff --git a/ios/RNFirebase/admob/BannerComponent.h b/ios/RNFirebase/admob/BannerComponent.h deleted file mode 100644 index 378002fa..00000000 --- a/ios/RNFirebase/admob/BannerComponent.h +++ /dev/null @@ -1,29 +0,0 @@ -#import -#import - -#if __has_include() - -#import -#import - -@interface BannerComponent : UIView - -@property GADBannerView *banner; -@property (nonatomic, assign) BOOL requested; - -@property (nonatomic, copy) NSString *size; -@property (nonatomic, copy) NSString *unitId; -@property (nonatomic, copy) NSDictionary *request; - -@property (nonatomic, copy) RCTBubblingEventBlock onBannerEvent; - -- (void)requestAd; - -@end -#else - -@interface BannerComponent : NSObject { -} -@end - -#endif diff --git a/ios/RNFirebase/admob/BannerComponent.m b/ios/RNFirebase/admob/BannerComponent.m deleted file mode 100644 index b51c028e..00000000 --- a/ios/RNFirebase/admob/BannerComponent.m +++ /dev/null @@ -1,93 +0,0 @@ -#import "BannerComponent.h" -#import "RNFirebaseAdMob.h" -#import - -@implementation BannerComponent - -#if __has_include() - -- (void)initBanner:(GADAdSize)adSize { - if (_requested) { - [_banner removeFromSuperview]; - } - _banner = [[GADBannerView alloc] initWithAdSize:adSize]; - _banner.rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController; - _banner.delegate = self; -} - -- (void)setUnitId:(NSString *)unitId { - _unitId = unitId; - [self requestAd]; -} - -- (void)setSize:(NSString *)size { - _size = size; - [self requestAd]; -} - -- (void)setRequest:(NSDictionary *)request { - _request = request; - [self requestAd]; -} - -- (void)requestAd { - #ifndef __LP64__ - return; // prevent crash on 32bit - #endif - - if (_unitId == nil || _size == nil || _request == nil) { - [self setRequested:NO]; - return; - } - - [self initBanner:[RNFirebaseAdMob stringToAdSize:_size]]; - [self addSubview:_banner]; - - [self sendEvent:@"onSizeChange" payload:@{ - @"width": @(_banner.bounds.size.width), - @"height": @(_banner.bounds.size.height), - }]; - - _banner.adUnitID = _unitId; - [self setRequested:YES]; - [_banner loadRequest:[RNFirebaseAdMob buildRequest:_request]]; -} - -- (void)sendEvent:(NSString *)type payload:(NSDictionary *_Nullable)payload { - self.onBannerEvent(@{ - @"type": type, - @"payload": payload != nil ? payload : [NSNull null], - }); -} - -- (void)adViewDidReceiveAd:(GADBannerView *)adView { - [self sendEvent:@"onAdLoaded" payload:@{ - @"width": @(adView.bounds.size.width), - @"height": @(adView.bounds.size.height), - @"hasVideoContent": @NO, - }]; -} - -- (void)adView:(GADBannerView *)adView didFailToReceiveAdWithError:(GADRequestError *)error { - [self sendEvent:@"onAdFailedToLoad" payload:[RNFirebaseAdMob errorCodeToDictionary:error]]; -} - -- (void)adViewWillPresentScreen:(GADBannerView *)adView { - [self sendEvent:@"onAdOpened" payload:nil]; -} - -- (void)adViewWillDismissScreen:(GADBannerView *)adView { - // not in use -} - -- (void)adViewDidDismissScreen:(GADBannerView *)adView { - [self sendEvent:@"onAdClosed" payload:nil]; -} - -- (void)adViewWillLeaveApplication:(GADBannerView *)adView { - [self sendEvent:@"onAdLeftApplication" payload:nil]; -} - -#endif - -@end diff --git a/ios/RNFirebase/admob/NativeExpressComponent.h b/ios/RNFirebase/admob/NativeExpressComponent.h deleted file mode 100644 index 2e9a9ccd..00000000 --- a/ios/RNFirebase/admob/NativeExpressComponent.h +++ /dev/null @@ -1,29 +0,0 @@ -#import -#import - -#if __has_include() - -#import -#import - -@interface NativeExpressComponent : UIView - -@property GADNativeExpressAdView *banner; -@property (nonatomic, assign) BOOL requested; - -@property (nonatomic, copy) NSString *size; -@property (nonatomic, copy) NSString *unitId; -@property (nonatomic, copy) NSDictionary *request; -@property (nonatomic, copy) NSDictionary *video; - -@property (nonatomic, copy) RCTBubblingEventBlock onBannerEvent; - -- (void)requestAd; - -@end -#else - -@interface NativeExpressComponent : NSObject -@end - -#endif diff --git a/ios/RNFirebase/admob/NativeExpressComponent.m b/ios/RNFirebase/admob/NativeExpressComponent.m deleted file mode 100644 index f5dfd91a..00000000 --- a/ios/RNFirebase/admob/NativeExpressComponent.m +++ /dev/null @@ -1,122 +0,0 @@ -#import "NativeExpressComponent.h" -#import "RNFirebaseAdMob.h" -#import - -@implementation NativeExpressComponent - -#if __has_include() - -- (void)initBanner:(GADAdSize)adSize { - if (_requested) { - [_banner removeFromSuperview]; - } - _banner = [[GADNativeExpressAdView alloc] initWithAdSize:adSize]; - _banner.rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController; - _banner.delegate = self; - _banner.videoController.delegate = self; -} - -- (void)setUnitId:(NSString *)unitId { - _unitId = unitId; - [self requestAd]; -} - -- (void)setSize:(NSString *)size { - _size = size; - [self requestAd]; -} - -- (void)setRequest:(NSDictionary *)request { - _request = request; - [self requestAd]; -} - -- (void)setVideo:(NSDictionary *)video { - _video = video; - [self requestAd]; -} - -- (void)requestAd { - if (_unitId == nil || _size == nil || _request == nil || _video == nil) { - [self setRequested:NO]; - return; - } - - [self initBanner:[RNFirebaseAdMob stringToAdSize:_size]]; - [self addSubview:_banner]; - - [self sendEvent:@"onSizeChange" payload:@{ - @"width": @(_banner.bounds.size.width), - @"height": @(_banner.bounds.size.height), - }]; - - _banner.adUnitID = _unitId; - [self setRequested:YES]; - [_banner setAdOptions:@[[RNFirebaseAdMob buildVideoOptions:_video]]]; - [_banner loadRequest:[RNFirebaseAdMob buildRequest:_request]]; -} - -- (void)sendEvent:(NSString *)type payload:(NSDictionary *_Nullable)payload { - self.onBannerEvent(@{ - @"type": type, - @"payload": payload != nil ? payload : [NSNull null], - }); -} - -- (void)nativeExpressAdViewDidReceiveAd:(GADNativeExpressAdView *)adView { - [self sendEvent:@"onAdLoaded" payload:@{ - @"width": @(adView.bounds.size.width), - @"height": @(adView.bounds.size.height), - @"hasVideoContent": @(adView.videoController.hasVideoContent), - }]; -} - -- (void)nativeExpressAdView:(nonnull GADNativeExpressAdView *)nativeExpressAdView didFailToReceiveAdWithError:(nonnull GADRequestError *)error { - [self sendEvent:@"onAdFailedToLoad" payload:[RNFirebaseAdMob errorCodeToDictionary:error]]; -} - -- (void)nativeExpressAdViewWillPresentScreen:(GADNativeExpressAdView *)adView { - [self sendEvent:@"onAdOpened" payload:nil]; -} - -- (void)nativeExpressAdViewWillDismissScreen:(GADNativeExpressAdView *)adView { - // not in use -} - -- (void)nativeExpressAdViewDidDismissScreen:(GADNativeExpressAdView *)adView { - [self sendEvent:@"onAdClosed" payload:nil]; -} - -- (void)nativeExpressAdViewWillLeaveApplication:(GADNativeExpressAdView *)adView { - [self sendEvent:@"onAdLeftApplication" payload:nil]; -} - -- (void)videoControllerDidEndVideoPlayback:(nonnull GADVideoController *)videoController { - [self sendEvent:@"onVideoEnd" payload:nil]; -} - -// Only one video play method? -- (void)videoControllerDidPlayVideo:(nonnull GADVideoController *)videoController { - [self sendEvent:@"onVideoStart" payload:nil]; - [self sendEvent:@"onVideoPlay" payload:nil]; -} - -- (void)videoControllerDidPauseVideo:(nonnull GADVideoController *)videoController { - [self sendEvent:@"onVideoPause" payload:nil]; -} - -- (void)videoControllerDidMuteVideo:(nonnull GADVideoController *)videoController { - [self sendEvent:@"onVideoMute" payload:@{ - @"isMuted": @YES, - }]; -} - -- (void)videoControllerDidUnmuteVideo:(nonnull GADVideoController *)videoController { - [self sendEvent:@"onVideoMute" payload:@{ - @"isMuted": @NO, - }]; -} - -#endif - -@end diff --git a/ios/RNFirebase/admob/RNFirebaseAdMob.h b/ios/RNFirebase/admob/RNFirebaseAdMob.h deleted file mode 100644 index ee7e8f0d..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMob.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef RNFirebaseAdMob_h -#define RNFirebaseAdMob_h -#import - -#if __has_include() -#import -#import "RNFirebaseEvents.h" -#import -#import -#import -#import - - -@interface RNFirebaseAdMob : RCTEventEmitter -@property NSMutableDictionary *interstitials; -@property NSMutableDictionary *rewardedVideos; - -+ (GADRequest *)buildRequest:(NSDictionary *)request; -+ (GADVideoOptions *)buildVideoOptions:(NSDictionary *)options; -+ (NSDictionary *)errorCodeToDictionary:(NSError *)error; -+ (GADAdSize)stringToAdSize:(NSString *)value; -@end - -#else -@interface RNFirebaseAdMob : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/admob/RNFirebaseAdMob.m b/ios/RNFirebase/admob/RNFirebaseAdMob.m deleted file mode 100644 index dbee154c..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMob.m +++ /dev/null @@ -1,232 +0,0 @@ -#import "RNFirebaseAdMob.h" - -#if __has_include() - -#import "RNFirebaseAdMobInterstitial.h" -#import "RNFirebaseAdMobRewardedVideo.h" - -NSString *MALE = @"male"; -NSString *FEMALE = @"female"; -NSString *UNKNOWN = @"unknown"; - -@implementation RNFirebaseAdMob -RCT_EXPORT_MODULE(); - -- (id)init { - self = [super init]; - if (self != nil) { - _interstitials = [[NSMutableDictionary alloc] init]; - _rewardedVideos = [[NSMutableDictionary alloc] init]; - } - return self; -} - -- (dispatch_queue_t)methodQueue { - return dispatch_get_main_queue(); -} - -RCT_EXPORT_METHOD(initialize: - (NSString *) appId) { - [GADMobileAds configureWithApplicationID:appId]; -} - -RCT_EXPORT_METHOD(openDebugMenu: - (NSString *) appId) { - GADDebugOptionsViewController *debugOptionsViewController = [GADDebugOptionsViewController debugOptionsViewControllerWithAdUnitID:appId]; - UIWindow *window = [UIApplication sharedApplication].keyWindow; - - [[window rootViewController] presentViewController:debugOptionsViewController animated:YES completion:nil]; -} - -RCT_EXPORT_METHOD(interstitialLoadAd: - (NSString *) adUnit - request: - (NSDictionary *) request) { - RNFirebaseAdMobInterstitial *interstitial = [self getOrCreateInterstitial:adUnit]; - [interstitial loadAd:request]; -} - -RCT_EXPORT_METHOD(interstitialShowAd: - (NSString *) adUnit) { - RNFirebaseAdMobInterstitial *interstitial = [self getOrCreateInterstitial:adUnit]; - [interstitial show]; -} - -RCT_EXPORT_METHOD(rewardedVideoLoadAd: - (NSString *) adUnit - request: - (NSDictionary *) request) { - RNFirebaseAdMobRewardedVideo *rewardedVideo = [self getOrCreateRewardedVideo:adUnit]; - [rewardedVideo loadAd:request]; -} - -RCT_EXPORT_METHOD(rewardedVideoShowAd: - (NSString *) adUnit) { - RNFirebaseAdMobRewardedVideo *rewardedVideo = [self getOrCreateRewardedVideo:adUnit]; - [rewardedVideo show]; -} - -RCT_EXPORT_METHOD(clearInterstitial: - (NSString *) adUnit) { - if (_interstitials[adUnit]) [_interstitials removeObjectForKey:adUnit]; -} - -- (RNFirebaseAdMobInterstitial *)getOrCreateInterstitial:(NSString *)adUnit { - if (_interstitials[adUnit]) { - return _interstitials[adUnit]; - } - - _interstitials[adUnit] = [[RNFirebaseAdMobInterstitial alloc] initWithProps:adUnit delegate:self]; - return _interstitials[adUnit]; -} - -- (RNFirebaseAdMobRewardedVideo *)getOrCreateRewardedVideo:(NSString *)adUnit { - if (_rewardedVideos[adUnit]) { - return _rewardedVideos[adUnit]; - } - - _rewardedVideos[adUnit] = [[RNFirebaseAdMobRewardedVideo alloc] initWithProps:adUnit delegate:self]; - return _rewardedVideos[adUnit]; -} - -- (NSArray *)supportedEvents { - return @[ADMOB_INTERSTITIAL_EVENT, ADMOB_REWARDED_VIDEO_EVENT]; -} - -+ (GADRequest *)buildRequest:(NSDictionary *)request { - GADRequest *builder = [GADRequest request]; - - if (request[@"tagForChildDirectedTreatment"]) [builder tagForChildDirectedTreatment:(BOOL) request[@"tagForChildDirectedTreatment"]]; - if (request[@"contentUrl"]) builder.contentURL = request[@"contentUrl"]; - if (request[@"requestAgent"]) builder.requestAgent = request[@"requestAgent"]; - if (request[@"keywords"]) builder.keywords = request[@"keywords"]; - - if (request[@"testDevices"]) { - NSArray *devices = request[@"testDevices"]; - NSMutableArray *testDevices = [[NSMutableArray alloc] init]; - - for (id device in devices) { - if ([device isEqual:@"DEVICE_ID_EMULATOR"]) { - [testDevices addObject:kGADSimulatorID]; - } else { - [testDevices addObject:device]; - } - } - - builder.testDevices = testDevices; - } - - if (request[@"gender"]) { - NSString *gender = [request[@"gender"] stringValue]; - - if (gender == MALE) { - builder.gender = kGADGenderMale; - } else if (gender == FEMALE) { - builder.gender = kGADGenderFemale; - } else if (gender == UNKNOWN) { - builder.gender = kGADGenderUnknown; - } - } - - return builder; -} - -+ (GADVideoOptions *)buildVideoOptions:(NSDictionary *)options { - GADVideoOptions *builder = [[GADVideoOptions alloc] init]; - builder.startMuted = (BOOL) options[@"startMuted"]; - return builder; -} - -+ (NSDictionary *)errorCodeToDictionary:(NSError *)error { - NSString *code; - NSString *message; - - switch (error.code) { - default: - case kGADErrorServerError: - case kGADErrorInternalError: - case kGADErrorInvalidArgument: - case kGADErrorMediationDataError: - case kGADErrorMediationAdapterError: - code = @"admob/error-code-internal-error "; - message = @"Something happened internally; for instance, an invalid response was received from the ad server."; - break; - case kGADErrorMediationInvalidAdSize: - code = @"admob/error-code-invalid-request"; - message = @"The ad requested has an invalid size."; - break; - case kGADErrorInvalidRequest: - case kGADErrorReceivedInvalidResponse: - code = @"admob/error-code-invalid-request"; - message = @"The ad request was invalid; for instance, the ad unit ID was incorrect."; - break; - case kGADErrorNoFill: - case kGADErrorMediationNoFill: - code = @"admob/error-code-no-fill"; - message = @"The ad request was successful, but no ad was returned due to lack of ad inventory."; - break; - case kGADErrorNetworkError: - code = @"admob/error-code-network-error"; - message = @"The ad request was unsuccessful due to network connectivity."; - break; - case kGADErrorOSVersionTooLow: - code = @"admob/os-version-too-low"; - message = @"The current device’s OS is below the minimum required version."; - break; - } - - return @{ - @"code": code, - @"message": message, - }; -} - -+ (GADAdSize)stringToAdSize:(NSString *)value { - NSError *error = nil; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)x([0-9]+)" options:0 error:&error]; - NSArray *matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])]; - - for (NSTextCheckingResult *match in matches) { - NSString *matchText = [value substringWithRange:[match range]]; - if (matchText) { - NSArray *values = [matchText componentsSeparatedByString:@"x"]; - CGFloat width = (CGFloat) [values[0] intValue]; - CGFloat height = (CGFloat) [values[1] intValue]; - return GADAdSizeFromCGSize(CGSizeMake(width, height)); - } - } - - value = [value uppercaseString]; - - if ([value isEqualToString:@"BANNER"]) { - return kGADAdSizeBanner; - } else if ([value isEqualToString:@"LARGE_BANNER"]) { - return kGADAdSizeLargeBanner; - } else if ([value isEqualToString:@"MEDIUM_RECTANGLE"]) { - return kGADAdSizeMediumRectangle; - } else if ([value isEqualToString:@"FULL_BANNER"]) { - return kGADAdSizeFullBanner; - } else if ([value isEqualToString:@"LEADERBOARD"]) { - return kGADAdSizeLeaderboard; - } else if ([value isEqualToString:@"SMART_BANNER"]) { - return kGADAdSizeSmartBannerPortrait; - } else if ([value isEqualToString:@"SMART_BANNER_LANDSCAPE"]) { - return kGADAdSizeSmartBannerLandscape; - } else { - return kGADAdSizeBanner; - } -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else - -@implementation RNFirebaseAdMob -@end - -#endif diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.h b/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.h deleted file mode 100644 index 9a826b33..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface RNFirebaseAdMobBannerManager : RCTViewManager - -@end \ No newline at end of file diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.m b/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.m deleted file mode 100644 index e295e090..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobBannerManager.m +++ /dev/null @@ -1,32 +0,0 @@ -#import "RNFirebaseAdMobBannerManager.h" -#import "BannerComponent.h" - -@implementation RNFirebaseAdMobBannerManager - -RCT_EXPORT_MODULE(); - -#if __has_include() - - -@synthesize bridge = _bridge; - -- (UIView *)view -{ - return [[BannerComponent alloc] init]; -} - -- (dispatch_queue_t)methodQueue -{ - return dispatch_get_main_queue(); -} - - -RCT_EXPORT_VIEW_PROPERTY(size, NSString); -RCT_EXPORT_VIEW_PROPERTY(unitId, NSString); -RCT_EXPORT_VIEW_PROPERTY(request, NSDictionary); - -RCT_EXPORT_VIEW_PROPERTY(onBannerEvent, RCTBubblingEventBlock); - -#endif - -@end \ No newline at end of file diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.h b/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.h deleted file mode 100644 index 66f01629..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RNFirebaseAdMobInterstitial_h -#define RNFirebaseAdMobInterstitial_h - -#import -#import "RNFirebaseEvents.h" - -#if __has_include() - -#import -#import -#import -#import "RNFirebaseAdMob.h" - -@interface RNFirebaseAdMobInterstitial : NSObject -@property NSString *adUnitID; -@property RNFirebaseAdMob *delegate; -@property GADInterstitial *interstitial; - -- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate; - -- (void)show; -- (void)loadAd:(NSDictionary *)request; -- (void)sendJSEvent:(NSString *)type payload:(nullable NSDictionary *)payload; - -@end - -#else -@interface RNFirebaseAdMobInterstitial : NSObject { -} -@end -#endif - -#endif diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.m b/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.m deleted file mode 100644 index 04a22400..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobInterstitial.m +++ /dev/null @@ -1,64 +0,0 @@ -#import "RNFirebaseAdMobInterstitial.h" -#import "RNFirebaseUtil.h" - -@implementation RNFirebaseAdMobInterstitial - -#if __has_include() - -- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate { - self = [super init]; - if (self) { - _adUnitID = adUnit; - _delegate = delegate; - _interstitial = [self createInterstitial]; - } - return self; -} - -- (GADInterstitial *)createInterstitial { - GADInterstitial *interstitial = [[GADInterstitial alloc] initWithAdUnitID:_adUnitID]; - interstitial.delegate = self; - return interstitial; -} - -- (void)loadAd:(NSDictionary *)request { - [_interstitial loadRequest:[RNFirebaseAdMob buildRequest:request]]; -} - -- (void)show { - if (_interstitial.isReady) { - [_interstitial presentFromRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController]; - } -} - -- (void)sendJSEvent:(NSString *)type payload:(NSDictionary *)payload { - [RNFirebaseUtil sendJSEvent:self.delegate name:ADMOB_INTERSTITIAL_EVENT body:@{ - @"type": type, - @"adUnit": _adUnitID, - @"payload": payload - }]; -} - -- (void)interstitialDidReceiveAd:(nonnull GADInterstitial *)ad { - [self sendJSEvent:@"onAdLoaded" payload:@{}]; -} - -- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error { - [self sendJSEvent:@"onAdFailedToLoad" payload:[RNFirebaseAdMob errorCodeToDictionary:error]]; -} - -- (void)interstitialWillPresentScreen:(GADInterstitial *)ad { - [self sendJSEvent:@"onAdOpened" payload:@{}]; -} - -- (void)interstitialDidDismissScreen:(GADInterstitial *)ad { - [self sendJSEvent:@"onAdClosed" payload:@{}]; -} - -- (void)interstitialWillLeaveApplication:(GADInterstitial *)ad { - [self sendJSEvent:@"onAdLeftApplication" payload:@{}]; -} - -#endif - -@end diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.h b/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.h deleted file mode 100644 index 90948041..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface RNFirebaseAdMobNativeExpressManager : RCTViewManager - -@end \ No newline at end of file diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m b/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m deleted file mode 100644 index d1f7ce4d..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m +++ /dev/null @@ -1,32 +0,0 @@ -#import "RNFirebaseAdMobNativeExpressManager.h" -#import "NativeExpressComponent.h" - -@implementation RNFirebaseAdMobNativeExpressManager - -RCT_EXPORT_MODULE(); - -#if __has_include() - -@synthesize bridge = _bridge; - -- (UIView *)view -{ - return [[NativeExpressComponent alloc] init]; -} - -- (dispatch_queue_t)methodQueue -{ - return dispatch_get_main_queue(); -} - - -RCT_EXPORT_VIEW_PROPERTY(size, NSString); -RCT_EXPORT_VIEW_PROPERTY(unitId, NSString); -RCT_EXPORT_VIEW_PROPERTY(request, NSDictionary); -RCT_EXPORT_VIEW_PROPERTY(video, NSDictionary); - -RCT_EXPORT_VIEW_PROPERTY(onBannerEvent, RCTBubblingEventBlock); - -#endif - -@end \ No newline at end of file diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.h b/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.h deleted file mode 100644 index 2e90f637..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RNFirebaseAdMobRewardedVideo_h -#define RNFirebaseAdMobRewardedVideo_h - -#import -#import "RNFirebaseEvents.h" - -#if __has_include() - -#import -#import -#import -#import "RNFirebaseAdMob.h" - -@interface RNFirebaseAdMobRewardedVideo : NSObject -@property NSString *adUnitID; -@property RNFirebaseAdMob *delegate; -@property GADRewardBasedVideoAd *videoAd; - -- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate; - -- (void)show; -- (void)loadAd:(NSDictionary *)request; -- (void)sendJSEvent:(NSString *)type payload:(nullable NSDictionary *)payload; - -@end - -#else -@interface RNFirebaseAdMobRewardedVideo : NSObject { -} -@end -#endif - -#endif diff --git a/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.m b/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.m deleted file mode 100644 index 0e2a27ba..00000000 --- a/ios/RNFirebase/admob/RNFirebaseAdMobRewardedVideo.m +++ /dev/null @@ -1,77 +0,0 @@ -#import "RNFirebaseAdMobRewardedVideo.h" -#import "RNFirebaseUtil.h" - -@implementation RNFirebaseAdMobRewardedVideo - -#if __has_include() - -- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate { - self = [super init]; - if (self) { - _adUnitID = adUnit; - _delegate = delegate; - _videoAd = [self createRewardedVideo]; - } - return self; -} - -- (GADRewardBasedVideoAd *)createRewardedVideo { - GADRewardBasedVideoAd *videoAd = [GADRewardBasedVideoAd sharedInstance]; - videoAd.delegate = self; - return videoAd; -} - -- (void)loadAd:(NSDictionary *)request { - [_videoAd loadRequest:[RNFirebaseAdMob buildRequest:request] withAdUnitID:_adUnitID]; -} - -- (void)show { - if (_videoAd.isReady) { - [_videoAd presentFromRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController]; - } -} - -- (void)sendJSEvent:(NSString *)type payload:(NSDictionary *)payload { - [RNFirebaseUtil sendJSEvent:self.delegate name:ADMOB_REWARDED_VIDEO_EVENT body:@{ - @"type": type, - @"adUnit": _adUnitID, - @"payload": payload - }]; -} - -- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd - didRewardUserWithReward:(GADAdReward *)reward { - [self sendJSEvent:@"onRewarded" payload:@{ - @"type":reward.type, - @"amount":reward.amount, - }]; -} - -- (void)rewardBasedVideoAdDidReceiveAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd { - [self sendJSEvent:@"onAdLoaded" payload:@{}]; -} - -- (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd { - [self sendJSEvent:@"onAdOpened" payload:@{}]; -} - -- (void)rewardBasedVideoAdDidStartPlaying:(GADRewardBasedVideoAd *)rewardBasedVideoAd { - [self sendJSEvent:@"onRewardedVideoStarted" payload:@{}]; -} - -- (void)rewardBasedVideoAdDidClose:(GADRewardBasedVideoAd *)rewardBasedVideoAd { - [self sendJSEvent:@"onAdClosed" payload:@{}]; -} - -- (void)rewardBasedVideoAdWillLeaveApplication:(GADRewardBasedVideoAd *)rewardBasedVideoAd { - [self sendJSEvent:@"onAdLeftApplication" payload:@{}]; -} - -- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd - didFailToLoadWithError:(NSError *)error { - [self sendJSEvent:@"onAdFailedToLoad" payload:[RNFirebaseAdMob errorCodeToDictionary:error]]; -} - -#endif - -@end diff --git a/ios/RNFirebase/analytics/RNFirebaseAnalytics.h b/ios/RNFirebase/analytics/RNFirebaseAnalytics.h deleted file mode 100644 index da0c5bba..00000000 --- a/ios/RNFirebase/analytics/RNFirebaseAnalytics.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RNFirebaseAnalytics_h -#define RNFirebaseAnalytics_h -#import - -#if __has_include() -#import - -@interface RNFirebaseAnalytics : NSObject { - -} - -@end - -#else -@interface RNFirebaseAnalytics : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/analytics/RNFirebaseAnalytics.m b/ios/RNFirebase/analytics/RNFirebaseAnalytics.m deleted file mode 100644 index 91de5476..00000000 --- a/ios/RNFirebase/analytics/RNFirebaseAnalytics.m +++ /dev/null @@ -1,41 +0,0 @@ -#import "RNFirebaseAnalytics.h" -#import - -#if __has_include() -#import -#import - -@implementation RNFirebaseAnalytics -RCT_EXPORT_MODULE(); - -RCT_EXPORT_METHOD(logEvent:(NSString *)name props:(NSDictionary *)props) { - [FIRAnalytics logEventWithName:name parameters:props]; -} - -RCT_EXPORT_METHOD(setAnalyticsCollectionEnabled:(BOOL) enabled) { - [[FIRAnalyticsConfiguration sharedInstance] setAnalyticsCollectionEnabled:enabled]; -} - -RCT_EXPORT_METHOD(setCurrentScreen:(NSString *) screenName screenClass:(NSString *) screenClassOverriew) { - RCTUnsafeExecuteOnMainQueueSync(^{ - [FIRAnalytics setScreenName:screenName screenClass:screenClassOverriew]; - }); -} - -RCT_EXPORT_METHOD(setUserId: (NSString *) id) { - [FIRAnalytics setUserID:id]; -} - -RCT_EXPORT_METHOD(setUserProperty: (NSString *) name value:(NSString *) value) { - [FIRAnalytics setUserPropertyString:value forName:name]; -} - -// not implemented on iOS sdk -RCT_EXPORT_METHOD(setMinimumSessionDuration:(nonnull NSNumber *) milliseconds) {} -RCT_EXPORT_METHOD(setSessionTimeoutDuration:(nonnull NSNumber *) milliseconds) {} -@end - -#else -@implementation RNFirebaseAnalytics -@end -#endif diff --git a/ios/RNFirebase/auth/RNFirebaseAuth.h b/ios/RNFirebase/auth/RNFirebaseAuth.h deleted file mode 100644 index dd3fef77..00000000 --- a/ios/RNFirebase/auth/RNFirebaseAuth.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef RNFirebaseAuth_h -#define RNFirebaseAuth_h -#import - -#if __has_include() -#import -#import -#import - -@interface RNFirebaseAuth : RCTEventEmitter {}; -@end - -extern NSString * const AuthErrorCode_toJSErrorCode[]; -NSString * const AuthErrorCode_toJSErrorCode[] = { - [FIRAuthErrorCodeInvalidCustomToken] = @"auth/invalid-custom-token", - [FIRAuthErrorCodeCustomTokenMismatch] = @"auth/custom-token-mismatch", - [FIRAuthErrorCodeInvalidCredential] = @"auth/invalid-credential", - [FIRAuthErrorCodeUserDisabled] = @"auth/user-disabled", - [FIRAuthErrorCodeOperationNotAllowed] = @"auth/operation-not-allowed", - [FIRAuthErrorCodeEmailAlreadyInUse] = @"auth/email-already-in-use", - [FIRAuthErrorCodeInvalidEmail] = @"auth/invalid-email", - [FIRAuthErrorCodeWrongPassword] = @"auth/wrong-password", - [FIRAuthErrorCodeTooManyRequests] = @"auth/too-many-requests", - [FIRAuthErrorCodeUserNotFound] = @"auth/user-not-found", - [FIRAuthErrorCodeAccountExistsWithDifferentCredential] = @"auth/account-exists-with-different-credential", - [FIRAuthErrorCodeRequiresRecentLogin] = @"auth/requires-recent-login", - [FIRAuthErrorCodeProviderAlreadyLinked] = @"auth/provider-already-linked", - [FIRAuthErrorCodeNoSuchProvider] = @"auth/no-such-provider", - [FIRAuthErrorCodeInvalidUserToken] = @"auth/invalid-user-token", - [FIRAuthErrorCodeNetworkError] = @"auth/network-request-failed", - [FIRAuthErrorCodeUserTokenExpired] = @"auth/user-token-expired", - [FIRAuthErrorCodeInvalidAPIKey] = @"auth/invalid-api-key", - [FIRAuthErrorCodeUserMismatch] = @"auth/user-mismatch", - [FIRAuthErrorCodeCredentialAlreadyInUse] = @"auth/credential-already-in-use", - [FIRAuthErrorCodeWeakPassword] = @"auth/weak-password", - [FIRAuthErrorCodeAppNotAuthorized] = @"auth/app-not-authorized", - [FIRAuthErrorCodeExpiredActionCode] = @"auth/expired-action-code", - [FIRAuthErrorCodeInvalidActionCode] = @"auth/invalid-action-code", - [FIRAuthErrorCodeInvalidMessagePayload] = @"auth/invalid-message-payload", - [FIRAuthErrorCodeInvalidSender] = @"auth/invalid-sender", - [FIRAuthErrorCodeInvalidRecipientEmail] = @"auth/invalid-recipient-email", - [FIRAuthErrorCodeMissingEmail] = @"auth/invalid-email", - [FIRAuthErrorCodeMissingIosBundleID] = @"auth/missing-ios-bundle-id", - [FIRAuthErrorCodeMissingAndroidPackageName] = @"auth/missing-android-pkg-name", - [FIRAuthErrorCodeUnauthorizedDomain] = @"auth/unauthorized-domain", - [FIRAuthErrorCodeInvalidContinueURI] = @"auth/invalid-continue-uri", - [FIRAuthErrorCodeMissingContinueURI] = @"auth/missing-continue-uri", - [FIRAuthErrorCodeMissingPhoneNumber] = @"auth/missing-phone-number", - [FIRAuthErrorCodeInvalidPhoneNumber] = @"auth/invalid-phone-number", - [FIRAuthErrorCodeMissingVerificationCode] = @"auth/missing-verification-code", - [FIRAuthErrorCodeInvalidVerificationCode] = @"auth/invalid-verification-code", - [FIRAuthErrorCodeMissingVerificationID] = @"auth/missing-verification-id", - [FIRAuthErrorCodeInvalidVerificationID] = @"auth/invalid-verification-id", - [FIRAuthErrorCodeMissingAppCredential] = @"auth/missing-app-credential", - [FIRAuthErrorCodeInvalidAppCredential] = @"auth/invalid-app-credential", - [FIRAuthErrorCodeSessionExpired] = @"auth/code-expired", - [FIRAuthErrorCodeQuotaExceeded] = @"auth/quota-exceeded", - [FIRAuthErrorCodeMissingAppToken] = @"auth/missing-apns-token", - [FIRAuthErrorCodeNotificationNotForwarded] = @"auth/notification-not-forwarded", - [FIRAuthErrorCodeAppNotVerified] = @"auth/app-not-verified", - [FIRAuthErrorCodeCaptchaCheckFailed] = @"auth/captcha-check-failed", - [FIRAuthErrorCodeWebContextAlreadyPresented] = @"auth/cancelled-popup-request", - [FIRAuthErrorCodeWebContextCancelled] = @"auth/popup-closed-by-user", - [FIRAuthErrorCodeAppVerificationUserInteractionFailure] = @"auth/app-verification-user-interaction-failure", - [FIRAuthErrorCodeInvalidClientID] = @"auth/invalid-oauth-client-id", - [FIRAuthErrorCodeWebNetworkRequestFailed] = @"auth/network-request-failed", - [FIRAuthErrorCodeWebInternalError] = @"auth/internal-error", - [FIRAuthErrorCodeNullUser] = @"auth/null-user", - [FIRAuthErrorCodeKeychainError] = @"auth/keychain-error", - [FIRAuthErrorCodeInternalError] = @"auth/internal-error", - [FIRAuthErrorCodeMalformedJWT] = @"auth/malformed-jwt" -}; -#else -@interface RNFirebaseAuth : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/auth/RNFirebaseAuth.m b/ios/RNFirebase/auth/RNFirebaseAuth.m deleted file mode 100644 index 2246e165..00000000 --- a/ios/RNFirebase/auth/RNFirebaseAuth.m +++ /dev/null @@ -1,1586 +0,0 @@ -#import "RNFirebaseAuth.h" -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" - -#if __has_include() - -static NSString *const keyIOS = @"iOS"; -static NSString *const keyUrl = @"url"; -static NSString *const keyUid = @"uid"; -static NSString *const keyUser = @"user"; -static NSString *const keyEmail = @"email"; -static NSString *const keyAndroid = @"android"; -static NSString *const keyProfile = @"profile"; -static NSString *const keyNewUser = @"isNewUser"; -static NSString *const keyUsername = @"username"; -static NSString *const keyPhotoUrl = @"photoURL"; -static NSString *const keyBundleId = @"bundleId"; -static NSString *const keyInstallApp = @"installApp"; -static NSString *const keyProviderId = @"providerId"; -static NSString *const keyPhoneNumber = @"phoneNumber"; -static NSString *const keyDisplayName = @"displayName"; -static NSString *const keyPackageName = @"packageName"; -static NSString *const keyMinVersion = @"minimumVersion"; -static NSString *const constAppLanguage = @"APP_LANGUAGE"; -static NSString *const constAppUser = @"APP_USER"; -static NSString *const keyHandleCodeInApp = @"handleCodeInApp"; -static NSString *const keyAdditionalUserInfo = @"additionalUserInfo"; - -static NSMutableDictionary *authStateHandlers; -static NSMutableDictionary *idTokenHandlers; - -@implementation RNFirebaseAuth -RCT_EXPORT_MODULE(); - -- (id)init { - self = [super init]; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - authStateHandlers = [[NSMutableDictionary alloc] init]; - idTokenHandlers = [[NSMutableDictionary alloc] init]; - DLog(@"RNFirebaseAuth:instance-created"); - }); - - DLog(@"RNFirebaseAuth:instance-initialized"); - return self; -} - -- (void)dealloc { - DLog(@"RNFirebaseAuth:instance-destroyed"); - - for(NSString* key in authStateHandlers) { - FIRApp *firApp = [RNFirebaseUtil getApp:key]; - [[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[authStateHandlers valueForKey:key]]; - [authStateHandlers removeObjectForKey:key]; - } - - for(NSString* key in idTokenHandlers) { - FIRApp *firApp = [RNFirebaseUtil getApp:key]; - [[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:key]]; - [idTokenHandlers removeObjectForKey:key]; - } -} - -- (void)invalidate { - // dealloc sometimes is not called when app is reloaded. - - for(NSString* key in authStateHandlers) { - FIRApp *firApp = [RNFirebaseUtil getApp:key]; - [[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[authStateHandlers valueForKey:key]]; - [authStateHandlers removeObjectForKey:key]; - } - - for(NSString* key in idTokenHandlers) { - FIRApp *firApp = [RNFirebaseUtil getApp:key]; - [[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:key]]; - [idTokenHandlers removeObjectForKey:key]; - } -} - -/** - * addAuthStateListener - * - */ -RCT_EXPORT_METHOD(addAuthStateListener: - (NSString *) appDisplayName) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - if (![authStateHandlers valueForKey:firApp.name]) { - FIRAuthStateDidChangeListenerHandle newListenerHandle = - [[FIRAuth authWithApp:firApp] addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { - if (user != nil) { - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:AUTH_STATE_CHANGED_EVENT body:@{ - keyUser: [self firebaseUserToDict:user]}]; - } else { - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:AUTH_STATE_CHANGED_EVENT body:@{}]; - } - }]; - - authStateHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle]; - } -} - -/** - * removeAuthStateListener - * - */ -RCT_EXPORT_METHOD(removeAuthStateListener: - (NSString *) appDisplayName) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - if ([authStateHandlers valueForKey:firApp.name]) { - [[FIRAuth authWithApp:firApp] removeAuthStateDidChangeListener:[authStateHandlers valueForKey:firApp.name]]; - [authStateHandlers removeObjectForKey:firApp.name]; - } -} - -/** - * addIdTokenListener - * - */ -RCT_EXPORT_METHOD(addIdTokenListener: - (NSString *) appDisplayName) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - if (![idTokenHandlers valueForKey:firApp.name]) { - FIRIDTokenDidChangeListenerHandle newListenerHandle = - [[FIRAuth authWithApp:firApp] addIDTokenDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { - if (user != nil) { - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:AUTH_ID_TOKEN_CHANGED_EVENT body:@{ - keyUser: [self firebaseUserToDict:user]}]; - } else { - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:AUTH_ID_TOKEN_CHANGED_EVENT body:@{}]; - } - }]; - - idTokenHandlers[firApp.name] = [NSValue valueWithNonretainedObject:newListenerHandle]; - } -} - -/** - removeAuthStateListener - - */ -RCT_EXPORT_METHOD(removeIdTokenListener: - (NSString *) appDisplayName) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - if ([idTokenHandlers valueForKey:firApp.name]) { - [[FIRAuth authWithApp:firApp] removeIDTokenDidChangeListener:[idTokenHandlers valueForKey:firApp.name]]; - [idTokenHandlers removeObjectForKey:firApp.name]; - } -} - -/** - * Flag to determine whether app verification should be disabled for testing or not. - * - * @return - */ -RCT_EXPORT_METHOD( - setAppVerificationDisabledForTesting: - (NSString *) appDisplayName - disabled: - (BOOL) disabled -) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [FIRAuth authWithApp:firApp].settings.appVerificationDisabledForTesting = disabled; -} - - -/** - signOut - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(signOut: - (NSString *) appDisplayName - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - NSError *error; - [[FIRAuth authWithApp:firApp] signOut:&error]; - if (!error) [self promiseNoUser:resolve rejecter:reject isError:NO]; - else [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - - -/** - signInAnonymously - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(signInAnonymously: - (NSString *) appDisplayName - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] signInAnonymouslyWithCompletion:^(FIRAuthDataResult *authResult, NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - signInWithEmailAndPassword - - @param NSString NSString email - @param NSString NSString password - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(signInWithEmailAndPassword: - (NSString *) appDisplayName - email: - (NSString *) email - password: - (NSString *) password - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] signInWithEmail:email password:password completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - signInWithEmailLink - - @param NSString NSString email - @param NSString NSString emailLink - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(signInWithEmailLink: - (NSString *) appDisplayName - email: - (NSString *) email - emailLink: - (NSString *) emailLink - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] signInWithEmail:email link:emailLink completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - createUserWithEmailAndPassword - - @param NSString NSString email - @param NSString NSString password - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ - -RCT_EXPORT_METHOD(createUserWithEmailAndPassword: - (NSString *) appDisplayName - email: - (NSString *) email - password: - (NSString *) password - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] createUserWithEmail:email password:password completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - deleteUser - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(delete: - (NSString *) appDisplayName - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user deleteWithCompletion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:NO]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - reload - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(reload: - (NSString *) appDisplayName - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [self reloadAndReturnUser:user resolver:resolve rejecter:reject]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - sendEmailVerification - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(sendEmailVerification: - (NSString *) appDisplayName - actionCodeSettings: - (NSDictionary *) actionCodeSettings - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - if (user) { - id handler = ^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - FIRUser *userAfterUpdate = [FIRAuth authWithApp:firApp].currentUser; - [self promiseWithUser:resolve rejecter:reject user:userAfterUpdate]; - } - }; - if (actionCodeSettings) { - FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings]; - [user sendEmailVerificationWithActionCodeSettings:settings completion:handler]; - } else { - [user sendEmailVerificationWithCompletion:handler]; - } - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - updateEmail - - @param NSString email - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(updateEmail: - (NSString *) appDisplayName - email: - (NSString *) email - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user updateEmail:email completion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self reloadAndReturnUser:user resolver:resolve rejecter:reject]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - updatePassword - - @param NSString password - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(updatePassword: - (NSString *) appDisplayName - password: - (NSString *) password - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user updatePassword:password completion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - FIRUser *userAfterUpdate = [FIRAuth authWithApp:firApp].currentUser; - [self promiseWithUser:resolve rejecter:reject user:userAfterUpdate]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - - -/** - updatePhoneNumber - - @param NSString password - @param NSString provider - @param NSString authToken - @param NSString authSecret - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(updatePhoneNumber: - (NSString *) appDisplayName - provider: - (NSString *) provider - token: - (NSString *) authToken - secret: - (NSString *) authSecret - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - FIRPhoneAuthCredential *credential = - (FIRPhoneAuthCredential *) [self getCredentialForProvider:provider token:authToken secret:authSecret]; - - if (credential == nil) { - return reject(@"auth/invalid-credential", - @"The supplied auth credential is malformed, has expired or is not currently supported.", - nil); - } - - [user updatePhoneNumberCredential:credential completion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - FIRUser *userAfterUpdate = [FIRAuth authWithApp:firApp].currentUser; - [self promiseWithUser:resolve rejecter:reject user:userAfterUpdate]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - updateProfile - - @param NSDictionary props - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return return - */ -RCT_EXPORT_METHOD(updateProfile: - (NSString *) appDisplayName - props: - (NSDictionary *) props - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - FIRUserProfileChangeRequest *changeRequest = [user profileChangeRequest]; - NSMutableArray *allKeys = [[props allKeys] mutableCopy]; - - for (NSString *key in allKeys) { - @try { - if ([key isEqualToString:keyPhotoUrl]) { - NSURL *url = [NSURL URLWithString:[props valueForKey:key]]; - [changeRequest setValue:url forKey:key]; - } else { - [changeRequest setValue:props[key] forKey:key]; - } - } @catch (NSException *exception) { - DLog(@"Exception occurred while configuring: %@", exception); - } - } - - [changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self reloadAndReturnUser:user resolver:resolve rejecter:reject]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - getIdToken - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(getIdToken: - (NSString *) appDisplayName - forceRefresh: - (BOOL) forceRefresh - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user getIDTokenForcingRefresh:(BOOL) forceRefresh completion:^(NSString *token, NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - resolve(token); - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - * getIdTokenResult - * - * @param RCTPromiseResolveBlock resolve - * @param RCTPromiseRejectBlock reject - * @return - */ -RCT_EXPORT_METHOD(getIdTokenResult: - (NSString *) appDisplayName - forceRefresh: - (BOOL) forceRefresh - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user getIDTokenResultForcingRefresh:(BOOL) forceRefresh completion:^(FIRAuthTokenResult *_Nullable tokenResult, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - NSMutableDictionary *tokenResultDict = [NSMutableDictionary dictionary]; - [tokenResultDict setValue:[RNFirebaseUtil getISO8601String:tokenResult.authDate] forKey:@"authTime"]; - [tokenResultDict setValue:[RNFirebaseUtil getISO8601String:tokenResult.issuedAtDate] forKey:@"issuedAtTime"]; - [tokenResultDict setValue:[RNFirebaseUtil getISO8601String:tokenResult.expirationDate] forKey:@"expirationTime"]; - - [tokenResultDict setValue:tokenResult.token forKey:@"token"]; - [tokenResultDict setValue:tokenResult.claims forKey:@"claims"]; - - NSString *provider = tokenResult.signInProvider; - if (!provider) { - provider = tokenResult.claims[@"firebase"][@"sign_in_provider"]; - } - - [tokenResultDict setValue:provider forKey:@"signInProvider"]; - resolve(tokenResultDict); - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - signInWithCredential - - @param NSString provider - @param NSString authToken - @param NSString authSecret - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(signInWithCredential: - (NSString *) appDisplayName - provider: - (NSString *) provider - token: - (NSString *) authToken - secret: - (NSString *) authSecret - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret]; - - if (credential == nil) { - return reject(@"auth/invalid-credential", - @"The supplied auth credential is malformed, has expired or is not currently supported.", - nil); - } - - [[FIRAuth authWithApp:firApp] signInAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - confirmPasswordReset - - @param NSString code - @param NSString newPassword - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(confirmPasswordReset: - (NSString *) appDisplayName - code: - (NSString *) code - newPassword: - (NSString *) newPassword - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] confirmPasswordResetWithCode:code newPassword:newPassword completion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:NO]; - } - }]; -} - - -/** - * applyActionCode - * - * @param NSString code - * @param RCTPromiseResolveBlock resolve - * @param RCTPromiseRejectBlock reject - * @return - */ -RCT_EXPORT_METHOD(applyActionCode: - (NSString *) appDisplayName - code: - (NSString *) code - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] applyActionCode:code completion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:NO]; - } - }]; -} - -/** - * checkActionCode - * - * @param NSString code - * @param RCTPromiseResolveBlock resolve - * @param RCTPromiseRejectBlock reject - * @return - */ -RCT_EXPORT_METHOD(checkActionCode: - (NSString *) appDisplayName - code: - (NSString *) code - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] checkActionCode:code completion:^(FIRActionCodeInfo *_Nullable info, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - NSString *actionType = @"ERROR"; - switch (info.operation) { - case FIRActionCodeOperationPasswordReset:actionType = @"PASSWORD_RESET"; - break; - case FIRActionCodeOperationVerifyEmail:actionType = @"VERIFY_EMAIL"; - break; - case FIRActionCodeOperationUnknown:actionType = @"UNKNOWN"; - break; - case FIRActionCodeOperationRecoverEmail:actionType = @"RECOVER_EMAIL"; - break; - case FIRActionCodeOperationEmailLink:actionType = @"EMAIL_SIGNIN"; - break; - } - - NSMutableDictionary *data = [NSMutableDictionary dictionary]; - - if ([info dataForKey:FIRActionCodeEmailKey] != nil) { - [data setValue:[info dataForKey:FIRActionCodeEmailKey] forKey:keyEmail]; - } else { - [data setValue:[NSNull null] forKey:keyEmail]; - } - - if ([info dataForKey:FIRActionCodeFromEmailKey] != nil) { - [data setValue:[info dataForKey:FIRActionCodeFromEmailKey] forKey:@"fromEmail"]; - } else { - [data setValue:[NSNull null] forKey:@"fromEmail"]; - } - - NSDictionary *result = @{@"data": data, @"operation": actionType}; - - resolve(result); - } - }]; -} - -/** - sendPasswordResetEmail - - @param NSString email - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(sendPasswordResetEmail: - (NSString *) appDisplayName - email: - (NSString *) email - actionCodeSettings: - (NSDictionary *) actionCodeSettings - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - id handler = ^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:NO]; - } - }; - - if (actionCodeSettings) { - FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings]; - [[FIRAuth authWithApp:firApp] sendPasswordResetWithEmail:email actionCodeSettings:settings completion:handler]; - } else { - [[FIRAuth authWithApp:firApp] sendPasswordResetWithEmail:email completion:handler]; - } -} - -/** - sendSignInLinkToEmail - - @param NSString email - @param NSDictionary actionCodeSettings - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(sendSignInLinkToEmail: - (NSString *) appDisplayName - email: - (NSString *) email - actionCodeSettings: - (NSDictionary *) actionCodeSettings - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - id handler = ^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:NO]; - } - }; - - FIRActionCodeSettings *settings = [self buildActionCodeSettings:actionCodeSettings]; - [[FIRAuth authWithApp:firApp] sendSignInLinkToEmail:email actionCodeSettings:settings completion:handler]; -} - - -/** - signInWithCustomToken - - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(signInWithCustomToken: - (NSString *) appDisplayName - customToken: - (NSString *) customToken - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] signInWithCustomToken:customToken completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; -} - -/** - signInWithPhoneNumber - - @param string phoneNumber - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(signInWithPhoneNumber: - (NSString *) appDisplayName - phoneNumber: - (NSString *) phoneNumber - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firApp]] verifyPhoneNumber:phoneNumber UIDelegate:nil completion:^( - NSString *_Nullable verificationID, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:verificationID forKey:@"authVerificationID"]; - resolve(@{ - @"verificationId": verificationID - }); - } - }]; -} - -/** - verifyPhoneNumber - - @param string phoneNumber - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(verifyPhoneNumber: - (NSString *) appDisplayName - phoneNumber: - (NSString *) phoneNumber - requestKey: - (NSString *) requestKey) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firApp]] verifyPhoneNumber:phoneNumber UIDelegate:nil completion:^( - NSString *_Nullable verificationID, - NSError *_Nullable error) { - if (error) { - NSDictionary *jsError = [self getJSError:(error)]; - NSDictionary *body = @{ - @"type": @"onVerificationFailed", - @"requestKey": requestKey, - @"state": @{@"error": jsError}, - }; - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:PHONE_AUTH_STATE_CHANGED_EVENT body:body]; - } else { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:verificationID forKey:@"authVerificationID"]; - NSDictionary *body = @{ - @"type": @"onCodeSent", - @"requestKey": requestKey, - @"state": @{@"verificationId": verificationID}, - }; - [RNFirebaseUtil sendJSEventWithAppName:self app:firApp name:PHONE_AUTH_STATE_CHANGED_EVENT body:body]; - } - }]; -} - -RCT_EXPORT_METHOD(_confirmVerificationCode: - (NSString *) appDisplayName - verificationCode: - (NSString *) verificationCode - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *verificationId = [defaults stringForKey:@"authVerificationID"]; - - FIRAuthCredential *credential = - [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationId verificationCode:verificationCode]; - - [[FIRAuth authWithApp:firApp] signInAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *authResult, - NSError *error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithUser:resolve rejecter:reject user:authResult.user]; - } - }]; -} - -/** - linkWithCredential - - @param NSString provider - @param NSString authToken - @param NSString authSecret - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(linkWithCredential: - (NSString *) appDisplayName - provider: - (NSString *) provider - authToken: - (NSString *) authToken - authSecret: - (NSString *) authSecret - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret]; - - if (credential == nil) { - return reject(@"auth/invalid-credential", - @"The supplied auth credential is malformed, has expired or is not currently supported.", - nil); - } - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - if (user) { - [user linkAndRetrieveDataWithCredential:credential - completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - unlink - - @param NSString provider - @param NSString authToken - @param NSString authSecret - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(unlink: - (NSString *) appDisplayName - providerId: - (NSString *) providerId - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user unlinkFromProvider:providerId completion:^(FIRUser *_Nullable _user, NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self reloadAndReturnUser:user resolver:resolve rejecter:reject]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - reauthenticateWithCredential - - @param NSString provider - @param NSString authToken - @param NSString authSecret - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(reauthenticateWithCredential: - (NSString *) appDisplayName - provider: - (NSString *) provider - authToken: - (NSString *) authToken - authSecret: - (NSString *) authSecret - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - FIRAuthCredential *credential = [self getCredentialForProvider:provider token:authToken secret:authSecret]; - - if (credential == nil) { - return reject(@"auth/invalid-credential", - @"The supplied auth credential is malformed, has expired or is not currently supported.", - nil); - } - - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if (user) { - [user reauthenticateAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *_Nullable authResult, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithAuthResult:resolve rejecter:reject authResult:authResult]; - } - }]; - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } -} - -/** - fetchSignInMethodsForEmail - - @param NSString email - @param RCTPromiseResolveBlock resolve - @param RCTPromiseRejectBlock reject - @return - */ -RCT_EXPORT_METHOD(fetchSignInMethodsForEmail: - (NSString *) appDisplayName - email: - (NSString *) email - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - - [[FIRAuth authWithApp:firApp] fetchSignInMethodsForEmail:email completion:^(NSArray *_Nullable providers, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else if (!providers) { - NSMutableArray *emptyResponse = [[NSMutableArray alloc] init]; - resolve(emptyResponse); - } else { - resolve(providers); - } - }]; -} - -/** - getCredentialForProvider - - @param provider string - @param authToken string - @param authTokenSecret string - @return FIRAuthCredential - */ -- (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider token:(NSString *)authToken secret:(NSString *)authTokenSecret { - FIRAuthCredential *credential; - - if ([provider compare:@"twitter.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIRTwitterAuthProvider credentialWithToken:authToken secret:authTokenSecret]; - } else if ([provider compare:@"facebook.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIRFacebookAuthProvider credentialWithAccessToken:authToken]; - } else if ([provider compare:@"google.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIRGoogleAuthProvider credentialWithIDToken:authToken accessToken:authTokenSecret]; - } else if ([provider compare:@"password" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIREmailAuthProvider credentialWithEmail:authToken password:authTokenSecret]; - } else if ([provider compare:@"emailLink" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIREmailAuthProvider credentialWithEmail:authToken link:authTokenSecret]; - } else if ([provider compare:@"github.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIRGitHubAuthProvider credentialWithToken:authToken]; - } else if ([provider compare:@"phone" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = - [[FIRPhoneAuthProvider provider] credentialWithVerificationID:authToken verificationCode:authTokenSecret]; - } else if ([provider compare:@"oauth" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIROAuthProvider credentialWithProviderID:@"oauth" IDToken:authToken accessToken:authTokenSecret]; - } else { - DLog(@"Provider not yet handled: %@", provider); - } - - return credential; -} - -/** - setLanguageCode - - @param NSString code - @return - */ -RCT_EXPORT_METHOD(setLanguageCode: - (NSString *) appDisplayName - code: - (NSString *) code) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [FIRAuth authWithApp:firApp].languageCode = code; -} - -/** - useDeviceLanguage - - @param NSString code - @return - */ -RCT_EXPORT_METHOD(useDeviceLanguage: - (NSString *) appDisplayName) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [[FIRAuth authWithApp:firApp] useAppLanguage]; -} - -RCT_EXPORT_METHOD(verifyPasswordResetCode: - (NSString *) appDisplayName - code: - (NSString *) code - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [[FIRAuth authWithApp:firApp] verifyPasswordResetCode:code completion:^(NSString *_Nullable email, - NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - resolve(email); - } - }]; -} - -// This is here to protect against bugs in the iOS SDK which don't -// correctly refresh the user object when performing certain operations -- (void)reloadAndReturnUser:(FIRUser *)user - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - [user reloadWithCompletion:^(NSError *_Nullable error) { - if (error) { - [self promiseRejectAuthException:reject error:error]; - } else { - [self promiseWithUser:resolve rejecter:reject user:user]; - } - }]; -} - -/** - Resolve or reject a promise based on isError value - - @param resolve RCTPromiseResolveBlock - @param reject RCTPromiseRejectBlock - @param isError BOOL - */ -- (void)promiseNoUser:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject isError:(BOOL)isError { - if (isError) { - reject(@"auth/no-current-user", @"No user currently signed in.", nil); - } else { - resolve([NSNull null]); - } -} - -/** - Reject a promise with an auth exception - - @param reject RCTPromiseRejectBlock - @param error NSError - */ -- (void)promiseRejectAuthException:(RCTPromiseRejectBlock)reject error:(NSError *)error { - NSDictionary *jsError = [self getJSError:(error)]; - reject([jsError valueForKey:@"code"], [jsError valueForKey:@"message"], error); -} - -/** - Reject a promise with an auth exception - - @param error NSError - */ -- (NSDictionary *)getJSError:(NSError *)error { - NSString *code = AuthErrorCode_toJSErrorCode[error.code]; - NSString *message = [error localizedDescription]; - NSString *nativeErrorMessage = [error localizedDescription]; - - if (code == nil) code = @"auth/unknown"; - - // TODO: Salakar: replace these with a AuthErrorCode_toJSErrorMessage map (like codes now does) - switch (error.code) { - case FIRAuthErrorCodeInvalidCustomToken: - message = @"The custom token format is incorrect. Please check the documentation."; - break; - case FIRAuthErrorCodeCustomTokenMismatch: - message = @"The custom token corresponds to a different audience."; - break; - case FIRAuthErrorCodeInvalidCredential: - message = @"The supplied auth credential is malformed or has expired."; - break; - case FIRAuthErrorCodeInvalidEmail: - message = @"The email address is badly formatted."; - break; - case FIRAuthErrorCodeWrongPassword: - message = @"The password is invalid or the user does not have a password."; - break; - case FIRAuthErrorCodeUserMismatch: - message = @"The supplied credentials do not correspond to the previously signed in user."; - break; - case FIRAuthErrorCodeRequiresRecentLogin: - message = - @"This operation is sensitive and requires recent authentication. Log in again before retrying this request."; - break; - case FIRAuthErrorCodeAccountExistsWithDifferentCredential: - message = - @"An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address."; - break; - case FIRAuthErrorCodeEmailAlreadyInUse: - message = @"The email address is already in use by another account."; - break; - case FIRAuthErrorCodeCredentialAlreadyInUse: - message = @"This credential is already associated with a different user account."; - break; - case FIRAuthErrorCodeUserDisabled: - message = @"The user account has been disabled by an administrator."; - break; - case FIRAuthErrorCodeUserTokenExpired: - message = @"The user's credential is no longer valid. The user must sign in again."; - break; - case FIRAuthErrorCodeUserNotFound: - message = @"There is no user record corresponding to this identifier. The user may have been deleted."; - break; - case FIRAuthErrorCodeInvalidUserToken: - message = @"The user's credential is no longer valid. The user must sign in again."; - break; - case FIRAuthErrorCodeWeakPassword: - message = @"The given password is invalid."; - break; - case FIRAuthErrorCodeOperationNotAllowed: - message = @"This operation is not allowed. You must enable this service in the console."; - break; - case FIRAuthErrorCodeNetworkError: - message = @"A network error has occurred, please try again."; - break; - case FIRAuthErrorCodeInternalError: - message = @"An internal error has occurred, please try again."; - break; - default: - break; - } - - return @{ - @"code": code, - @"message": message, - @"nativeErrorMessage": nativeErrorMessage, - }; -} - -/** - * Resolve or reject a promise based on FIRUser value existence - * - * @param resolve RCTPromiseResolveBlock - * @param reject RCTPromiseRejectBlock - * @param user FIRUser - */ -- (void)promiseWithUser:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject user:(FIRUser *)user { - if (user) { - NSDictionary *userDict = [self firebaseUserToDict:user]; - resolve(userDict); - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } - -} - -/** - * Resolve or reject a promise based on FIRAuthResult value existence - * - * @param resolve RCTPromiseResolveBlock - * @param reject RCTPromiseRejectBlock - * @param authResult FIRAuthDataResult - */ -- (void)promiseWithAuthResult:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject authResult:(FIRAuthDataResult *)authResult { - if (authResult && authResult.user) { - NSMutableDictionary *authResultDict = [NSMutableDictionary dictionary]; - - // additionalUserInfo - if (authResult.additionalUserInfo) { - NSMutableDictionary *additionalUserInfo = [NSMutableDictionary dictionary]; - - // isNewUser - [additionalUserInfo setValue:@(authResult.additionalUserInfo.isNewUser) forKey:keyNewUser]; - - // profile - if (authResult.additionalUserInfo.profile) { - [additionalUserInfo setValue:authResult.additionalUserInfo.profile forKey:keyProfile]; - } else { - [additionalUserInfo setValue:[NSNull null] forKey:keyProfile]; - } - - // providerId - if (authResult.additionalUserInfo.providerID) { - [additionalUserInfo setValue:authResult.additionalUserInfo.providerID forKey:keyProviderId]; - } else { - [additionalUserInfo setValue:[NSNull null] forKey:keyProviderId]; - } - - // username - if (authResult.additionalUserInfo.username) { - [additionalUserInfo setValue:authResult.additionalUserInfo.username forKey:keyUsername]; - } else { - [additionalUserInfo setValue:[NSNull null] forKey:keyUsername]; - } - - [authResultDict setValue:additionalUserInfo forKey:keyAdditionalUserInfo]; - } else { - [authResultDict setValue:[NSNull null] forKey:keyAdditionalUserInfo]; - } - - // user - [authResultDict setValue:[self firebaseUserToDict:authResult.user] forKey:keyUser]; - resolve(authResultDict); - } else { - [self promiseNoUser:resolve rejecter:reject isError:YES]; - } - -} - -/** - * Converts an array of FIRUserInfo instances into a web sdk compatible format - * - * @param providerData NSArray - * @return NSArray - */ -- (NSArray *)convertProviderData:(NSArray > *)providerData { - NSMutableArray *output = [NSMutableArray array]; - - for (id userInfo in providerData) { - NSMutableDictionary *pData = [NSMutableDictionary dictionary]; - - if (userInfo.providerID != nil) { - [pData setValue:userInfo.providerID forKey:keyProviderId]; - } - - if (userInfo.uid != nil) { - [pData setValue:userInfo.uid forKey:keyUid]; - } - - if (userInfo.displayName != nil) { - [pData setValue:userInfo.displayName forKey:keyDisplayName]; - } - - if (userInfo.photoURL != nil) { - [pData setValue:[userInfo.photoURL absoluteString] forKey:keyPhotoUrl]; - } - - if (userInfo.email != nil) { - [pData setValue:userInfo.email forKey:keyEmail]; - } - - if (userInfo.phoneNumber != nil) { - [pData setValue:userInfo.phoneNumber forKey:keyPhoneNumber]; - } - - [output addObject:pData]; - } - - return output; -} - -/** - * React native constant exports - exports native firebase apps mainly - * - * @return NSDictionary - */ -- (NSDictionary *)constantsToExport { - NSDictionary *firApps = [FIRApp allApps]; - NSMutableDictionary *constants = [NSMutableDictionary new]; - NSMutableDictionary *appLanguage = [NSMutableDictionary new]; - NSMutableDictionary *appUser = [NSMutableDictionary new]; - - for (id key in firApps) { - FIRApp *firApp = firApps[key]; - NSString *appName = firApp.name; - FIRUser *user = [FIRAuth authWithApp:firApp].currentUser; - - if ([appName isEqualToString:@"__FIRAPP_DEFAULT"]) { - appName = @"[DEFAULT]"; - } - - appLanguage[appName] = [FIRAuth authWithApp:firApp].languageCode; - - if (user != nil) { - appUser[appName] = [self firebaseUserToDict: user]; - } - } - - constants[constAppLanguage] = appLanguage; - constants[constAppUser] = appUser; - return constants; -} - -/** - * Converts a FIRUser instance into a dictionary to send via RNBridge - * - * @param user FIRUser - * @return NSDictionary - */ -- (NSDictionary *)firebaseUserToDict:(FIRUser *)user { - return @{ - keyDisplayName: user.displayName ? user.displayName : [NSNull null], - keyEmail: user.email ? user.email : [NSNull null], - @"emailVerified": @(user.emailVerified), - @"isAnonymous": @(user.anonymous), - @"metadata": @{ - @"creationTime": user.metadata.creationDate ? @(round( - [user.metadata.creationDate timeIntervalSince1970] * 1000.0)) : [NSNull null], - @"lastSignInTime": user.metadata.lastSignInDate ? @(round( - [user.metadata.lastSignInDate timeIntervalSince1970] * 1000.0)) : [NSNull null], - }, - keyPhoneNumber: user.phoneNumber ? user.phoneNumber : [NSNull null], - keyPhotoUrl: user.photoURL ? [user.photoURL absoluteString] : [NSNull null], - @"providerData": [self convertProviderData:user.providerData], - keyProviderId: [user.providerID lowercaseString], - @"refreshToken": user.refreshToken, - keyUid: user.uid - }; -} - -/** - * Create a FIRActionCodeSettings instance from JS args - * - * @param actionCodeSettings NSDictionary - * @return FIRActionCodeSettings - */ -- (FIRActionCodeSettings *)buildActionCodeSettings:(NSDictionary *)actionCodeSettings { - NSString *url = actionCodeSettings[keyUrl]; - NSDictionary *ios = actionCodeSettings[keyIOS]; - NSDictionary *android = actionCodeSettings[keyAndroid]; - BOOL handleCodeInApp = [actionCodeSettings[keyHandleCodeInApp] boolValue]; - - FIRActionCodeSettings *settings = [[FIRActionCodeSettings alloc] init]; - - if (android) { - NSString *packageName = android[keyPackageName]; - NSString *minimumVersion = android[keyMinVersion]; - BOOL installApp = [android[keyInstallApp] boolValue]; - - [settings setAndroidPackageName:packageName installIfNotAvailable:installApp minimumVersion:minimumVersion]; - } - - if (handleCodeInApp) { - [settings setHandleCodeInApp:handleCodeInApp]; - } - - if (ios && ios[keyBundleId]) { - [settings setIOSBundleID:ios[keyBundleId]]; - } - - if (url) { - [settings setURL:[NSURL URLWithString:url]]; - } - - return settings; -} - -- (NSArray *)supportedEvents { - return @[AUTH_STATE_CHANGED_EVENT, AUTH_ID_TOKEN_CHANGED_EVENT, PHONE_AUTH_STATE_CHANGED_EVENT]; -} - -+ (BOOL)requiresMainQueueSetup { - return YES; -} - -@end - -#else -@implementation RNFirebaseAuth -@end -#endif diff --git a/ios/RNFirebase/config/RNFirebaseRemoteConfig.h b/ios/RNFirebase/config/RNFirebaseRemoteConfig.h deleted file mode 100644 index 2f80806a..00000000 --- a/ios/RNFirebase/config/RNFirebaseRemoteConfig.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef RNFirebaseRemoteConfig_h -#define RNFirebaseRemoteConfig_h -#import - -#if __has_include() -#import - -@interface RNFirebaseRemoteConfig : NSObject - -@end - -#else -@interface RNFirebaseRemoteConfig : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/config/RNFirebaseRemoteConfig.m b/ios/RNFirebase/config/RNFirebaseRemoteConfig.m deleted file mode 100644 index 59f8d17e..00000000 --- a/ios/RNFirebase/config/RNFirebaseRemoteConfig.m +++ /dev/null @@ -1,144 +0,0 @@ -#import "RNFirebaseRemoteConfig.h" - -#if __has_include() - -#import -#import -#import - -NSString *convertFIRRemoteConfigFetchStatusToNSString(FIRRemoteConfigFetchStatus value) { - switch (value) { - case FIRRemoteConfigFetchStatusNoFetchYet: - return @"config/no_fetch_yet"; - case FIRRemoteConfigFetchStatusSuccess: - return @"config/success"; - case FIRRemoteConfigFetchStatusThrottled: - return @"config/throttled"; - default: - return @"config/failure"; - } -} - -NSString *convertFIRRemoteConfigFetchStatusToNSStringDescription(FIRRemoteConfigFetchStatus value) { - switch (value) { - case FIRRemoteConfigFetchStatusThrottled: - return @"fetch() operation cannot be completed successfully, due to throttling."; - case FIRRemoteConfigFetchStatusNoFetchYet: - default: - return @"fetch() operation cannot be completed successfully."; - } -} - -NSString *convertFIRRemoteConfigSourceToNSString(FIRRemoteConfigSource value) { - switch (value) { - case FIRRemoteConfigSourceDefault: - return @"default"; - case FIRRemoteConfigSourceRemote: - return @"remote"; - default: - return @"static"; - } -} - -NSDictionary *convertFIRRemoteConfigValueToNSDictionary(FIRRemoteConfigValue *value) { - return @{@"stringValue": value.stringValue ?: [NSNull null], @"numberValue": value.numberValue ?: [NSNull null], @"dataValue": value.dataValue ? [value.dataValue base64EncodedStringWithOptions:0] : [NSNull null], @"boolValue": @(value.boolValue), @"source": convertFIRRemoteConfigSourceToNSString(value.source)}; -} - -@implementation RNFirebaseRemoteConfig - -RCT_EXPORT_MODULE(RNFirebaseRemoteConfig); - -RCT_EXPORT_METHOD(enableDeveloperMode) { - FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:YES]; - [FIRRemoteConfig remoteConfig].configSettings = remoteConfigSettings; -} - -RCT_EXPORT_METHOD(fetch: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - [[FIRRemoteConfig remoteConfig] fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) { - if (error) { - reject(convertFIRRemoteConfigFetchStatusToNSString(status), convertFIRRemoteConfigFetchStatusToNSStringDescription(status), error); - } else { - resolve([NSNull null]); - } - }]; -} - -RCT_EXPORT_METHOD(fetchWithExpirationDuration: - (nonnull - NSNumber *)expirationDuration - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[FIRRemoteConfig remoteConfig] fetchWithExpirationDuration:expirationDuration.doubleValue completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) { - if (error) { - reject(convertFIRRemoteConfigFetchStatusToNSString(status), convertFIRRemoteConfigFetchStatusToNSStringDescription(status), error); - } else { - resolve([NSNull null]); - } - }]; -} - -RCT_EXPORT_METHOD(activateFetched: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - BOOL status = [[FIRRemoteConfig remoteConfig] activateFetched]; - resolve(@(status)); -} - -RCT_EXPORT_METHOD(getValue: - (NSString *) key - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - FIRRemoteConfigValue *value = [[FIRRemoteConfig remoteConfig] configValueForKey:key]; - resolve(convertFIRRemoteConfigValueToNSDictionary(value)); -} - -RCT_EXPORT_METHOD(getValues: - (NSArray *) keys - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - NSMutableArray *valuesArray = [[NSMutableArray alloc] init]; - for (NSString *key in keys) { - FIRRemoteConfigValue *value = [[FIRRemoteConfig remoteConfig] configValueForKey:key]; - [valuesArray addObject:convertFIRRemoteConfigValueToNSDictionary(value)]; - } - resolve(valuesArray); -} - -RCT_EXPORT_METHOD(getKeysByPrefix: - (NSString *) prefix - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject) { - NSSet *keys = [[FIRRemoteConfig remoteConfig] keysWithPrefix:prefix]; - NSMutableArray *keysArray = [[NSMutableArray alloc] init]; - for (NSString *key in keys) { - [keysArray addObject:key]; - } - resolve(keysArray); -} - -RCT_EXPORT_METHOD(setDefaults: - (NSDictionary *) defaults) { - [[FIRRemoteConfig remoteConfig] setDefaults:defaults]; -} - -RCT_EXPORT_METHOD(setDefaultsFromResource: - (NSString *) fileName) { - [[FIRRemoteConfig remoteConfig] setDefaultsFromPlistFileName:fileName]; -} - -@end - -#else -@implementation RNFirebaseRemoteConfig -@end -#endif diff --git a/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.h b/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.h deleted file mode 100644 index e0ed190a..00000000 --- a/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface RCTConvert (UIBackgroundFetchResult) - -@end diff --git a/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.m b/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.m deleted file mode 100644 index 2aae8f60..00000000 --- a/ios/RNFirebase/converters/RCTConvert+UIBackgroundFetchResult.m +++ /dev/null @@ -1,16 +0,0 @@ -#import "RCTConvert+UIBackgroundFetchResult.h" - -@implementation RCTConvert (UIBackgroundFetchResult) - -RCT_ENUM_CONVERTER( - UIBackgroundFetchResult, - (@{ - @"backgroundFetchResultNoData" : @(UIBackgroundFetchResultNoData), - @"backgroundFetchResultNewData" : @(UIBackgroundFetchResultNewData), - @"backgroundFetchResultFailed" : @(UIBackgroundFetchResultFailed)} - ), - UIBackgroundFetchResultNoData, - integerValue -) - -@end diff --git a/ios/RNFirebase/database/RNFirebaseDatabase.h b/ios/RNFirebase/database/RNFirebaseDatabase.h deleted file mode 100644 index 86840a2d..00000000 --- a/ios/RNFirebase/database/RNFirebaseDatabase.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef RNFirebaseDatabase_h -#define RNFirebaseDatabase_h - -#import - -#if __has_include() - -#import -#import -#import - -@interface RNFirebaseDatabase : RCTEventEmitter {} -@property NSMutableDictionary *dbReferences; -@property NSMutableDictionary *transactions; -@property dispatch_queue_t transactionQueue; - -+ (void)handlePromise:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject databaseError:(NSError *)databaseError; - -+ (FIRDatabase *)getDatabaseForApp:(NSString *)appDisplayName; -+ (FIRDatabase *)getDatabaseForApp:(NSString *)appDisplayName URL:(NSString *)url; - -+ (NSDictionary *)getJSError:(NSError *)nativeError; - -+ (NSString *)getMessageWithService:(NSString *)message service:(NSString *)service fullCode:(NSString *)fullCode; - -+ (NSString *)getCodeWithService:(NSString *)service code:(NSString *)code; - -@end - -#else -@interface RNFirebaseDatabase : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/database/RNFirebaseDatabase.m b/ios/RNFirebase/database/RNFirebaseDatabase.m deleted file mode 100644 index 5fe0fc93..00000000 --- a/ios/RNFirebase/database/RNFirebaseDatabase.m +++ /dev/null @@ -1,451 +0,0 @@ -#import "RNFirebaseDatabase.h" - -#if __has_include() - -#import -#import "RNFirebaseDatabaseReference.h" -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" - -@implementation RNFirebaseDatabase -RCT_EXPORT_MODULE(); - -// Run on a different thread -- (dispatch_queue_t)methodQueue { - return dispatch_queue_create("io.invertase.react-native-firebase.database", DISPATCH_QUEUE_SERIAL); -} - -- (id)init { - self = [super init]; - if (self != nil) { - _dbReferences = [[NSMutableDictionary alloc] init]; - _transactions = [[NSMutableDictionary alloc] init]; - _transactionQueue = dispatch_queue_create("io.invertase.react-native-firebase.database.transactions", DISPATCH_QUEUE_CONCURRENT); - } - return self; -} - -RCT_EXPORT_METHOD(goOnline:(NSString *)appDisplayName - dbURL:(NSString *)dbURL) { - [[RNFirebaseDatabase getDatabaseForApp:appDisplayName URL:dbURL] goOnline]; -} - -RCT_EXPORT_METHOD(goOffline:(NSString *)appDisplayName - dbURL:(NSString *)dbURL) { - [[RNFirebaseDatabase getDatabaseForApp:appDisplayName URL:dbURL] goOffline]; -} - -RCT_EXPORT_METHOD(setPersistence:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - state:(BOOL)state) { - [RNFirebaseDatabase getDatabaseForApp:appDisplayName URL:dbURL].persistenceEnabled = state; -} - -RCT_EXPORT_METHOD(setPersistenceCacheSizeBytes:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - size:(NSInteger *)size) { - [RNFirebaseDatabase getDatabaseForApp:appDisplayName URL:dbURL].persistenceCacheSizeBytes = (NSUInteger)size; -} - -RCT_EXPORT_METHOD(enableLogging:(BOOL)enabled) { - [FIRDatabase setLoggingEnabled:enabled]; -} - -RCT_EXPORT_METHOD(keepSynced:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - key:(NSString *)key - path:(NSString *)path - modifiers:(NSArray *)modifiers - state:(BOOL)state) { - FIRDatabaseQuery *query = [self getInternalReferenceForApp:appDisplayName dbURL:dbURL key:key path:path modifiers:modifiers].query; - [query keepSynced:state]; -} - -RCT_EXPORT_METHOD(transactionTryCommit:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - transactionId:(nonnull NSNumber *)transactionId - updates:(NSDictionary *)updates) { - __block NSMutableDictionary *transactionState; - - dispatch_sync(_transactionQueue, ^{ - transactionState = _transactions[[transactionId stringValue]]; - }); - - if (!transactionState) { - DLog(@"tryCommitTransaction for unknown ID %@", transactionId); - return; - } - - dispatch_semaphore_t sema = [transactionState valueForKey:@"semaphore"]; - - BOOL abort = [[updates valueForKey:@"abort"] boolValue]; - - if (abort) { - [transactionState setValue:@true forKey:@"abort"]; - } else { - id newValue = [updates valueForKey:@"value"]; - [transactionState setValue:newValue forKey:@"value"]; - } - - dispatch_semaphore_signal(sema); -} - - -RCT_EXPORT_METHOD(transactionStart:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - transactionId:(nonnull NSNumber *)transactionId - applyLocally:(BOOL)applyLocally) { - dispatch_async(_transactionQueue, ^{ - NSMutableDictionary *transactionState = [NSMutableDictionary new]; - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - transactionState[@"semaphore"] = sema; - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - - [ref runTransactionBlock:^FIRTransactionResult *_Nonnull (FIRMutableData *_Nonnull currentData) { - dispatch_barrier_async(_transactionQueue, ^{ - [_transactions setValue:transactionState forKey:[transactionId stringValue]]; - NSDictionary *updateMap = [self createTransactionUpdateMap:appDisplayName dbURL:dbURL transactionId:transactionId updatesData:currentData]; - [RNFirebaseUtil sendJSEvent:self name:DATABASE_TRANSACTION_EVENT body:updateMap]; - }); - - // wait for the js event handler to call tryCommitTransaction - // this wait occurs on the Firebase Worker Queue - // so if the tryCommitTransaction fails to signal the semaphore - // no further blocks will be executed by Firebase until the timeout expires - dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC); - BOOL timedout = dispatch_semaphore_wait(sema, delayTime) != 0; - - BOOL abort = [transactionState valueForKey:@"abort"] || timedout; - id value = [transactionState valueForKey:@"value"]; - - dispatch_barrier_async(_transactionQueue, ^{ - [_transactions removeObjectForKey:[transactionId stringValue]]; - }); - - if (abort) { - return [FIRTransactionResult abort]; - } else { - currentData.value = value; - return [FIRTransactionResult successWithValue:currentData]; - } - } andCompletionBlock:^(NSError *_Nullable databaseError, BOOL committed, FIRDataSnapshot *_Nullable snapshot) { - NSDictionary *resultMap = [self createTransactionResultMap:appDisplayName dbURL:dbURL transactionId:transactionId error:databaseError committed:committed snapshot:snapshot]; - [RNFirebaseUtil sendJSEvent:self name:DATABASE_TRANSACTION_EVENT body:resultMap]; - } withLocalEvents:applyLocally]; - }); -} - -RCT_EXPORT_METHOD(onDisconnectSet:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - props:(NSDictionary *)props - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(onDisconnectUpdate:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - props:(NSDictionary *)props - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref onDisconnectUpdateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(onDisconnectRemove:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref onDisconnectRemoveValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(onDisconnectCancel:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref cancelDisconnectOperationsWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(set:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - props:(NSDictionary *)props - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref setValue:[props valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(setPriority:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - priority:(NSDictionary *)priority - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref setPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(setWithPriority:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - data:(NSDictionary *)data - priority:(NSDictionary *)priority - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref setValue:[data valueForKey:@"value"] andPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(update:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - props:(NSDictionary *)props - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref updateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(remove:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - path:(NSString *)path - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRDatabaseReference *ref = [self getReferenceForAppPath:appDisplayName dbURL:dbURL path:path]; - [ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -RCT_EXPORT_METHOD(once:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - key:(NSString *)key - path:(NSString *)path - modifiers:(NSArray *)modifiers - eventName:(NSString *)eventName - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - RNFirebaseDatabaseReference *ref = [self getInternalReferenceForApp:appDisplayName dbURL:dbURL key:key path:path modifiers:modifiers]; - [ref once:eventName resolver:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(on:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - props:(NSDictionary *)props) { - RNFirebaseDatabaseReference *ref = [self getCachedInternalReferenceForApp:appDisplayName dbURL:dbURL props:props]; - [ref on:props[@"eventType"] registration:props[@"registration"]]; -} - -RCT_EXPORT_METHOD(off:(NSString *)key - eventRegistrationKey:(NSString *)eventRegistrationKey) { - RNFirebaseDatabaseReference *ref = _dbReferences[key]; - if (ref) { - [ref removeEventListener:eventRegistrationKey]; - - if (![ref hasListeners]) { - [_dbReferences removeObjectForKey:key]; - } - } -} - - - -/* - * INTERNALS/UTILS - */ -+ (void)handlePromise:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject databaseError:(NSError *)databaseError { - if (databaseError != nil) { - NSDictionary *jsError = [RNFirebaseDatabase getJSError:databaseError]; - reject([jsError valueForKey:@"code"], [jsError valueForKey:@"message"], databaseError); - } else { - resolve([NSNull null]); - } -} - -+ (FIRDatabase *)getDatabaseForApp:(NSString *)appDisplayName { - FIRApp *app = [RNFirebaseUtil getApp:appDisplayName]; - return [FIRDatabase databaseForApp:app]; -} - -+ (FIRDatabase *)getDatabaseForApp:(NSString *)appDisplayName URL:(NSString *)url { - if (url == nil) { - return [self getDatabaseForApp:appDisplayName]; - } - FIRApp *app = [RNFirebaseUtil getApp:appDisplayName]; - return [FIRDatabase databaseForApp:app URL:url]; -} - -- (FIRDatabaseReference *)getReferenceForAppPath:(NSString *)appDisplayName dbURL:(NSString *)dbURL path:(NSString *)path { - return [[RNFirebaseDatabase getDatabaseForApp:appDisplayName URL:dbURL] referenceWithPath:path]; -} - -- (RNFirebaseDatabaseReference *)getInternalReferenceForApp:(NSString *)appDisplayName dbURL:(NSString *)dbURL key:(NSString *)key path:(NSString *)path modifiers:(NSArray *)modifiers { - return [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self appDisplayName:appDisplayName dbURL:dbURL key:key refPath:path modifiers:modifiers]; -} - -- (RNFirebaseDatabaseReference *)getCachedInternalReferenceForApp:(NSString *)appDisplayName dbURL:(NSString *)dbURL props:(NSDictionary *)props { - NSString *key = props[@"key"]; - NSString *path = props[@"path"]; - NSArray *modifiers = props[@"modifiers"]; - - RNFirebaseDatabaseReference *ref = _dbReferences[key]; - - if (ref == nil) { - ref = [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self appDisplayName:appDisplayName dbURL:dbURL key:key refPath:path modifiers:modifiers]; - _dbReferences[key] = ref; - } - return ref; -} - -// TODO: Move to error util for use in other modules -+ (NSString *)getMessageWithService:(NSString *)message service:(NSString *)service fullCode:(NSString *)fullCode { - return [NSString stringWithFormat:@"%@: %@ (%@).", service, message, [fullCode lowercaseString]]; -} - -+ (NSString *)getCodeWithService:(NSString *)service code:(NSString *)code { - return [NSString stringWithFormat:@"%@/%@", [service lowercaseString], [code lowercaseString]]; -} - -+ (NSDictionary *)getJSError:(NSError *)nativeError { - NSMutableDictionary *errorMap = [[NSMutableDictionary alloc] init]; - [errorMap setValue:@(nativeError.code) forKey:@"nativeErrorCode"]; - [errorMap setValue:[nativeError localizedDescription] forKey:@"nativeErrorMessage"]; - - NSString *code; - NSString *message; - NSString *service = @"Database"; - - switch (nativeError.code) { - // iOS confirmed codes - case 1: // -3 on Android - code = [RNFirebaseDatabase getCodeWithService:service code:@"permission-denied"]; - message = [RNFirebaseDatabase getMessageWithService:@"Client doesn't have permission to access the desired data." service:service fullCode:code]; - break; - case 2: // -10 on Android - code = [RNFirebaseDatabase getCodeWithService:service code:@"unavailable"]; - message = [RNFirebaseDatabase getMessageWithService:@"The service is unavailable." service:service fullCode:code]; - break; - case 3: // -25 on Android - code = [RNFirebaseDatabase getCodeWithService:service code:@"write-cancelled"]; - message = [RNFirebaseDatabase getMessageWithService:@"The write was canceled by the user." service:service fullCode:code]; - break; - - // TODO: Missing iOS equivalent codes - case -1: - code = [RNFirebaseDatabase getCodeWithService:service code:@"data-stale"]; - message = [RNFirebaseDatabase getMessageWithService:@"The transaction needs to be run again with current data." service:service fullCode:code]; - break; - case -2: - code = [RNFirebaseDatabase getCodeWithService:service code:@"failure"]; - message = [RNFirebaseDatabase getMessageWithService:@"The server indicated that this operation failed." service:service fullCode:code]; - break; - case -4: - code = [RNFirebaseDatabase getCodeWithService:service code:@"disconnected"]; - message = [RNFirebaseDatabase getMessageWithService:@"The operation had to be aborted due to a network disconnect." service:service fullCode:code]; - break; - case -6: - code = [RNFirebaseDatabase getCodeWithService:service code:@"expired-token"]; - message = [RNFirebaseDatabase getMessageWithService:@"The supplied auth token has expired." service:service fullCode:code]; - break; - case -7: - code = [RNFirebaseDatabase getCodeWithService:service code:@"invalid-token"]; - message = [RNFirebaseDatabase getMessageWithService:@"The supplied auth token was invalid." service:service fullCode:code]; - break; - case -8: - code = [RNFirebaseDatabase getCodeWithService:service code:@"max-retries"]; - message = [RNFirebaseDatabase getMessageWithService:@"The transaction had too many retries." service:service fullCode:code]; - break; - case -9: - code = [RNFirebaseDatabase getCodeWithService:service code:@"overridden-by-set"]; - message = [RNFirebaseDatabase getMessageWithService:@"The transaction was overridden by a subsequent set." service:service fullCode:code]; - break; - case -11: - code = [RNFirebaseDatabase getCodeWithService:service code:@"user-code-exception"]; - message = [RNFirebaseDatabase getMessageWithService:@"User code called from the Firebase Database runloop threw an exception." service:service fullCode:code]; - break; - case -24: - code = [RNFirebaseDatabase getCodeWithService:service code:@"network-error"]; - message = [RNFirebaseDatabase getMessageWithService:@"The operation could not be performed due to a network error." service:service fullCode:code]; - break; - default: - code = [RNFirebaseDatabase getCodeWithService:service code:@"unknown"]; - message = [RNFirebaseDatabase getMessageWithService:@"An unknown error occurred." service:service fullCode:code]; - break; - } - - [errorMap setValue:code forKey:@"code"]; - [errorMap setValue:message forKey:@"message"]; - - return errorMap; -} - -- (NSDictionary *)createTransactionUpdateMap:(NSString *)appDisplayName dbURL:(NSString *)dbURL transactionId:(NSNumber *)transactionId updatesData:(FIRMutableData *)updatesData { - NSMutableDictionary *updatesMap = [[NSMutableDictionary alloc] init]; - [updatesMap setValue:transactionId forKey:@"id"]; - [updatesMap setValue:@"update" forKey:@"type"]; - [updatesMap setValue:appDisplayName forKey:@"appName"]; - [updatesMap setValue:dbURL forKey:@"dbURL"]; - [updatesMap setValue:updatesData.value forKey:@"value"]; - - return updatesMap; -} - -- (NSDictionary *)createTransactionResultMap:(NSString *)appDisplayName dbURL:(NSString *)dbURL transactionId:(NSNumber *)transactionId error:(NSError *)error committed:(BOOL)committed snapshot:(FIRDataSnapshot *)snapshot { - NSMutableDictionary *resultMap = [[NSMutableDictionary alloc] init]; - [resultMap setValue:transactionId forKey:@"id"]; - [resultMap setValue:appDisplayName forKey:@"appName"]; - [resultMap setValue:dbURL forKey:@"dbURL"]; - // TODO: no timeout on iOS - [resultMap setValue:@(committed) forKey:@"committed"]; - // TODO: no interrupted on iOS - if (error != nil) { - [resultMap setValue:@"error" forKey:@"type"]; - [resultMap setValue:[RNFirebaseDatabase getJSError:error] forKey:@"error"]; - // TODO: timeout error on iOS - } else { - [resultMap setValue:@"complete" forKey:@"type"]; - [resultMap setValue:[RNFirebaseDatabaseReference snapshotToDict:snapshot] forKey:@"snapshot"]; - } - - return resultMap; -} - -- (NSArray *)supportedEvents { - return @[DATABASE_SYNC_EVENT, DATABASE_TRANSACTION_EVENT]; -} - -+ (BOOL)requiresMainQueueSetup { - return YES; -} - -@end - -#else -@implementation RNFirebaseDatabase -@end -#endif diff --git a/ios/RNFirebase/database/RNFirebaseDatabaseReference.h b/ios/RNFirebase/database/RNFirebaseDatabaseReference.h deleted file mode 100644 index 9bf1d18e..00000000 --- a/ios/RNFirebase/database/RNFirebaseDatabaseReference.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef RNFirebaseDatabaseReference_h -#define RNFirebaseDatabaseReference_h -#import - -#if __has_include() -#import -#import "RNFirebaseDatabase.h" -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" -#import - -@interface RNFirebaseDatabaseReference : NSObject -@property RCTEventEmitter *emitter; -@property FIRDatabaseQuery *query; -@property NSString *appDisplayName; -@property NSString *dbURL; -@property NSString *key; -@property NSString *path; -@property NSMutableDictionary *listeners; - -- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter appDisplayName:(NSString *)appDisplayName dbURL:(NSString *)dbURL key:(NSString *)key refPath:(NSString *)refPath modifiers:(NSArray *)modifiers; -- (void)on:(NSString *) eventName registration:(NSDictionary *) registration; -- (void)once:(NSString *) eventType resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -- (void)removeEventListener:(NSString *)eventRegistrationKey; -- (BOOL)hasListeners; -+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)dataSnapshot; -@end - -#else - -@interface RNFirebaseDatabaseReference : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/database/RNFirebaseDatabaseReference.m b/ios/RNFirebase/database/RNFirebaseDatabaseReference.m deleted file mode 100644 index ad7faf52..00000000 --- a/ios/RNFirebase/database/RNFirebaseDatabaseReference.m +++ /dev/null @@ -1,219 +0,0 @@ -#import "RNFirebaseDatabaseReference.h" - -@implementation RNFirebaseDatabaseReference - -#if __has_include() - -- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter - appDisplayName:(NSString *)appDisplayName - dbURL:(NSString *)dbURL - key:(NSString *)key - refPath:(NSString *)refPath - modifiers:(NSArray *)modifiers { - self = [super init]; - if (self) { - _emitter = emitter; - _appDisplayName = appDisplayName; - _dbURL = dbURL; - _key = key; - _path = refPath; - _listeners = [[NSMutableDictionary alloc] init]; - _query = [self buildQueryAtPathWithModifiers:refPath modifiers:modifiers]; - } - return self; -} - -- (void)removeEventListener:(NSString *)eventRegistrationKey { - FIRDatabaseHandle handle = (FIRDatabaseHandle)[_listeners[eventRegistrationKey] integerValue]; - if (handle) { - [_query removeObserverWithHandle:handle]; - [_listeners removeObjectForKey:eventRegistrationKey]; - } -} - -- (void)on:(NSString *)eventType registration:(NSDictionary *)registration { - NSString *eventRegistrationKey = registration[@"eventRegistrationKey"]; - if (![self hasEventListener:eventRegistrationKey]) { - id andPreviousSiblingKeyWithBlock = ^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) { - [self handleDatabaseEvent:eventType registration:registration dataSnapshot:snapshot previousChildName:previousChildName]; - }; - id errorBlock = ^(NSError *_Nonnull error) { - DLog(@"Error onDBEvent: %@", [error debugDescription]); - [self removeEventListener:eventRegistrationKey]; - [self handleDatabaseError:registration error:error]; - }; - FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventType]; - FIRDatabaseHandle handle = [_query observeEventType:firDataEventType andPreviousSiblingKeyWithBlock:andPreviousSiblingKeyWithBlock withCancelBlock:errorBlock]; - _listeners[eventRegistrationKey] = @(handle); - } -} - -- (void)once:(NSString *)eventType - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventType]; - [_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) { - NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:snapshot previousChildName:previousChildName]; - resolve(data); - } withCancelBlock:^(NSError *_Nonnull error) { - DLog(@"Error onDBEventOnce: %@", [error debugDescription]); - [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; - }]; -} - -- (void)handleDatabaseEvent:(NSString *)eventType - registration:(NSDictionary *)registration - dataSnapshot:(FIRDataSnapshot *)dataSnapshot - previousChildName:(NSString *)previousChildName { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:dataSnapshot previousChildName:previousChildName]; - - [event setValue:data forKey:@"data"]; - [event setValue:_key forKey:@"key"]; - [event setValue:eventType forKey:@"eventType"]; - [event setValue:registration forKey:@"registration"]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:DATABASE_SYNC_EVENT body:event]; -} - -- (void)handleDatabaseError:(NSDictionary *)registration - error:(NSError *)error { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - [event setValue:_key forKey:@"key"]; - [event setValue:[RNFirebaseDatabase getJSError:error] forKey:@"error"]; - [event setValue:registration forKey:@"registration"]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:DATABASE_SYNC_EVENT body:event]; -} - -+ (NSDictionary *)snapshotToDictionary:(FIRDataSnapshot *)dataSnapshot - previousChildName:(NSString *)previousChildName { - NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; - NSDictionary *snapshot = [RNFirebaseDatabaseReference snapshotToDict:dataSnapshot]; - - [result setValue:snapshot forKey:@"snapshot"]; - [result setValue:previousChildName forKey:@"previousChildName"]; - - return result; -} - -+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)dataSnapshot { - NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init]; - - [snapshot setValue:dataSnapshot.key forKey:@"key"]; - [snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"]; - [snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"]; - [snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"]; - [snapshot setValue:[RNFirebaseDatabaseReference getChildKeys:dataSnapshot] forKey:@"childKeys"]; - [snapshot setValue:dataSnapshot.priority forKey:@"priority"]; - [snapshot setValue:dataSnapshot.value forKey:@"value"]; - - return snapshot; -} - -+ (NSMutableArray *)getChildKeys:(FIRDataSnapshot *)snapshot { - NSMutableArray *childKeys = [NSMutableArray array]; - if (snapshot.childrenCount > 0) { - NSEnumerator *children = [snapshot children]; - FIRDataSnapshot *child; - while (child = [children nextObject]) { - [childKeys addObject:child.key]; - } - } - return childKeys; -} - -- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(NSString *)path - modifiers:(NSArray *)modifiers { - FIRDatabase *firebaseDatabase = [RNFirebaseDatabase getDatabaseForApp:_appDisplayName URL:_dbURL]; - FIRDatabaseQuery *query = [[firebaseDatabase reference] child:path]; - - for (NSDictionary *modifier in modifiers) { - NSString *type = [modifier valueForKey:@"type"]; - NSString *name = [modifier valueForKey:@"name"]; - if ([type isEqualToString:@"orderBy"]) { - if ([name isEqualToString:@"orderByKey"]) { - query = [query queryOrderedByKey]; - } else if ([name isEqualToString:@"orderByPriority"]) { - query = [query queryOrderedByPriority]; - } else if ([name isEqualToString:@"orderByValue"]) { - query = [query queryOrderedByValue]; - } else if ([name isEqualToString:@"orderByChild"]) { - NSString *key = [modifier valueForKey:@"key"]; - query = [query queryOrderedByChild:key]; - } - } else if ([type isEqualToString:@"limit"]) { - int limit = [[modifier valueForKey:@"limit"] integerValue]; - if ([name isEqualToString:@"limitToLast"]) { - query = [query queryLimitedToLast:limit]; - } else if ([name isEqualToString:@"limitToFirst"]) { - query = [query queryLimitedToFirst:limit]; - } - } else if ([type isEqualToString:@"filter"]) { - NSString *valueType = [modifier valueForKey:@"valueType"]; - NSString *key = [modifier valueForKey:@"key"]; - id value = [self getIdValue:[modifier valueForKey:@"value"] type:valueType]; - if ([name isEqualToString:@"equalTo"]) { - if (key != nil) { - query = [query queryEqualToValue:value childKey:key]; - } else { - query = [query queryEqualToValue:value]; - } - } else if ([name isEqualToString:@"endAt"]) { - if (key != nil) { - query = [query queryEndingAtValue:value childKey:key]; - } else { - query = [query queryEndingAtValue:value]; - } - } else if ([name isEqualToString:@"startAt"]) { - if (key != nil) { - query = [query queryStartingAtValue:value childKey:key]; - } else { - query = [query queryStartingAtValue:value]; - } - } - } - } - - return query; -} - -- (id)getIdValue:(NSString *)value type:(NSString *)type { - if ([type isEqualToString:@"number"]) { - return @(value.doubleValue); - } else if ([type isEqualToString:@"boolean"]) { - return @(value.boolValue); - } else { - return value; - } -} - -- (BOOL)hasEventListener:(NSString *)eventRegistrationKey { - return _listeners[eventRegistrationKey] != nil; -} - -- (BOOL)hasListeners { - return [[_listeners allKeys] count] > 0; -} - -- (int)eventTypeFromName:(NSString *)name { - int eventType = FIRDataEventTypeValue; - - if ([name isEqualToString:DATABASE_VALUE_EVENT]) { - eventType = FIRDataEventTypeValue; - } else if ([name isEqualToString:DATABASE_CHILD_ADDED_EVENT]) { - eventType = FIRDataEventTypeChildAdded; - } else if ([name isEqualToString:DATABASE_CHILD_MODIFIED_EVENT]) { - eventType = FIRDataEventTypeChildChanged; - } else if ([name isEqualToString:DATABASE_CHILD_REMOVED_EVENT]) { - eventType = FIRDataEventTypeChildRemoved; - } else if ([name isEqualToString:DATABASE_CHILD_MOVED_EVENT]) { - eventType = FIRDataEventTypeChildMoved; - } - return eventType; -} - -#endif - -@end - diff --git a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h deleted file mode 100644 index 15025488..00000000 --- a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef RNFirebaseCrashlytics_h -#define RNFirebaseCrashlytics_h -#import - - #if __has_include() - #define HAS_CRASHLYTICS 1 - #else - #if __has_include() - #define HAS_CRASHLYTICS 2 - #endif - #endif - - #ifdef HAS_CRASHLYTICS - #import - - @interface RNFirebaseCrashlytics : NSObject { - - } - - @end - #else - @interface RNFirebaseCrashlytics : NSObject - @end - #endif - -#endif diff --git a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m b/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m deleted file mode 100644 index 2cbbb011..00000000 --- a/ios/RNFirebase/fabric/crashlytics/RNFirebaseCrashlytics.m +++ /dev/null @@ -1,64 +0,0 @@ -#import "RNFirebaseCrashlytics.h" - -#if __has_include() - #define HAS_CRASHLYTICS 1 - #import -#else - #if __has_include() - #define HAS_CRASHLYTICS 2 - #import - #endif -#endif - -#if __has_include() - #import -#endif - -#ifdef HAS_CRASHLYTICS - @implementation RNFirebaseCrashlytics - RCT_EXPORT_MODULE(); - - RCT_EXPORT_METHOD(crash) { - [[Crashlytics sharedInstance] crash]; - } - - RCT_EXPORT_METHOD(log:(NSString *)message) { - CLS_LOG(@"%@", message); - } - - RCT_EXPORT_METHOD(recordError:(nonnull NSNumber *)code domain:(NSString *)domain) { - NSError *error = [NSError errorWithDomain:domain code:[code integerValue] userInfo:nil]; - [CrashlyticsKit recordError:error]; - } - - RCT_EXPORT_METHOD(setBoolValue:(NSString *)key boolValue:(BOOL *)boolValue) { - [CrashlyticsKit setBoolValue:boolValue forKey:key]; - } - - RCT_EXPORT_METHOD(setFloatValue:(NSString *)key floatValue:(nonnull NSNumber *)floatValue) { - [CrashlyticsKit setFloatValue:[floatValue floatValue] forKey:key]; - } - - RCT_EXPORT_METHOD(setIntValue:(NSString *)key intValue:(nonnull NSNumber *)intValue) { - [CrashlyticsKit setIntValue:[intValue integerValue] forKey:key]; - } - - RCT_EXPORT_METHOD(setStringValue:(NSString *)key stringValue:(NSString *)stringValue) { - [CrashlyticsKit setObjectValue:stringValue forKey:key]; - } - - RCT_EXPORT_METHOD(setUserIdentifier:(NSString *)userId) { - [CrashlyticsKit setUserIdentifier:userId]; - } - - RCT_EXPORT_METHOD(enableCrashlyticsCollection) { -#if __has_include() - [Fabric with:@[[Crashlytics class]]]; -#endif - } - - @end -#else - @implementation RNFirebaseCrashlytics - @end -#endif diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestore.h b/ios/RNFirebase/firestore/RNFirebaseFirestore.h deleted file mode 100644 index bf54479a..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestore.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RNFirebaseFirestore_h -#define RNFirebaseFirestore_h - -#import - -#if __has_include() - -#import -#import -#import - -@interface RNFirebaseFirestore : RCTEventEmitter {} -@property NSMutableDictionary *transactions; - -+ (void)promiseRejectException:(RCTPromiseRejectBlock)reject error:(NSError *)error; - -+ (FIRFirestore *)getFirestoreForApp:(NSString *)appDisplayName; -+ (NSDictionary *)getJSError:(NSError *)nativeError; - -@end - -#else -@interface RNFirebaseFirestore : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestore.m b/ios/RNFirebase/firestore/RNFirebaseFirestore.m deleted file mode 100644 index e2689d0e..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestore.m +++ /dev/null @@ -1,538 +0,0 @@ -#import "RNFirebaseFirestore.h" - -#if __has_include() - -#import -#import "RNFirebaseEvents.h" -#import "RNFirebaseFirestoreCollectionReference.h" -#import "RNFirebaseFirestoreDocumentReference.h" - -@implementation RNFirebaseFirestore -RCT_EXPORT_MODULE(); - -static dispatch_queue_t firestoreQueue; -static NSMutableDictionary* initialisedApps; - -// Run on a different thread -- (dispatch_queue_t)methodQueue { - if (!firestoreQueue) { - firestoreQueue = dispatch_queue_create("io.invertase.react-native-firebase.firestore", DISPATCH_QUEUE_SERIAL); - } - return firestoreQueue; -} - -- (id)init { - self = [super init]; - if (self != nil) { - initialisedApps = [[NSMutableDictionary alloc] init]; - _transactions = [[NSMutableDictionary alloc] init]; - } - return self; -} - -/** - * TRANSACTIONS - */ -RCT_EXPORT_METHOD(transactionGetDocument:(NSString *)appDisplayName - transactionId:(nonnull NSNumber *)transactionId - path:(NSString *)path - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - @synchronized (self->_transactions[[transactionId stringValue]]) { - __block NSMutableDictionary *transactionState = self->_transactions[[transactionId stringValue]]; - - if (!transactionState) { - DLog(@"transactionGetDocument called for non-existant transactionId %@", transactionId); - return; - } - - NSError *error = nil; - FIRTransaction *transaction = [transactionState valueForKey:@"transaction"]; - FIRDocumentReference *ref = [self getDocumentForAppPath:appDisplayName path:path].ref; - FIRDocumentSnapshot *snapshot = [transaction getDocument:ref error:&error]; - - if (error != nil) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - NSDictionary *snapshotDict = [RNFirebaseFirestoreDocumentReference snapshotToDictionary:snapshot]; - NSString *path = snapshotDict[@"path"]; - - if (path == nil) { - [snapshotDict setValue:ref.path forKey:@"path"]; - } - - resolve(snapshotDict); - } - } -} - -RCT_EXPORT_METHOD(transactionDispose:(NSString *)appDisplayName - transactionId:(nonnull NSNumber *)transactionId) { - @synchronized (self->_transactions[[transactionId stringValue]]) { - __block NSMutableDictionary *transactionState = self->_transactions[[transactionId stringValue]]; - - if (!transactionState) { - DLog(@"transactionGetDocument called for non-existant transactionId %@", transactionId); - return; - } - - dispatch_semaphore_t semaphore = [transactionState valueForKey:@"semaphore"]; - [transactionState setValue:@true forKey:@"abort"]; - dispatch_semaphore_signal(semaphore); - } -} - -RCT_EXPORT_METHOD(transactionApplyBuffer:(NSString *)appDisplayName - transactionId:(nonnull NSNumber *)transactionId - commandBuffer:(NSArray *)commandBuffer) { - @synchronized (self->_transactions[[transactionId stringValue]]) { - __block NSMutableDictionary *transactionState = self->_transactions[[transactionId stringValue]]; - - if (!transactionState) { - DLog(@"transactionGetDocument called for non-existant transactionId %@", transactionId); - return; - } - - dispatch_semaphore_t semaphore = [transactionState valueForKey:@"semaphore"]; - [transactionState setValue:commandBuffer forKey:@"commandBuffer"]; - dispatch_semaphore_signal(semaphore); - } -} - -RCT_EXPORT_METHOD(transactionBegin:(NSString *)appDisplayName - transactionId:(nonnull NSNumber *)transactionId) { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appDisplayName]; - __block BOOL aborted = false; - __block BOOL completed = false; - __block NSMutableDictionary *transactionState = [NSMutableDictionary new]; - - [firestore runTransactionWithBlock:^id (FIRTransaction *transaction, NSError * *errorPointer) { - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - - @synchronized (transactionState) { - transactionState[@"semaphore"] = semaphore; - transactionState[@"transaction"] = transaction; - - if (!self->_transactions[[transactionId stringValue]]) { - [self->_transactions setValue:transactionState forKey:[transactionId stringValue]]; - } - - // Build and send transaction update event - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSMutableDictionary *eventMap = [NSMutableDictionary new]; - eventMap[@"type"] = @"update"; - eventMap[@"id"] = transactionId; - eventMap[@"appName"] = appDisplayName; - [RNFirebaseUtil sendJSEvent:self name:FIRESTORE_TRANSACTION_EVENT body:eventMap]; - }); - } - - // wait for the js event handler to call transactionApplyBuffer - // this wait occurs on the RNFirestore Worker Queue so if transactionApplyBuffer fails to - // signal the semaphore then no further blocks will be executed by RNFirestore until the timeout expires - dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 5000 * NSEC_PER_SEC); - BOOL timedOut = dispatch_semaphore_wait(semaphore, delayTime) != 0; - - @synchronized (transactionState) { - aborted = [transactionState valueForKey:@"abort"]; - - if (transactionState[@"semaphore"] != semaphore) { - return nil; - } - - if (aborted == YES) { - *errorPointer = [NSError errorWithDomain:FIRFirestoreErrorDomain code:FIRFirestoreErrorCodeAborted userInfo:@{}]; - return nil; - } - - if (timedOut == YES) { - *errorPointer = [NSError errorWithDomain:FIRFirestoreErrorDomain code:FIRFirestoreErrorCodeDeadlineExceeded userInfo:@{}]; - return nil; - } - - if (completed == YES) { - return nil; - } - - NSArray *commandBuffer = [transactionState valueForKey:@"commandBuffer"]; - - for (NSDictionary *command in commandBuffer) { - NSString *type = command[@"type"]; - NSString *path = command[@"path"]; - NSDictionary *data = [RNFirebaseFirestoreDocumentReference parseJSMap:firestore jsMap:command[@"data"]]; - - FIRDocumentReference *ref = [firestore documentWithPath:path]; - - if ([type isEqualToString:@"delete"]) { - [transaction deleteDocument:ref]; - } else if ([type isEqualToString:@"set"]) { - NSDictionary *options = command[@"options"]; - if (options && options[@"merge"]) { - [transaction setData:data forDocument:ref merge:true]; - } else { - [transaction setData:data forDocument:ref]; - } - } else if ([type isEqualToString:@"update"]) { - [transaction updateData:data forDocument:ref]; - } - } - - return nil; - } - } completion:^(id result, NSError *error) { - if (completed == YES) return; - completed = YES; - - @synchronized (transactionState) { - if (aborted == NO) { - NSMutableDictionary *eventMap = [NSMutableDictionary new]; - eventMap[@"id"] = transactionId; - eventMap[@"appName"] = appDisplayName; - - if (error != nil) { - eventMap[@"type"] = @"error"; - eventMap[@"error"] = [RNFirebaseFirestore getJSError:error]; - } else { - eventMap[@"type"] = @"complete"; - } - - [RNFirebaseUtil sendJSEvent:self name:FIRESTORE_TRANSACTION_EVENT body:eventMap]; - } - - [self->_transactions removeObjectForKey:[transactionId stringValue]]; - } - - }]; -} - -/** - * TRANSACTIONS END - */ - -RCT_EXPORT_METHOD(disableNetwork:(NSString *)appDisplayName - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appDisplayName]; - [firestore disableNetworkWithCompletion:^(NSError * _Nullable error) { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - resolve(nil); - } - }]; -} - -RCT_EXPORT_METHOD(setLogLevel:(NSString *)logLevel) { - if ([@"debug" isEqualToString:logLevel] || [@"error" isEqualToString:logLevel]) { - [FIRFirestore enableLogging:true]; - } else { - [FIRFirestore enableLogging:false]; - } -} - -RCT_EXPORT_METHOD(enableNetwork:(NSString *)appDisplayName - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appDisplayName]; - [firestore enableNetworkWithCompletion:^(NSError * _Nullable error) { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - resolve(nil); - } - }]; -} - -RCT_EXPORT_METHOD(collectionGet:(NSString *)appDisplayName - path:(NSString *)path - filters:(NSArray *)filters - orders:(NSArray *)orders - options:(NSDictionary *)options - getOptions:(NSDictionary *)getOptions - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getCollectionForAppPath:appDisplayName path:path filters:filters orders:orders options:options] get:getOptions resolver:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(collectionOffSnapshot:(NSString *)appDisplayName - path:(NSString *)path - filters:(NSArray *)filters - orders:(NSArray *)orders - options:(NSDictionary *)options - listenerId:(nonnull NSString *)listenerId) { - [RNFirebaseFirestoreCollectionReference offSnapshot:listenerId]; -} - -RCT_EXPORT_METHOD(collectionOnSnapshot:(NSString *)appDisplayName - path:(NSString *)path - filters:(NSArray *)filters - orders:(NSArray *)orders - options:(NSDictionary *)options - listenerId:(nonnull NSString *)listenerId - queryListenOptions:(NSDictionary *)queryListenOptions) { - RNFirebaseFirestoreCollectionReference *ref = [self getCollectionForAppPath:appDisplayName path:path filters:filters orders:orders options:options]; - [ref onSnapshot:listenerId queryListenOptions:queryListenOptions]; -} - -RCT_EXPORT_METHOD(documentBatch:(NSString *)appDisplayName - writes:(NSArray *)writes - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appDisplayName]; - FIRWriteBatch *batch = [firestore batch]; - - for (NSDictionary *write in writes) { - NSString *type = write[@"type"]; - NSString *path = write[@"path"]; - NSDictionary *data = [RNFirebaseFirestoreDocumentReference parseJSMap:firestore jsMap:write[@"data"]]; - - FIRDocumentReference *ref = [firestore documentWithPath:path]; - - if ([type isEqualToString:@"DELETE"]) { - batch = [batch deleteDocument:ref]; - } else if ([type isEqualToString:@"SET"]) { - NSDictionary *options = write[@"options"]; - if (options && options[@"merge"]) { - batch = [batch setData:data forDocument:ref merge:true]; - } else { - batch = [batch setData:data forDocument:ref]; - } - } else if ([type isEqualToString:@"UPDATE"]) { - batch = [batch updateData:data forDocument:ref]; - } - } - - [batch commitWithCompletion:^(NSError *_Nullable error) { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - resolve(nil); - } - }]; -} - -RCT_EXPORT_METHOD(documentDelete:(NSString *)appDisplayName - path:(NSString *)path - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getDocumentForAppPath:appDisplayName path:path] delete:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(documentGet:(NSString *)appDisplayName - path:(NSString *)path - getOptions:(NSDictionary *)getOptions - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getDocumentForAppPath:appDisplayName path:path] get:getOptions resolver:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(documentOffSnapshot:(NSString *)appDisplayName - path:(NSString *)path - listenerId:(nonnull NSString *)listenerId) { - [RNFirebaseFirestoreDocumentReference offSnapshot:listenerId]; -} - -RCT_EXPORT_METHOD(documentOnSnapshot:(NSString *)appDisplayName - path:(NSString *)path - listenerId:(nonnull NSString *)listenerId - docListenOptions:(NSDictionary *)docListenOptions) { - RNFirebaseFirestoreDocumentReference *ref = [self getDocumentForAppPath:appDisplayName path:path]; - [ref onSnapshot:listenerId docListenOptions:docListenOptions]; -} - -RCT_EXPORT_METHOD(documentSet:(NSString *)appDisplayName - path:(NSString *)path - data:(NSDictionary *)data - options:(NSDictionary *)options - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getDocumentForAppPath:appDisplayName path:path] set:data options:options resolver:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(documentUpdate:(NSString *)appDisplayName - path:(NSString *)path - data:(NSDictionary *)data - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getDocumentForAppPath:appDisplayName path:path] update:data resolver:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(settings:(NSString *)appDisplayName - settings:(NSDictionary *)settings - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appDisplayName]; - FIRFirestoreSettings *firestoreSettings = [[FIRFirestoreSettings alloc] init]; - - // Make sure the dispatch queue is set correctly - firestoreSettings.dispatchQueue = firestoreQueue; - - // Apply the settings passed by the user, or ensure that the current settings are preserved - if (settings[@"host"]) { - firestoreSettings.host = settings[@"host"]; - } else { - firestoreSettings.host = firestore.settings.host; - } - if (settings[@"persistence"]) { - firestoreSettings.persistenceEnabled = settings[@"persistence"]; - } else { - firestoreSettings.persistenceEnabled = firestore.settings.persistenceEnabled; - } - if (settings[@"ssl"]) { - firestoreSettings.sslEnabled = settings[@"ssl"]; - } else { - firestoreSettings.sslEnabled = firestore.settings.sslEnabled; - } - if (settings[@"timestampsInSnapshots"]) { - // TODO: Enable when available on Android - // firestoreSettings.timestampsInSnapshotsEnabled = settings[@"timestampsInSnapshots"]; - } - - [firestore setSettings:firestoreSettings]; - resolve(nil); -} - -/* - * INTERNALS/UTILS - */ -+ (void)promiseRejectException:(RCTPromiseRejectBlock)reject error:(NSError *)error { - NSDictionary *jsError = [RNFirebaseFirestore getJSError:error]; - reject([jsError valueForKey:@"code"], [jsError valueForKey:@"message"], error); -} - -+ (FIRFirestore *)getFirestoreForApp:(NSString *)appDisplayName { - FIRApp *app = [RNFirebaseUtil getApp:appDisplayName]; - FIRFirestore *firestore = [FIRFirestore firestoreForApp:app]; - - // This is the first time we've tried to do something on this Firestore instance - // So we need to make sure the dispatch queue is set correctly - if (!initialisedApps[appDisplayName]) { - initialisedApps[appDisplayName] = @(true); - FIRFirestoreSettings *firestoreSettings = [[FIRFirestoreSettings alloc] init]; - firestoreSettings.dispatchQueue = firestoreQueue; - [firestore setSettings:firestoreSettings]; - } - return firestore; -} - -- (RNFirebaseFirestoreCollectionReference *)getCollectionForAppPath:(NSString *)appDisplayName path:(NSString *)path filters:(NSArray *)filters orders:(NSArray *)orders options:(NSDictionary *)options { - return [[RNFirebaseFirestoreCollectionReference alloc] initWithPathAndModifiers:self appDisplayName:appDisplayName path:path filters:filters orders:orders options:options]; -} - -- (RNFirebaseFirestoreDocumentReference *)getDocumentForAppPath:(NSString *)appDisplayName path:(NSString *)path { - return [[RNFirebaseFirestoreDocumentReference alloc] initWithPath:self appDisplayName:appDisplayName path:path]; -} - -// TODO: Move to error util for use in other modules -+ (NSString *)getMessageWithService:(NSString *)message service:(NSString *)service fullCode:(NSString *)fullCode { - return [NSString stringWithFormat:@"%@: %@ (%@).", service, message, [fullCode lowercaseString]]; -} - -+ (NSString *)getCodeWithService:(NSString *)service code:(NSString *)code { - return [NSString stringWithFormat:@"%@/%@", [service lowercaseString], [code lowercaseString]]; -} - -+ (NSDictionary *)getJSError:(NSError *)nativeError { - NSMutableDictionary *errorMap = [[NSMutableDictionary alloc] init]; - [errorMap setValue:@(nativeError.code) forKey:@"nativeErrorCode"]; - [errorMap setValue:[nativeError localizedDescription] forKey:@"nativeErrorMessage"]; - - NSString *code; - NSString *message; - NSString *service = @"Firestore"; - - switch (nativeError.code) { - case FIRFirestoreErrorCodeOK: - code = [RNFirebaseFirestore getCodeWithService:service code:@"ok"]; - message = [RNFirebaseFirestore getMessageWithService:@"Ok." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeCancelled: - code = [RNFirebaseFirestore getCodeWithService:service code:@"cancelled"]; - message = [RNFirebaseFirestore getMessageWithService:@"The operation was cancelled." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeUnknown: - code = [RNFirebaseFirestore getCodeWithService:service code:@"unknown"]; - message = [RNFirebaseFirestore getMessageWithService:@"Unknown error or an error from a different error domain." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeInvalidArgument: - code = [RNFirebaseFirestore getCodeWithService:service code:@"invalid-argument"]; - message = [RNFirebaseFirestore getMessageWithService:@"Client specified an invalid argument." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeDeadlineExceeded: - code = [RNFirebaseFirestore getCodeWithService:service code:@"deadline-exceeded"]; - message = [RNFirebaseFirestore getMessageWithService:@"Deadline expired before operation could complete." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeNotFound: - code = [RNFirebaseFirestore getCodeWithService:service code:@"not-found"]; - message = [RNFirebaseFirestore getMessageWithService:@"Some requested document was not found." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeAlreadyExists: - code = [RNFirebaseFirestore getCodeWithService:service code:@"already-exists"]; - message = [RNFirebaseFirestore getMessageWithService:@"Some document that we attempted to create already exists." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodePermissionDenied: - code = [RNFirebaseFirestore getCodeWithService:service code:@"permission-denied"]; - message = [RNFirebaseFirestore getMessageWithService:@"The caller does not have permission to execute the specified operation." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeResourceExhausted: - code = [RNFirebaseFirestore getCodeWithService:service code:@"resource-exhausted"]; - message = [RNFirebaseFirestore getMessageWithService:@"Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeFailedPrecondition: - code = [RNFirebaseFirestore getCodeWithService:service code:@"failed-precondition"]; - message = [RNFirebaseFirestore getMessageWithService:@"Operation was rejected because the system is not in a state required for the operation`s execution." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeAborted: - code = [RNFirebaseFirestore getCodeWithService:service code:@"aborted"]; - message = [RNFirebaseFirestore getMessageWithService:@"The operation was aborted, typically due to a concurrency issue like transaction aborts, etc." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeOutOfRange: - code = [RNFirebaseFirestore getCodeWithService:service code:@"out-of-range"]; - message = [RNFirebaseFirestore getMessageWithService:@"Operation was attempted past the valid range." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeUnimplemented: - code = [RNFirebaseFirestore getCodeWithService:service code:@"unimplemented"]; - message = [RNFirebaseFirestore getMessageWithService:@"Operation is not implemented or not supported/enabled." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeInternal: - code = [RNFirebaseFirestore getCodeWithService:service code:@"internal"]; - message = [RNFirebaseFirestore getMessageWithService:@"Internal errors." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeUnavailable: - code = [RNFirebaseFirestore getCodeWithService:service code:@"unavailable"]; - message = [RNFirebaseFirestore getMessageWithService:@"The service is currently unavailable." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeDataLoss: - code = [RNFirebaseFirestore getCodeWithService:service code:@"data-loss"]; - message = [RNFirebaseFirestore getMessageWithService:@"Unrecoverable data loss or corruption." service:service fullCode:code]; - break; - case FIRFirestoreErrorCodeUnauthenticated: - code = [RNFirebaseFirestore getCodeWithService:service code:@"unauthenticated"]; - message = [RNFirebaseFirestore getMessageWithService:@"The request does not have valid authentication credentials for the operation." service:service fullCode:code]; - break; - default: - code = [RNFirebaseFirestore getCodeWithService:service code:@"unknown"]; - message = [RNFirebaseFirestore getMessageWithService:@"An unknown error occurred." service:service fullCode:code]; - break; - } - - [errorMap setValue:code forKey:@"code"]; - [errorMap setValue:message forKey:@"message"]; - - return errorMap; -} - -- (NSArray *)supportedEvents { - return @[FIRESTORE_COLLECTION_SYNC_EVENT, FIRESTORE_DOCUMENT_SYNC_EVENT, FIRESTORE_TRANSACTION_EVENT]; -} - -+ (BOOL)requiresMainQueueSetup { - return YES; -} - -@end - -#else -@implementation RNFirebaseFirestore -@end -#endif diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.h b/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.h deleted file mode 100644 index b00742a5..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef RNFirebaseFirestoreCollectionReference_h -#define RNFirebaseFirestoreCollectionReference_h -#import - -#if __has_include() - -#import -#import -#import "RNFirebaseEvents.h" -#import "RNFirebaseFirestore.h" -#import "RNFirebaseFirestoreDocumentReference.h" -#import "RNFirebaseUtil.h" - -@interface RNFirebaseFirestoreCollectionReference : NSObject -@property RCTEventEmitter *emitter; -@property NSString *appDisplayName; -@property NSString *path; -@property NSArray *filters; -@property NSArray *orders; -@property NSDictionary *options; -@property FIRQuery *query; - -- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter appDisplayName:(NSString *)appDisplayName path:(NSString *)path filters:(NSArray *)filters orders:(NSArray *)orders options:(NSDictionary *)options; -- (void)get:(NSDictionary *)getOptions resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -+ (void)offSnapshot:(NSString *)listenerId; -- (void)onSnapshot:(NSString *)listenerId queryListenOptions:(NSDictionary *) queryListenOptions; -+ (NSDictionary *)snapshotToDictionary:(FIRQuerySnapshot *)querySnapshot; -@end - -#else - -@interface RNFirebaseFirestoreCollectionReference : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m b/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m deleted file mode 100644 index 95540bc7..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m +++ /dev/null @@ -1,271 +0,0 @@ -#import "RNFirebaseFirestoreCollectionReference.h" - -@implementation RNFirebaseFirestoreCollectionReference - -#if __has_include() - -static NSMutableDictionary *_listeners; - -- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter - appDisplayName:(NSString *)appDisplayName - path:(NSString *)path - filters:(NSArray *)filters - orders:(NSArray *)orders - options:(NSDictionary *)options { - self = [super init]; - if (self) { - _emitter = emitter; - _appDisplayName = appDisplayName; - _path = path; - _filters = filters; - _orders = orders; - _options = options; - _query = [self buildQuery]; - } - // Initialise the static listeners object if required - if (!_listeners) { - _listeners = [[NSMutableDictionary alloc] init]; - } - return self; -} - -- (void)get:(NSDictionary *)getOptions - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - FIRFirestoreSource source; - if (getOptions && getOptions[@"source"]) { - if ([getOptions[@"source"] isEqualToString:@"server"]) { - source = FIRFirestoreSourceServer; - } else if ([getOptions[@"source"] isEqualToString:@"cache"]) { - source = FIRFirestoreSourceCache; - } else { - source = FIRFirestoreSourceDefault; - } - } else { - source = FIRFirestoreSourceDefault; - } - [_query getDocumentsWithSource:source completion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - NSDictionary *data = [RNFirebaseFirestoreCollectionReference snapshotToDictionary:snapshot]; - resolve(data); - } - }]; -} - -+ (void)offSnapshot:(NSString *)listenerId { - id listener = _listeners[listenerId]; - if (listener) { - [_listeners removeObjectForKey:listenerId]; - [listener remove]; - } -} - -- (void)onSnapshot:(NSString *)listenerId -queryListenOptions:(NSDictionary *)queryListenOptions { - if (_listeners[listenerId] == nil) { - id listenerBlock = ^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error) { - id listener = _listeners[listenerId]; - if (listener) { - [_listeners removeObjectForKey:listenerId]; - [listener remove]; - } - [self handleQuerySnapshotError:listenerId error:error]; - } else { - [self handleQuerySnapshotEvent:listenerId querySnapshot:snapshot]; - } - }; - - bool includeMetadataChanges; - if (queryListenOptions && queryListenOptions[@"includeMetadataChanges"]) { - includeMetadataChanges = true; - } else { - includeMetadataChanges = false; - } - - id - listener = [_query addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges listener:listenerBlock]; - _listeners[listenerId] = listener; - } -} - -- (FIRQuery *)buildQuery { - FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:_appDisplayName]; - FIRQuery *query = (FIRQuery *) [firestore collectionWithPath:_path]; - query = [self applyFilters:firestore query:query]; - query = [self applyOrders:query]; - query = [self applyOptions:firestore query:query]; - - return query; -} - -- (FIRQuery *)applyFilters:(FIRFirestore *)firestore - query:(FIRQuery *)query { - for (NSDictionary *filter in _filters) { - NSDictionary *fieldPathDictionary = filter[@"fieldPath"]; - NSString *fieldPathType = fieldPathDictionary[@"type"]; - NSString *operator = filter[@"operator"]; - NSDictionary *jsValue = filter[@"value"]; - id value = [RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:jsValue]; - - if ([fieldPathType isEqualToString:@"string"]) { - NSString *fieldPath = fieldPathDictionary[@"string"]; - if ([operator isEqualToString:@"EQUAL"]) { - query = [query queryWhereField:fieldPath isEqualTo:value]; - } else if ([operator isEqualToString:@"GREATER_THAN"]) { - query = [query queryWhereField:fieldPath isGreaterThan:value]; - } else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) { - query = [query queryWhereField:fieldPath isGreaterThanOrEqualTo:value]; - } else if ([operator isEqualToString:@"LESS_THAN"]) { - query = [query queryWhereField:fieldPath isLessThan:value]; - } else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) { - query = [query queryWhereField:fieldPath isLessThanOrEqualTo:value]; - } else if ([operator isEqualToString:@"ARRAY_CONTAINS"]) { - query = [query queryWhereField:fieldPath arrayContains:value]; - } - } else { - NSArray *fieldPathElements = fieldPathDictionary[@"elements"]; - FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathElements]; - if ([operator isEqualToString:@"EQUAL"]) { - query = [query queryWhereFieldPath:fieldPath isEqualTo:value]; - } else if ([operator isEqualToString:@"GREATER_THAN"]) { - query = [query queryWhereFieldPath:fieldPath isGreaterThan:value]; - } else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) { - query = [query queryWhereFieldPath:fieldPath isGreaterThanOrEqualTo:value]; - } else if ([operator isEqualToString:@"LESS_THAN"]) { - query = [query queryWhereFieldPath:fieldPath isLessThan:value]; - } else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) { - query = [query queryWhereFieldPath:fieldPath isLessThanOrEqualTo:value]; - } else if ([operator isEqualToString:@"ARRAY_CONTAINS"]) { - query = [query queryWhereFieldPath:fieldPath arrayContains:value]; - } - } - } - - return query; -} - -- (FIRQuery *)applyOrders:(FIRQuery *)query { - for (NSDictionary *order in _orders) { - NSString *direction = order[@"direction"]; - NSDictionary *fieldPathDictionary = order[@"fieldPath"]; - NSString *fieldPathType = fieldPathDictionary[@"type"]; - - if ([fieldPathType isEqualToString:@"string"]) { - NSString *fieldPath = fieldPathDictionary[@"string"]; - query = [query queryOrderedByField:fieldPath descending:([direction isEqualToString:@"DESCENDING"])]; - } else { - NSArray *fieldPathElements = fieldPathDictionary[@"elements"]; - FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathElements]; - query = [query queryOrderedByFieldPath:fieldPath descending:([direction isEqualToString:@"DESCENDING"])]; - } - } - return query; -} - -- (FIRQuery *)applyOptions:(FIRFirestore *)firestore - query:(FIRQuery *)query { - if (_options[@"endAt"]) { - query = - [query queryEndingAtValues:[RNFirebaseFirestoreDocumentReference parseJSArray:firestore jsArray:_options[@"endAt"]]]; - } - if (_options[@"endBefore"]) { - query = - [query queryEndingBeforeValues:[RNFirebaseFirestoreDocumentReference parseJSArray:firestore jsArray:_options[@"endBefore"]]]; - } - if (_options[@"limit"]) { - query = [query queryLimitedTo:[_options[@"limit"] intValue]]; - } - if (_options[@"offset"]) { - // iOS doesn't support offset - } - if (_options[@"selectFields"]) { - // iOS doesn't support selectFields - } - if (_options[@"startAfter"]) { - query = - [query queryStartingAfterValues:[RNFirebaseFirestoreDocumentReference parseJSArray:firestore jsArray:_options[@"startAfter"]]]; - } - if (_options[@"startAt"]) { - query = - [query queryStartingAtValues:[RNFirebaseFirestoreDocumentReference parseJSArray:firestore jsArray:_options[@"startAt"]]]; - } - return query; -} - -- (void)handleQuerySnapshotError:(NSString *)listenerId - error:(NSError *)error { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - [event setValue:_appDisplayName forKey:@"appName"]; - [event setValue:_path forKey:@"path"]; - [event setValue:listenerId forKey:@"listenerId"]; - [event setValue:[RNFirebaseFirestore getJSError:error] forKey:@"error"]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:FIRESTORE_COLLECTION_SYNC_EVENT body:event]; -} - -- (void)handleQuerySnapshotEvent:(NSString *)listenerId - querySnapshot:(FIRQuerySnapshot *)querySnapshot { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - [event setValue:_appDisplayName forKey:@"appName"]; - [event setValue:_path forKey:@"path"]; - [event setValue:listenerId forKey:@"listenerId"]; - [event setValue:[RNFirebaseFirestoreCollectionReference snapshotToDictionary:querySnapshot] forKey:@"querySnapshot"]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:FIRESTORE_COLLECTION_SYNC_EVENT body:event]; -} - -+ (NSDictionary *)snapshotToDictionary:(FIRQuerySnapshot *)querySnapshot { - NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init]; - [snapshot setValue:[self documentChangesToArray:querySnapshot.documentChanges] forKey:@"changes"]; - [snapshot setValue:[self documentSnapshotsToArray:querySnapshot.documents] forKey:@"documents"]; - if (querySnapshot.metadata) { - NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init]; - [metadata setValue:@(querySnapshot.metadata.fromCache) forKey:@"fromCache"]; - [metadata setValue:@(querySnapshot.metadata.hasPendingWrites) forKey:@"hasPendingWrites"]; - [snapshot setValue:metadata forKey:@"metadata"]; - } - - return snapshot; -} - -+ (NSArray *)documentChangesToArray:(NSArray *)documentChanges { - NSMutableArray *changes = [[NSMutableArray alloc] init]; - for (FIRDocumentChange *change in documentChanges) { - [changes addObject:[self documentChangeToDictionary:change]]; - } - - return changes; -} - -+ (NSDictionary *)documentChangeToDictionary:(FIRDocumentChange *)documentChange { - NSMutableDictionary *change = [[NSMutableDictionary alloc] init]; - [change setValue:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:documentChange.document] forKey:@"document"]; - [change setValue:@(documentChange.newIndex) forKey:@"newIndex"]; - [change setValue:@(documentChange.oldIndex) forKey:@"oldIndex"]; - - if (documentChange.type == FIRDocumentChangeTypeAdded) { - [change setValue:@"added" forKey:@"type"]; - } else if (documentChange.type == FIRDocumentChangeTypeRemoved) { - [change setValue:@"removed" forKey:@"type"]; - } else if (documentChange.type == FIRDocumentChangeTypeModified) { - [change setValue:@"modified" forKey:@"type"]; - } - - return change; -} - -+ (NSArray *)documentSnapshotsToArray:(NSArray *)documentSnapshots { - NSMutableArray *snapshots = [[NSMutableArray alloc] init]; - for (FIRDocumentSnapshot *snapshot in documentSnapshots) { - [snapshots addObject:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:snapshot]]; - } - - return snapshots; -} - -#endif - -@end diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h deleted file mode 100644 index 7f4cbc60..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef RNFirebaseFirestoreDocumentReference_h -#define RNFirebaseFirestoreDocumentReference_h - -#import - -#if __has_include() - -#import -#import -#import "RNFirebaseEvents.h" -#import "RNFirebaseFirestore.h" -#import "RNFirebaseUtil.h" - -@interface RNFirebaseFirestoreDocumentReference : NSObject -@property RCTEventEmitter *emitter; -@property NSString *appDisplayName; -@property NSString *path; -@property FIRDocumentReference *ref; - -- (id)initWithPath:(RCTEventEmitter *)emitter appDisplayName:(NSString *)appDisplayName path:(NSString *)path; -- (void)delete:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -- (void)get:(NSDictionary *)getOptions resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -+ (void)offSnapshot:(NSString *)listenerId; -- (void)onSnapshot:(NSString *)listenerId docListenOptions:(NSDictionary *) docListenOptions; -- (void)set:(NSDictionary *)data options:(NSDictionary *)options resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -- (void)update:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot; -+ (NSDictionary *)parseJSMap:(FIRFirestore *) firestore jsMap:(NSDictionary *) jsMap; -+ (NSArray *)parseJSArray:(FIRFirestore *) firestore jsArray:(NSArray *) jsArray; -+ (id)parseJSTypeMap:(FIRFirestore *) firestore jsTypeMap:(NSDictionary *) jsTypeMap; - -@end - -#else - -@interface RNFirebaseFirestoreDocumentReference : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m deleted file mode 100644 index 939b27d5..00000000 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m +++ /dev/null @@ -1,435 +0,0 @@ -#import "RNFirebaseFirestoreDocumentReference.h" - -@implementation RNFirebaseFirestoreDocumentReference - -#if __has_include() - -static NSMutableDictionary *_listeners; -static NSString *const typeKey = @"type"; -static NSString *const keyPath = @"path"; -static NSString *const keyData = @"data"; -static NSString *const keyError = @"error"; -static NSString *const valueKey = @"value"; -static NSString *const keyMerge = @"merge"; -static NSString *const keyAppName = @"appName"; -static NSString *const keyLatitude = @"latitude"; -static NSString *const keyMetadata = @"metadata"; -static NSString *const keyLongitude = @"longitude"; -static NSString *const keyFromCache = @"fromCache"; -static NSString *const keyListenerId = @"listenerId"; -static NSString *const keyDocumentSnapshot = @"documentSnapshot"; -static NSString *const keyHasPendingWrites = @"hasPendingWrites"; -static NSString *const keyIncludeMetaChanges = @"includeMetadataChanges"; - -static NSString *const typeNaN = @"nan"; -static NSString *const typeNull = @"null"; -static NSString *const typeBlob = @"blob"; -static NSString *const typeDate = @"date"; -static NSString *const typeArray = @"array"; -static NSString *const typeObject = @"object"; -static NSString *const typeString = @"string"; -static NSString *const typeNumber = @"number"; -static NSString *const typeDelete = @"delete"; -static NSString *const typeBoolean = @"boolean"; -static NSString *const typeInfinity = @"infinity"; -static NSString *const typeGeoPoint = @"geopoint"; -static NSString *const typeTimestamp = @"timestamp"; -static NSString *const typeReference = @"reference"; -static NSString *const typeDocumentId = @"documentid"; -static NSString *const typeFieldValue = @"fieldvalue"; -static NSString *const typeFieldValueUnion = @"union"; -static NSString *const typeFieldValueRemove = @"remove"; -static NSString *const typeFieldValueType = @"type"; -static NSString *const typeFieldValueElements = @"elements"; - -- (id)initWithPath:(RCTEventEmitter *)emitter - appDisplayName:(NSString *)appDisplayName - path:(NSString *)path { - self = [super init]; - - if (self) { - _emitter = emitter; - _appDisplayName = appDisplayName; - _path = path; - _ref = [[RNFirebaseFirestore getFirestoreForApp:_appDisplayName] documentWithPath:_path]; - } - - // Initialise the static listeners object if required - if (!_listeners) { - _listeners = [[NSMutableDictionary alloc] init]; - } - - return self; -} - -- (void)delete:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - [_ref deleteDocumentWithCompletion:^(NSError *_Nullable error) { - [RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject]; - }]; -} - -- (void)get:(NSDictionary *)getOptions - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - FIRFirestoreSource source; - if (getOptions && getOptions[@"source"]) { - if ([getOptions[@"source"] isEqualToString:@"server"]) { - source = FIRFirestoreSourceServer; - } else if ([getOptions[@"source"] isEqualToString:@"cache"]) { - source = FIRFirestoreSourceCache; - } else { - source = FIRFirestoreSourceDefault; - } - } else { - source = FIRFirestoreSourceDefault; - } - [_ref getDocumentWithSource:source completion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - NSDictionary *data = [RNFirebaseFirestoreDocumentReference snapshotToDictionary:snapshot]; - resolve(data); - } - }]; -} - -+ (void)offSnapshot:(NSString *)listenerId { - id listener = _listeners[listenerId]; - if (listener) { - [_listeners removeObjectForKey:listenerId]; - [listener remove]; - } -} - -- (void)onSnapshot:(NSString *)listenerId - docListenOptions:(NSDictionary *)docListenOptions { - if (_listeners[listenerId] == nil) { - id listenerBlock = ^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error) { - id listener = _listeners[listenerId]; - if (listener) { - [_listeners removeObjectForKey:listenerId]; - [listener remove]; - } - [self handleDocumentSnapshotError:listenerId error:error]; - } else { - [self handleDocumentSnapshotEvent:listenerId documentSnapshot:snapshot]; - } - }; - bool includeMetadataChanges; - if (docListenOptions && docListenOptions[keyIncludeMetaChanges]) { - includeMetadataChanges = true; - } else { - includeMetadataChanges = false; - } - id - listener = [_ref addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges listener:listenerBlock]; - _listeners[listenerId] = listener; - } -} - -- (void)set:(NSDictionary *)data - options:(NSDictionary *)options - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - NSDictionary *dictionary = - [RNFirebaseFirestoreDocumentReference parseJSMap:[RNFirebaseFirestore getFirestoreForApp:_appDisplayName] jsMap:data]; - if (options && options[keyMerge]) { - [_ref setData:dictionary merge:true completion:^(NSError *_Nullable error) { - [RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject]; - }]; - } else { - [_ref setData:dictionary completion:^(NSError *_Nullable error) { - [RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject]; - }]; - } -} - -- (void)update:(NSDictionary *)data - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - NSDictionary *dictionary = - [RNFirebaseFirestoreDocumentReference parseJSMap:[RNFirebaseFirestore getFirestoreForApp:_appDisplayName] jsMap:data]; - [_ref updateData:dictionary completion:^(NSError *_Nullable error) { - [RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject]; - }]; -} - -+ (void)handleWriteResponse:(NSError *)error - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject { - if (error) { - [RNFirebaseFirestore promiseRejectException:reject error:error]; - } else { - resolve(nil); - } -} - -+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot { - NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init]; - [snapshot setValue:documentSnapshot.reference.path forKey:keyPath]; - if (documentSnapshot.exists) { - [snapshot setValue:[RNFirebaseFirestoreDocumentReference buildNativeMap:documentSnapshot.data] forKey:keyData]; - } - if (documentSnapshot.metadata) { - NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init]; - [metadata setValue:@(documentSnapshot.metadata.fromCache) forKey:keyFromCache]; - [metadata setValue:@(documentSnapshot.metadata.hasPendingWrites) forKey:keyHasPendingWrites]; - [snapshot setValue:metadata forKey:keyMetadata]; - } - return snapshot; -} - -- (void)handleDocumentSnapshotError:(NSString *)listenerId - error:(NSError *)error { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - [event setValue:_path forKey:keyPath]; - [event setValue:listenerId forKey:keyListenerId]; - [event setValue:_appDisplayName forKey:keyAppName]; - [event setValue:[RNFirebaseFirestore getJSError:error] forKey:keyError]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:FIRESTORE_DOCUMENT_SYNC_EVENT body:event]; -} - -- (void)handleDocumentSnapshotEvent:(NSString *)listenerId - documentSnapshot:(FIRDocumentSnapshot *)documentSnapshot { - NSMutableDictionary *event = [[NSMutableDictionary alloc] init]; - [event setValue:_path forKey:keyPath]; - [event setValue:listenerId forKey:keyListenerId]; - [event setValue:_appDisplayName forKey:keyAppName]; - [event setValue:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:documentSnapshot] forKey:keyDocumentSnapshot]; - - [RNFirebaseUtil sendJSEvent:self.emitter name:FIRESTORE_DOCUMENT_SYNC_EVENT body:event]; -} - -+ (NSDictionary *)buildNativeMap:(NSDictionary *)nativeMap { - NSMutableDictionary *map = [[NSMutableDictionary alloc] init]; - [nativeMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) { - NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj]; - map[key] = typeMap; - }]; - - return map; -} - -+ (NSArray *)buildNativeArray:(NSArray *)nativeArray { - NSMutableArray *array = [[NSMutableArray alloc] init]; - [nativeArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj]; - [array addObject:typeMap]; - }]; - - return array; -} - -+ (NSDictionary *)buildTypeMap:(id)value { - NSMutableDictionary *typeMap = [[NSMutableDictionary alloc] init]; - - // null - if (value == nil || [value isKindOfClass:[NSNull class]]) { - typeMap[typeKey] = typeNull; - return typeMap; - } - - // strings - if ([value isKindOfClass:[NSString class]]) { - typeMap[typeKey] = typeString; - typeMap[valueKey] = value; - return typeMap; - } - - // objects - if ([value isKindOfClass:[NSDictionary class]]) { - typeMap[typeKey] = typeObject; - typeMap[valueKey] = [RNFirebaseFirestoreDocumentReference buildNativeMap:value]; - return typeMap; - } - - // array - if ([value isKindOfClass:[NSArray class]]) { - typeMap[typeKey] = typeArray; - typeMap[valueKey] = [RNFirebaseFirestoreDocumentReference buildNativeArray:value]; - return typeMap; - } - - // reference - if ([value isKindOfClass:[FIRDocumentReference class]]) { - typeMap[typeKey] = typeReference; - FIRDocumentReference *ref = (FIRDocumentReference *) value; - typeMap[valueKey] = [ref path]; - return typeMap; - } - - // geopoint - if ([value isKindOfClass:[FIRGeoPoint class]]) { - typeMap[typeKey] = typeGeoPoint; - FIRGeoPoint *point = (FIRGeoPoint *) value; - NSMutableDictionary *geopoint = [[NSMutableDictionary alloc] init]; - geopoint[keyLatitude] = @([point latitude]); - geopoint[keyLongitude] = @([point longitude]); - typeMap[valueKey] = geopoint; - return typeMap; - } - - // date - if ([value isKindOfClass:[NSDate class]]) { - typeMap[typeKey] = typeDate; - // round is required otherwise iOS ends up with .999 and loses a millisecond - // when going between native and JS - typeMap[valueKey] = @(round([(NSDate *) value timeIntervalSince1970] * 1000.0)); - return typeMap; - } - - // number / boolean / infinity / nan - if ([value isKindOfClass:[NSNumber class]]) { - NSNumber *number = (NSNumber *) value; - - // infinity - if ([number isEqual:@(INFINITY)]) { - typeMap[typeKey] = typeInfinity; - return typeMap; - } - - // boolean - if (number == [NSValue valueWithPointer:(void *) kCFBooleanFalse] - || number == [NSValue valueWithPointer:(void *) kCFBooleanTrue]) { - typeMap[typeKey] = typeBoolean; - typeMap[valueKey] = value; - return typeMap; - } - - // nan - if ([[value description].lowercaseString isEqual:@"nan"]) { - typeMap[typeKey] = typeNaN; - return typeMap; - } - - // number - typeMap[typeKey] = typeNumber; - typeMap[valueKey] = value; - return typeMap; - } - - // blobs (converted to base64) - if ([value isKindOfClass:[NSData class]]) { - NSData *blob = (NSData *) value; - typeMap[typeKey] = typeBlob; - typeMap[valueKey] = [blob base64EncodedStringWithOptions:0]; - return typeMap; - } - - DLog(@"RNFirebaseFirestore: Unsupported value sent to buildTypeMap - class type is %@", - NSStringFromClass([value class])); - - typeMap[typeKey] = typeNull; - return typeMap; -} - -+ (NSDictionary *)parseJSMap:(FIRFirestore *)firestore - jsMap:(NSDictionary *)jsMap { - NSMutableDictionary *map = [[NSMutableDictionary alloc] init]; - - if (jsMap) { - [jsMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) { - map[key] = [RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:obj]; - }]; - } - - return map; -} - -+ (NSArray *)parseJSArray:(FIRFirestore *)firestore - jsArray:(NSArray *)jsArray { - NSMutableArray *array = [[NSMutableArray alloc] init]; - - if (jsArray) { - [jsArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [array addObject:[RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:obj]]; - }]; - } - - return array; -} - -+ (id)parseJSTypeMap:(FIRFirestore *)firestore - jsTypeMap:(NSDictionary *)jsTypeMap { - id value = jsTypeMap[valueKey]; - NSString *type = jsTypeMap[typeKey]; - - if ([type isEqualToString:typeArray]) { - return [self parseJSArray:firestore jsArray:value]; - } - - if ([type isEqualToString:typeObject]) { - return [self parseJSMap:firestore jsMap:value]; - } - - if ([type isEqualToString:typeReference]) { - return [firestore documentWithPath:value]; - } - - if ([type isEqualToString:typeBlob]) { - return [[NSData alloc] initWithBase64EncodedString:(NSString *) value options:0]; - } - - if ([type isEqualToString:typeGeoPoint]) { - NSDictionary *geopoint = (NSDictionary *) value; - NSNumber *latitude = geopoint[keyLatitude]; - NSNumber *longitude = geopoint[keyLongitude]; - return [[FIRGeoPoint alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]]; - } - - if ([type isEqualToString:typeDate]) { - return [NSDate dateWithTimeIntervalSince1970:([(NSNumber *) value doubleValue] / 1000.0)]; - } - - if ([type isEqualToString:typeDocumentId]) { - return [FIRFieldPath documentID]; - } - - if ([type isEqualToString:typeFieldValue]) { - NSDictionary *fieldValueMap = (NSDictionary *) value; - NSString *string = (NSString *) fieldValueMap[typeFieldValueType]; - - if ([string isEqualToString:typeDelete]) { - return [FIRFieldValue fieldValueForDelete]; - } - - if ([string isEqualToString:typeTimestamp]) { - return [FIRFieldValue fieldValueForServerTimestamp]; - } - - if ([string isEqualToString:typeFieldValueUnion]) { - NSArray *elements = [self parseJSArray:firestore jsArray:value[typeFieldValueElements]]; - return [FIRFieldValue fieldValueForArrayUnion:elements]; - } - - if ([string isEqualToString:typeFieldValueRemove]) { - NSArray *elements = [self parseJSArray:firestore jsArray:value[typeFieldValueElements]]; - return [FIRFieldValue fieldValueForArrayRemove:elements]; - } - - DLog(@"RNFirebaseFirestore: Unsupported field-value sent to parseJSTypeMap - value is %@", NSStringFromClass([value class])); - return nil; - } - - if ([type isEqualToString:typeInfinity]) { - return @(INFINITY); - } - - if ([type isEqualToString:typeNaN]) { - return [NSDecimalNumber notANumber]; - } - - if ([type isEqualToString:typeBoolean] || [type isEqualToString:typeNumber] || [type isEqualToString:typeString] - || [type isEqualToString:typeNull]) { - return value; - } - - return nil; -} - -#endif - -@end diff --git a/ios/RNFirebase/functions/RNFirebaseFunctions.h b/ios/RNFirebase/functions/RNFirebaseFunctions.h deleted file mode 100644 index 8190850c..00000000 --- a/ios/RNFirebase/functions/RNFirebaseFunctions.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef RNFirebaseFunctions_h -#define RNFirebaseFunctions_h -#import - -#if __has_include() -#import - -@interface RNFirebaseFunctions : NSObject { - -} - -@end - -#else -@interface RNFirebaseFunctions : NSObject -@end -#endif - -#endif - diff --git a/ios/RNFirebase/functions/RNFirebaseFunctions.m b/ios/RNFirebase/functions/RNFirebaseFunctions.m deleted file mode 100644 index ef5eba76..00000000 --- a/ios/RNFirebase/functions/RNFirebaseFunctions.m +++ /dev/null @@ -1,141 +0,0 @@ -#import "RNFirebaseFunctions.h" -#import "RNFirebaseUtil.h" - -#if __has_include() -#import -#import -#import - -@implementation RNFirebaseFunctions -RCT_EXPORT_MODULE(); - -RCT_EXPORT_METHOD(httpsCallable: - (NSString *) appName - region: - (NSString *) region - name: - (NSString *) name - wrapper: - (NSDictionary *) wrapper - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject - ){ - FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName]; - FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region]; - - FIRHTTPSCallable *callable = [functions HTTPSCallableWithName:name]; - - [callable - callWithObject:[wrapper valueForKey:@"data"] - completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) { - if (error) { - NSObject *details = [NSNull null]; - NSString *message = error.localizedDescription; - - if (error.domain == FIRFunctionsErrorDomain) { - details = error.userInfo[FIRFunctionsErrorDetailsKey]; - if (details == nil) { - details = [NSNull null]; - } - } - - resolve(@{ - @"__error": @true, - @"code": [self getErrorCodeName:error], - @"message": message, - @"details": details - }); - } else { - resolve(@{ @"data": [result data] }); - } - }]; -} - -RCT_EXPORT_METHOD(useFunctionsEmulator: - (NSString *) appName - region: - (NSString *) region - origin: - (NSString *) origin - resolver: - (RCTPromiseResolveBlock) resolve - rejecter: - (RCTPromiseRejectBlock) reject - ){ - FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName]; - FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region]; - [functions useFunctionsEmulatorOrigin:origin]; - resolve([NSNull null]); -} - -- (NSString *)getErrorCodeName:(NSError *)error { - NSString *code = @"UNKNOWN"; - switch (error.code) { - case FIRFunctionsErrorCodeOK: - code = @"OK"; - break; - case FIRFunctionsErrorCodeCancelled: - code = @"CANCELLED"; - break; - case FIRFunctionsErrorCodeUnknown: - code = @"UNKNOWN"; - break; - case FIRFunctionsErrorCodeInvalidArgument: - code = @"INVALID_ARGUMENT"; - break; - case FIRFunctionsErrorCodeDeadlineExceeded: - code = @"DEADLINE_EXCEEDED"; - break; - case FIRFunctionsErrorCodeNotFound: - code = @"NOT_FOUND"; - break; - case FIRFunctionsErrorCodeAlreadyExists: - code = @"ALREADY_EXISTS"; - break; - case FIRFunctionsErrorCodePermissionDenied: - code = @"PERMISSION_DENIED"; - break; - case FIRFunctionsErrorCodeResourceExhausted: - code = @"RESOURCE_EXHAUSTED"; - break; - case FIRFunctionsErrorCodeFailedPrecondition: - code = @"FAILED_PRECONDITION"; - break; - case FIRFunctionsErrorCodeAborted: - code = @"ABORTED"; - break; - case FIRFunctionsErrorCodeOutOfRange: - code = @"OUT_OF_RANGE"; - break; - case FIRFunctionsErrorCodeUnimplemented: - code = @"UNIMPLEMENTED"; - break; - case FIRFunctionsErrorCodeInternal: - code = @"INTERNAL"; - break; - case FIRFunctionsErrorCodeUnavailable: - code = @"UNAVAILABLE"; - break; - case FIRFunctionsErrorCodeDataLoss: - code = @"DATA_LOSS"; - break; - case FIRFunctionsErrorCodeUnauthenticated: - code = @"UNAUTHENTICATED"; - break; - default: - break; - } - - return code; -} - - -@end - -#else -@implementation RNFirebaseFunctions -@end -#endif - diff --git a/ios/RNFirebase/instanceid/RNFirebaseInstanceId.h b/ios/RNFirebase/instanceid/RNFirebaseInstanceId.h deleted file mode 100644 index e90f72b9..00000000 --- a/ios/RNFirebase/instanceid/RNFirebaseInstanceId.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RNFirebaseInstanceId_h -#define RNFirebaseInstanceId_h -#import - -#if __has_include() -#import - -@interface RNFirebaseInstanceId : NSObject { - -} - -@end - -#else -@interface RNFirebaseInstanceId : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/instanceid/RNFirebaseInstanceId.m b/ios/RNFirebase/instanceid/RNFirebaseInstanceId.m deleted file mode 100644 index 80d79a6e..00000000 --- a/ios/RNFirebase/instanceid/RNFirebaseInstanceId.m +++ /dev/null @@ -1,66 +0,0 @@ -#import "RNFirebaseInstanceId.h" - -#if __has_include() -//#import -#import - -@implementation RNFirebaseInstanceId -RCT_EXPORT_MODULE(); - -RCT_EXPORT_METHOD(delete:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - [[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError * _Nullable error) { - if (error) { - reject(@"instance_id_error", @"Failed to delete instance id", error); - } else { - resolve(nil); - } - }]; -} - -RCT_EXPORT_METHOD(get:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - [[FIRInstanceID instanceID] getIDWithHandler:^(NSString * _Nullable identity, NSError * _Nullable error) { - if (error) { - reject(@"instance_id_error", @"Failed to get instance id", error); - } else { - resolve(identity); - } - }]; -} - -RCT_EXPORT_METHOD(getToken:(NSString *)authorizedEntity - scope:(NSString *)scope - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSDictionary * options = nil; -// if ([FIRMessaging messaging].APNSToken) { -// options = @{@"apns_token": [FIRMessaging messaging].APNSToken}; -// } - [[FIRInstanceID instanceID] tokenWithAuthorizedEntity:authorizedEntity scope:scope options:options handler:^(NSString * _Nullable identity, NSError * _Nullable error) { - if (error) { - reject(@"instance_id_error", @"Failed to getToken", error); - } else { - resolve(identity); - } - }]; -} - -RCT_EXPORT_METHOD(deleteToken:(NSString *)authorizedEntity - scope:(NSString *)scope - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[FIRInstanceID instanceID] deleteTokenWithAuthorizedEntity:authorizedEntity scope:scope handler:^(NSError * _Nullable error) { - if (error) { - reject(@"instance_id_error", @"Failed to deleteToken", error); - } else { - resolve(nil); - } - }]; -} - -@end - -#else -@implementation RNFirebaseInstanceId -@end -#endif - diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.h b/ios/RNFirebase/invites/RNFirebaseInvites.h deleted file mode 100644 index 1554834e..00000000 --- a/ios/RNFirebase/invites/RNFirebaseInvites.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RNFirebaseInvites_h -#define RNFirebaseInvites_h -#import - -#if __has_include() -#import -#import -#import - -@interface RNFirebaseInvites : RCTEventEmitter - -+ (_Nonnull instancetype)instance; - -@property _Nullable RCTPromiseRejectBlock invitationsRejecter; -@property _Nullable RCTPromiseResolveBlock invitationsResolver; - -- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options; -- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler; - -@end - -#else -@interface RNFirebaseInvites : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.m b/ios/RNFirebase/invites/RNFirebaseInvites.m deleted file mode 100644 index c71d4880..00000000 --- a/ios/RNFirebase/invites/RNFirebaseInvites.m +++ /dev/null @@ -1,210 +0,0 @@ -#import "RNFirebaseInvites.h" - -#if __has_include() -#import "RNFirebaseEvents.h" -#import "RNFirebaseLinks.h" -#import "RNFirebaseUtil.h" -#import - -#import -#import -#import - -@implementation RNFirebaseInvites - -static RNFirebaseInvites *theRNFirebaseInvites = nil; -static NSString *initialInvite = nil; -static bool jsReady = FALSE; - -+ (nonnull instancetype)instance { - // If an event comes in before the bridge has initialised the native module - // then we create a temporary instance which handles events until the bridge - // and JS side are ready - if (theRNFirebaseInvites == nil) { - theRNFirebaseInvites = [[RNFirebaseInvites alloc] init]; - } - return theRNFirebaseInvites; -} - -RCT_EXPORT_MODULE() - -- (id)init { - self = [super init]; - if (self != nil) { - DLog(@"Setting up RNFirebaseInvites instance"); - // Set static instance for use from AppDelegate - theRNFirebaseInvites = self; - } - return self; -} - -// ******************************************************* -// ** Start AppDelegate methods -// ******************************************************* - -- (BOOL)application:(UIApplication *)app - openURL:(NSURL *)url - options:(NSDictionary *)options { - return [self handleUrl:url]; -} - -- (BOOL)application:(UIApplication *)application -continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(void (^)(NSArray *))restorationHandler { - if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { - return [self handleUrl:userActivity.webpageURL]; - } - return NO; -} -// ******************************************************* -// ** Finish AppDelegate methods -// ******************************************************* - -// ******************************************************* -// ** Start FIRInviteDelegate methods -// ******************************************************* - -// Listen for invitation response -- (void)inviteFinishedWithInvitations:(NSArray *)invitationIds error:(NSError *)error { - if (error) { - if (error.code == -402) { - _invitationsRejecter(@"invites/invitation-cancelled", @"Invitation cancelled", nil); - } else if (error.code == -404) { - _invitationsRejecter(@"invites/invitation-error", @"User must be signed in with GoogleSignIn", nil); - } else { - _invitationsRejecter(@"invites/invitation-error", @"Invitation failed to send", error); - } - } else { - _invitationsResolver(invitationIds); - } - _invitationsRejecter = nil; - _invitationsResolver = nil; -} - -// ******************************************************* -// ** Finish FIRInviteDelegate methods -// ******************************************************* - -// ** Start React Module methods ** -RCT_EXPORT_METHOD(getInitialInvitation:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - NSURL* url = nil; - if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { - url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; - } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]) { - NSDictionary *dictionary = self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; - if ([dictionary[UIApplicationLaunchOptionsUserActivityTypeKey] isEqual:NSUserActivityTypeBrowsingWeb]) { - NSUserActivity* userActivity = (NSUserActivity*) dictionary[@"UIApplicationLaunchOptionsUserActivityKey"]; - url = userActivity.webpageURL; - } - } - - if (url) { - [FIRInvites handleUniversalLink:url completion:^(FIRReceivedInvite * _Nullable receivedInvite, NSError * _Nullable error) { - if (error) { - DLog(@"Failed to handle universal link: %@", [error localizedDescription]); - reject(@"invites/initial-invitation-error", @"Failed to handle invitation", error); - } else if (receivedInvite && receivedInvite.inviteId) { - resolve(@{ - @"deepLink": receivedInvite.deepLink, - @"invitationId": receivedInvite.inviteId, - }); - } else { - resolve(initialInvite); - } - }]; - } else { - resolve(initialInvite); - } -} - -RCT_EXPORT_METHOD(sendInvitation:(NSDictionary *) invitation - resolve:(RCTPromiseResolveBlock) resolve - reject:(RCTPromiseRejectBlock) reject) { - if (!invitation[@"message"]) { - reject(@"invites/invalid-invitation", @"The supplied invitation is missing a 'message' field", nil); - } - if (!invitation[@"title"]) { - reject(@"invites/invalid-invitation", @"The supplied invitation is missing a 'title' field", nil); - } - id inviteDialog = [FIRInvites inviteDialog]; - [inviteDialog setInviteDelegate: self]; - [inviteDialog setMessage:invitation[@"message"]]; - [inviteDialog setTitle:invitation[@"title"]]; - - if (invitation[@"androidClientId"]) { - FIRInvitesTargetApplication *targetApplication = [[FIRInvitesTargetApplication alloc] init]; - targetApplication.androidClientID = invitation[@"androidClientId"]; - [inviteDialog setOtherPlatformsTargetApplication:targetApplication]; - } - if (invitation[@"androidMinimumVersionCode"]) { - [inviteDialog setAndroidMinimumVersionCode:invitation[@"androidMinimumVersionCode"]]; - } - if (invitation[@"callToActionText"]) { - [inviteDialog setCallToActionText:invitation[@"callToActionText"]]; - } - if (invitation[@"customImage"]) { - [inviteDialog setCustomImage:invitation[@"customImage"]]; - } - if (invitation[@"deepLink"]) { - [inviteDialog setDeepLink:invitation[@"deepLink"]]; - } - - // Save the promise details for later - _invitationsRejecter = reject; - _invitationsResolver = resolve; - - // Open the invitation dialog - dispatch_async(dispatch_get_main_queue(), ^{ - [inviteDialog open]; - }); -} - -RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - jsReady = TRUE; - resolve(nil); -} - -// ** Start internals ** -- (BOOL)handleUrl:(NSURL *)url { - return [FIRInvites handleUniversalLink:url completion:^(FIRReceivedInvite * _Nullable receivedInvite, NSError * _Nullable error) { - if (error) { - DLog(@"Failed to handle invitation: %@", [error localizedDescription]); - } else if (receivedInvite && receivedInvite.inviteId) { - [self sendJSEvent:self name:INVITES_INVITATION_RECEIVED body:@{ - @"deepLink": receivedInvite.deepLink, - @"invitationId": receivedInvite.inviteId, - }]; - } else { - [[RNFirebaseLinks instance] sendLink:receivedInvite.deepLink]; - } - }]; -} - -// Because of the time delay between the app starting and the bridge being initialised -// we catch any events that are received before the JS is ready to receive them -- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { - if (emitter.bridge && jsReady) { - [RNFirebaseUtil sendJSEvent:emitter name:name body:body]; - } else if (!initialInvite) { - initialInvite = body; - } else { - DLog(@"Multiple invite events received before the JS invites module has been initialised"); - } -} - -- (NSArray *)supportedEvents { - return @[INVITES_INVITATION_RECEIVED]; -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else -@implementation RNFirebaseInvites -@end -#endif - diff --git a/ios/RNFirebase/links/RNFirebaseLinks.h b/ios/RNFirebase/links/RNFirebaseLinks.h deleted file mode 100644 index f2b68445..00000000 --- a/ios/RNFirebase/links/RNFirebaseLinks.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef RNFirebaseLinks_h -#define RNFirebaseLinks_h -#import - -#if __has_include() -#import -#import -#import - -@interface RNFirebaseLinks : RCTEventEmitter - -+ (_Nonnull instancetype)instance; - -- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options; -- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler; -- (void)sendLink:(NSString *)link; - -@end - -#else -@interface RNFirebaseLinks : NSObject -@end -#endif - -#endif - diff --git a/ios/RNFirebase/links/RNFirebaseLinks.m b/ios/RNFirebase/links/RNFirebaseLinks.m deleted file mode 100644 index 1c501ca6..00000000 --- a/ios/RNFirebase/links/RNFirebaseLinks.m +++ /dev/null @@ -1,332 +0,0 @@ -#import "RNFirebaseLinks.h" - -#if __has_include() -#import -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" - -@implementation RNFirebaseLinks - -static RNFirebaseLinks *theRNFirebaseLinks = nil; -static NSString *initialLink = nil; -static bool jsReady = FALSE; - -+ (nonnull instancetype)instance { - // If an event comes in before the bridge has initialised the native module - // then we create a temporary instance which handles events until the bridge - // and JS side are ready - if (theRNFirebaseLinks == nil) { - theRNFirebaseLinks = [[RNFirebaseLinks alloc] init]; - } - return theRNFirebaseLinks; -} - -RCT_EXPORT_MODULE(); - -- (id)init { - self = [super init]; - if (self != nil) { - DLog(@"Setting up RNFirebaseLinks instance"); - // Set static instance for use from AppDelegate - theRNFirebaseLinks = self; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -// ******************************************************* -// ** Start AppDelegate methods -// ******************************************************* - -- (BOOL)application:(UIApplication *)app - openURL:(NSURL *)url - options:(NSDictionary *)options { - FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - if (dynamicLink && dynamicLink.url) { - NSURL* url = dynamicLink.url; - [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; - return YES; - } - return NO; -} - -- (BOOL)application:(UIApplication *)application -continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(void (^)(NSArray *))restorationHandler { - if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { - return [[FIRDynamicLinks dynamicLinks] - handleUniversalLink:userActivity.webpageURL - completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { - if (dynamicLink && dynamicLink.url && error == nil) { - NSURL* url = dynamicLink.url; - [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; - } else if (error != nil && [NSPOSIXErrorDomain isEqualToString:error.domain] && error.code == 53) { - DLog(@"Failed to handle universal link on first attempt, retrying: %@", userActivity.webpageURL); - - // Per Apple Tech Support, this could occur when returning from background on iOS 12. - // https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 - // Retry the request once - [[FIRDynamicLinks dynamicLinks] - handleUniversalLink:userActivity.webpageURL - completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { - if (dynamicLink && dynamicLink.url && error == nil) { - NSURL* url = dynamicLink.url; - [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; - } else { - DLog(@"Failed to handle universal link during retry: %@", userActivity.webpageURL); - } - }]; - } else { - DLog(@"Failed to handle universal link: %@", userActivity.webpageURL); - } - }]; - } - return NO; -} -// ******************************************************* -// ** Finish AppDelegate methods -// ******************************************************* - -- (void)sendLink:(NSString *)link { - [self sendJSEvent:self name:LINKS_LINK_RECEIVED body:link]; -} - -// ** Start React Module methods ** -RCT_EXPORT_METHOD(createDynamicLink:(NSDictionary *)linkData - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - @try { - FIRDynamicLinkComponents *dynamicLink = [self buildDynamicLink:linkData]; - - if (dynamicLink == nil) { - reject(@"links/failure", @"Failed to create Dynamic Link", nil); - } else { - NSString *longLink = dynamicLink.url.absoluteString; - DLog(@"created long dynamic link: %@", longLink); - resolve(longLink); - } - } - @catch(NSException * e) { - DLog(@"create dynamic link failure %@", e); - reject(@"links/failure",[e reason], nil); - } -} - -RCT_EXPORT_METHOD(createShortDynamicLink:(NSDictionary *)linkData - type:(NSString *)type - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - @try { - FIRDynamicLinkComponents *components = [self buildDynamicLink:linkData]; - if (type) { - FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options]; - if ([type isEqual: @"SHORT"]) { - options.pathLength = FIRShortDynamicLinkPathLengthShort; - } else if ([type isEqual: @"UNGUESSABLE"]) { - options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; - } - components.options = options; - } - [components shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error) { - if (error) { - DLog(@"create short dynamic link failure %@", [error localizedDescription]); - reject(@"links/failure", @"Failed to create Short Dynamic Link", error); - } else { - NSString *shortLink = shortURL.absoluteString; - DLog(@"created short dynamic link: %@", shortLink); - resolve(shortLink); - } - }]; - } - @catch(NSException * e) { - DLog(@"create short dynamic link failure %@", e); - reject(@"links/failure",[e reason], nil); - } -} - -RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { - NSURL* url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; - FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - resolve(dynamicLink ? dynamicLink.url.absoluteString : initialLink); - } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] - && [self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey][UIApplicationLaunchOptionsUserActivityTypeKey] isEqualToString:NSUserActivityTypeBrowsingWeb]) { - NSDictionary *dictionary = self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; - NSUserActivity* userActivity = (NSUserActivity*) dictionary[@"UIApplicationLaunchOptionsUserActivityKey"]; - BOOL handled = [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL - completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { - if (error != nil){ - DLog(@"Failed to handle universal link: %@", [error localizedDescription]); - reject(@"links/failure", @"Failed to handle universal link", error); - } else { - NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : userActivity.webpageURL.absoluteString; - DLog(@"initial link is: %@", urlString); - resolve(urlString); - } - }]; - if (!handled) { - resolve(nil); - } - } else { - resolve(initialLink); - } -} - -RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - jsReady = TRUE; - resolve(nil); -} - -// ** Start internals ** - -// Because of the time delay between the app starting and the bridge being initialised -// we catch any events that are received before the JS is ready to receive them -- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { - if (emitter.bridge && jsReady) { - [RNFirebaseUtil sendJSEvent:emitter name:name body:body]; - } else if (!initialLink) { - initialLink = body; - } else { - DLog(@"Multiple link events received before the JS links module has been initialised"); - } -} - -- (FIRDynamicLinkComponents *)buildDynamicLink:(NSDictionary *)linkData { - @try { - NSURL *link = [NSURL URLWithString:linkData[@"link"]]; - FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link domain:linkData[@"dynamicLinkDomain"]]; - - [self setAnalyticsParameters:linkData[@"analytics"] components:components]; - [self setAndroidParameters:linkData[@"android"] components:components]; - [self setIosParameters:linkData[@"ios"] components:components]; - [self setITunesParameters:linkData[@"itunes"] components:components]; - [self setNavigationParameters:linkData[@"navigation"] components:components]; - [self setSocialParameters:linkData[@"social"] components:components]; - - return components; - } - @catch(NSException * e) { - DLog(@"error while building componets from meta data %@", e); - @throw; - } -} - -- (void)setAnalyticsParameters:(NSDictionary *)analyticsData - components:(FIRDynamicLinkComponents *)components { - FIRDynamicLinkGoogleAnalyticsParameters *analyticsParams = [FIRDynamicLinkGoogleAnalyticsParameters parameters]; - - if (analyticsData[@"campaign"]) { - analyticsParams.campaign = analyticsData[@"campaign"]; - } - if (analyticsData[@"content"]) { - analyticsParams.content = analyticsData[@"content"]; - } - if (analyticsData[@"medium"]) { - analyticsParams.medium = analyticsData[@"medium"]; - } - if (analyticsData[@"source"]) { - analyticsParams.source = analyticsData[@"source"]; - } - if (analyticsData[@"term"]) { - analyticsParams.term = analyticsData[@"term"]; - } - components.analyticsParameters = analyticsParams; -} - -- (void)setAndroidParameters:(NSDictionary *)androidData - components:(FIRDynamicLinkComponents *)components { - if (androidData[@"packageName"]) { - FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters parametersWithPackageName: androidData[@"packageName"]]; - - if (androidData[@"fallbackUrl"]) { - androidParams.fallbackURL = [NSURL URLWithString:androidData[@"fallbackUrl"]]; - } - if (androidData[@"minimumVersion"]) { - androidParams.minimumVersion = [androidData[@"minimumVersion"] integerValue]; - } - components.androidParameters = androidParams; - } -} - -- (void)setIosParameters:(NSDictionary *)iosData - components:(FIRDynamicLinkComponents *)components { - if (iosData[@"bundleId"]) { - FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters parametersWithBundleID:iosData[@"bundleId"]]; - if (iosData[@"appStoreId"]) { - iOSParams.appStoreID = iosData[@"appStoreId"]; - } - if (iosData[@"customScheme"]) { - iOSParams.customScheme = iosData[@"customScheme"]; - } - if (iosData[@"fallbackUrl"]) { - iOSParams.fallbackURL = [NSURL URLWithString:iosData[@"fallbackUrl"]]; - } - if (iosData[@"iPadBundleId"]) { - iOSParams.iPadBundleID = iosData[@"iPadBundleId"]; - } - if (iosData[@"iPadFallbackUrl"]) { - iOSParams.iPadFallbackURL = [NSURL URLWithString:iosData[@"iPadFallbackUrl"]]; - } - if (iosData[@"minimumVersion"]) { - iOSParams.minimumAppVersion = iosData[@"minimumVersion"]; - } - components.iOSParameters = iOSParams; - } -} - -- (void)setITunesParameters:(NSDictionary *)itunesData - components:(FIRDynamicLinkComponents *)components { - FIRDynamicLinkItunesConnectAnalyticsParameters *itunesParams = [FIRDynamicLinkItunesConnectAnalyticsParameters parameters]; - if (itunesData[@"affiliateToken"]) { - itunesParams.affiliateToken = itunesData[@"affiliateToken"]; - } - if (itunesData[@"campaignToken"]) { - itunesParams.campaignToken = itunesData[@"campaignToken"]; - } - if (itunesData[@"providerToken"]) { - itunesParams.providerToken = itunesData[@"providerToken"]; - } - components.iTunesConnectParameters = itunesParams; -} - -- (void)setNavigationParameters:(NSDictionary *)navigationData - components:(FIRDynamicLinkComponents *)components { - FIRDynamicLinkNavigationInfoParameters *navigationParams = [FIRDynamicLinkNavigationInfoParameters parameters]; - if (navigationData[@"forcedRedirectEnabled"]) { - navigationParams.forcedRedirectEnabled = navigationData[@"forcedRedirectEnabled"]; - } - components.navigationInfoParameters = navigationParams; -} - -- (void)setSocialParameters:(NSDictionary *)socialData - components:(FIRDynamicLinkComponents *)components { - FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters]; - if (socialData[@"descriptionText"]) { - socialParams.descriptionText = socialData[@"descriptionText"]; - } - if (socialData[@"imageUrl"]) { - socialParams.imageURL = [NSURL URLWithString:socialData[@"imageUrl"]]; - } - if (socialData[@"title"]) { - socialParams.title = socialData[@"title"]; - } - components.socialMetaTagParameters = socialParams; -} - -- (NSArray *)supportedEvents { - return @[LINKS_LINK_RECEIVED]; -} - -+ (BOOL)requiresMainQueueSetup { - return YES; -} - -@end - -#else -@implementation RNFirebaseLinks -@end -#endif diff --git a/ios/RNFirebase/messaging/RNFirebaseMessaging.h b/ios/RNFirebase/messaging/RNFirebaseMessaging.h deleted file mode 100644 index 4db95fa9..00000000 --- a/ios/RNFirebase/messaging/RNFirebaseMessaging.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef RNFirebaseMessaging_h -#define RNFirebaseMessaging_h -#import - -#if __has_include() -#import -#import -#import - -@interface RNFirebaseMessaging : RCTEventEmitter - -+ (_Nonnull instancetype)instance; - -@property _Nullable RCTPromiseRejectBlock permissionRejecter; -@property _Nullable RCTPromiseResolveBlock permissionResolver; - -#if !TARGET_OS_TV -- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo; -- (void)didRegisterUserNotificationSettings:(nonnull UIUserNotificationSettings *)notificationSettings; -#endif - -@end - -#else -@interface RNFirebaseMessaging : NSObject -@end -#endif - -#endif - diff --git a/ios/RNFirebase/messaging/RNFirebaseMessaging.m b/ios/RNFirebase/messaging/RNFirebaseMessaging.m deleted file mode 100644 index 90fdb1d5..00000000 --- a/ios/RNFirebase/messaging/RNFirebaseMessaging.m +++ /dev/null @@ -1,344 +0,0 @@ -#import "RNFirebaseMessaging.h" - -#if __has_include() -@import UserNotifications; -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" -#import - -#import -#import -#import - -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 -@import UserNotifications; -#endif - -@implementation RNFirebaseMessaging - -static RNFirebaseMessaging *theRNFirebaseMessaging = nil; -static bool jsReady = FALSE; -static NSString* initialToken = nil; -static NSMutableArray* pendingMessages = nil; - -+ (nonnull instancetype)instance { - return theRNFirebaseMessaging; -} - -RCT_EXPORT_MODULE() - -- (id)init { - self = [super init]; - if (self != nil) { - DLog(@"Setting up RNFirebaseMessaging instance"); - [self configure]; - } - return self; -} - -- (void)configure { - // Set as delegate for FIRMessaging - [FIRMessaging messaging].delegate = self; - - // Establish Firebase managed data channel - [FIRMessaging messaging].shouldEstablishDirectChannel = YES; - - // Set static instance for use from AppDelegate - theRNFirebaseMessaging = self; -} - -// ******************************************************* -// ** Start AppDelegate methods -// ** iOS 8/9 Only -// ******************************************************* - -// Listen for permission response -- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - if (notificationSettings.types == UIUserNotificationTypeNone) { - if (_permissionRejecter) { - _permissionRejecter(@"messaging/permission_error", @"Failed to grant permission", nil); - } - } else if (_permissionResolver) { - _permissionResolver(nil); - } - _permissionRejecter = nil; - _permissionResolver = nil; -} - -// Listen for FCM data messages that arrive as a remote notification -- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo { - NSDictionary *message = [self parseUserInfo:userInfo]; - [self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message]; -} - -// ******************************************************* -// ** Finish AppDelegate methods -// ******************************************************* - - -// ******************************************************* -// ** Start FIRMessagingDelegate methods -// ** iOS 8+ -// ******************************************************* - -// Listen for FCM tokens -- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { - DLog(@"Received new FCM token: %@", fcmToken); - [self sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:fcmToken]; -} - -// Listen for data messages in the foreground -- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage { - NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage]; - [self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message]; -} - -// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground. -// To enable direct data messages, you can set [Messaging messaging].shouldEstablishDirectChannel to YES. -- (void)messaging:(nonnull FIRMessaging *)messaging -didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage { - NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage]; - [self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message]; -} - -// ******************************************************* -// ** Finish FIRMessagingDelegate methods -// ******************************************************* - -// ** Start React Module methods ** -RCT_EXPORT_METHOD(getToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (initialToken) { - resolve(initialToken); - initialToken = nil; - } else if ([[FIRMessaging messaging] FCMToken]) { - resolve([[FIRMessaging messaging] FCMToken]); - } else { - NSString * senderId = [[FIRApp defaultApp] options].GCMSenderID; - [[FIRMessaging messaging] retrieveFCMTokenForSenderID:senderId completion:^(NSString * _Nullable FCMToken, NSError * _Nullable error) { - if (error) { - reject(@"messaging/fcm-token-error", @"Failed to retrieve FCM token.", error); - } else if (FCMToken) { - resolve(FCMToken); - } else { - resolve([NSNull null]); - } - }]; - } -} - -RCT_EXPORT_METHOD(deleteToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - NSString * senderId = [[FIRApp defaultApp] options].GCMSenderID; - [[FIRMessaging messaging] deleteFCMTokenForSenderID:senderId completion:^(NSError * _Nullable error) { - if (error) { - reject(@"messaging/fcm-token-error", @"Failed to delete FCM token.", error); - } else { - resolve([NSNull null]); - } - }]; -} - - -RCT_EXPORT_METHOD(getAPNSToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - NSData *apnsToken = [FIRMessaging messaging].APNSToken; - if (apnsToken) { - const char *data = [apnsToken bytes]; - NSMutableString *token = [NSMutableString string]; - for (NSInteger i = 0; i < apnsToken.length; i++) { - [token appendFormat:@"%02.2hhX", data[i]]; - } - resolve([token copy]); - } else { - resolve([NSNull null]); - } -} - -RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (RCTRunningInAppExtension()) { - reject(@"messaging/request-permission-unavailable", @"requestPermission is not supported in App Extensions", nil); - return; - } - - if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) { - UIUserNotificationType types = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); - dispatch_async(dispatch_get_main_queue(), ^{ - [RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]]; - // We set the promise for usage by the AppDelegate callback which listens - // for the result of the permission request - self.permissionRejecter = reject; - self.permissionResolver = resolve; - }); - } else { - if (@available(iOS 10.0, *)) { - // For iOS 10 display notification (sent via APNS) - UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; - [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) { - if (granted) { - resolve(nil); - } else { - reject(@"messaging/permission_error", @"Failed to grant permission", error); - } - }]; - } - } - - dispatch_async(dispatch_get_main_queue(), ^{ - [RCTSharedApplication() registerForRemoteNotifications]; - }); -} - -RCT_EXPORT_METHOD(registerForRemoteNotifications:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - [RCTSharedApplication() registerForRemoteNotifications]; - resolve(nil); -} - -// Non Web SDK methods -RCT_EXPORT_METHOD(hasPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) { - dispatch_async(dispatch_get_main_queue(), ^{ - BOOL hasPermission = [RCTConvert BOOL:@([RCTSharedApplication() currentUserNotificationSettings].types != UIUserNotificationTypeNone)]; - resolve(@(hasPermission)); - }); - } else { - if (@available(iOS 10.0, *)) { - [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { - BOOL hasPermission = [RCTConvert BOOL:@(settings.alertSetting == UNNotificationSettingEnabled)]; - resolve(@(hasPermission)); - }]; - } - } -} - - -RCT_EXPORT_METHOD(sendMessage:(NSDictionary *) message - resolve:(RCTPromiseResolveBlock) resolve - reject:(RCTPromiseRejectBlock) reject) { - if (!message[@"to"]) { - reject(@"messaging/invalid-message", @"The supplied message is missing a 'to' field", nil); - } - NSString *to = message[@"to"]; - NSString *messageId = message[@"messageId"]; - NSNumber *ttl = message[@"ttl"]; - NSDictionary *data = message[@"data"]; - - [[FIRMessaging messaging] sendMessage:data to:to withMessageID:messageId timeToLive:[ttl intValue]]; - - // TODO: Listen for send success / errors - resolve(nil); -} - -RCT_EXPORT_METHOD(subscribeToTopic:(NSString*) topic - resolve:(RCTPromiseResolveBlock) resolve - reject:(RCTPromiseRejectBlock) reject) { - [[FIRMessaging messaging] subscribeToTopic:topic]; - resolve(nil); -} - -RCT_EXPORT_METHOD(unsubscribeFromTopic: (NSString*) topic - resolve:(RCTPromiseResolveBlock) resolve - reject:(RCTPromiseRejectBlock) reject) { - [[FIRMessaging messaging] unsubscribeFromTopic:topic]; - resolve(nil); -} - -RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - jsReady = TRUE; - resolve(nil); - if (initialToken) { - [self sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:initialToken]; - } - if (pendingMessages) { - for (id message in pendingMessages) { - [RNFirebaseUtil sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message]; - } - pendingMessages = nil; - } -} - -// ** Start internals ** - -// Because of the time delay between the app starting and the bridge being initialised -// we catch any events that are received before the JS is ready to receive them -- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { - if (emitter.bridge && jsReady) { - [RNFirebaseUtil sendJSEvent:emitter name:name body:body]; - } else { - if ([name isEqualToString:MESSAGING_TOKEN_REFRESHED]) { - initialToken = body; - } else if ([name isEqualToString:MESSAGING_MESSAGE_RECEIVED]) { - if (!pendingMessages) { - pendingMessages = [[NSMutableArray alloc] init]; - } - [pendingMessages addObject:body]; - } else { - DLog(@"Received unexpected message type"); - } - } -} - -- (NSDictionary*)parseFIRMessagingRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage { - NSDictionary *appData = remoteMessage.appData; - - NSMutableDictionary *message = [[NSMutableDictionary alloc] init]; - NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; - for (id k1 in appData) { - if ([k1 isEqualToString:@"collapse_key"]) { - message[@"collapseKey"] = appData[@"collapse_key"]; - } else if ([k1 isEqualToString:@"from"]) { - message[@"from"] = appData[k1]; - } else if ([k1 isEqualToString:@"notification"]) { - // Ignore for messages - } else { - // Assume custom data key - data[k1] = appData[k1]; - } - } - message[@"data"] = data; - - return message; -} - -- (NSDictionary*)parseUserInfo:(NSDictionary *)userInfo { - NSMutableDictionary *message = [[NSMutableDictionary alloc] init]; - NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; - - for (id k1 in userInfo) { - if ([k1 isEqualToString:@"aps"]) { - // Ignore notification section - } else if ([k1 isEqualToString:@"gcm.message_id"]) { - message[@"messageId"] = userInfo[k1]; - } else if ([k1 isEqualToString:@"google.c.a.ts"]) { - message[@"sentTime"] = userInfo[k1]; - } else if ([k1 isEqualToString:@"gcm.n.e"] - || [k1 isEqualToString:@"gcm.notification.sound2"] - || [k1 isEqualToString:@"google.c.a.c_id"] - || [k1 isEqualToString:@"google.c.a.c_l"] - || [k1 isEqualToString:@"google.c.a.e"] - || [k1 isEqualToString:@"google.c.a.udt"]) { - // Ignore known keys - } else { - // Assume custom data - data[k1] = userInfo[k1]; - } - } - - message[@"data"] = data; - - return message; -} - -- (NSArray *)supportedEvents { - return @[MESSAGING_MESSAGE_RECEIVED, MESSAGING_TOKEN_REFRESHED]; -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else -@implementation RNFirebaseMessaging -@end -#endif - diff --git a/ios/RNFirebase/notifications/RNFirebaseNotifications.h b/ios/RNFirebase/notifications/RNFirebaseNotifications.h deleted file mode 100644 index 5871ba7b..00000000 --- a/ios/RNFirebase/notifications/RNFirebaseNotifications.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RNFirebaseNotifications_h -#define RNFirebaseNotifications_h -#import - -#if __has_include() -#import -#import - -@interface RNFirebaseNotifications : RCTEventEmitter - -+ (void)configure; -+ (_Nonnull instancetype)instance; - -#if !TARGET_OS_TV -- (void)didReceiveLocalNotification:(nonnull UILocalNotification *)notification; -- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(void (^_Nonnull)(UIBackgroundFetchResult))completionHandler; -#endif - -@end - -#else -@interface RNFirebaseNotifications : NSObject -@end -#endif - -#endif - diff --git a/ios/RNFirebase/notifications/RNFirebaseNotifications.m b/ios/RNFirebase/notifications/RNFirebaseNotifications.m deleted file mode 100644 index d3aa1e36..00000000 --- a/ios/RNFirebase/notifications/RNFirebaseNotifications.m +++ /dev/null @@ -1,798 +0,0 @@ -#import "RNFirebaseNotifications.h" - -#if __has_include() -#import "RNFirebaseEvents.h" -#import "RNFirebaseMessaging.h" -#import "RNFirebaseUtil.h" -#import - -// For iOS 10 we need to implement UNUserNotificationCenterDelegate to receive display -// notifications via APNS -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 -@import UserNotifications; -@interface RNFirebaseNotifications () -#else -@interface RNFirebaseNotifications () -#endif -@end - -@implementation RNFirebaseNotifications { - NSMutableDictionary *fetchCompletionHandlers; - NSMutableDictionary *completionHandlers; -} - -static RNFirebaseNotifications *theRNFirebaseNotifications = nil; -// PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side -// static NSMutableArray *pendingEvents = nil; -static NSDictionary *initialNotification = nil; -static bool jsReady = FALSE; -static NSString *const DEFAULT_ACTION = @"com.apple.UNNotificationDefaultActionIdentifier"; - -+ (nonnull instancetype)instance { - return theRNFirebaseNotifications; -} - -+ (void)configure { - // PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side - // pendingEvents = [[NSMutableArray alloc] init]; - theRNFirebaseNotifications = [[RNFirebaseNotifications alloc] init]; -} - -RCT_EXPORT_MODULE(); - -- (id)init { - self = [super init]; - if (self != nil) { - DLog(@"Setting up RNFirebaseNotifications instance"); - [self initialise]; - } - return self; -} - -- (void)initialise { - // If we're on iOS 10 then we need to set this as a delegate for the UNUserNotificationCenter - if (@available(iOS 10.0, *)) { - [UNUserNotificationCenter currentNotificationCenter].delegate = self; - } - - // Set static instance for use from AppDelegate - theRNFirebaseNotifications = self; - completionHandlers = [[NSMutableDictionary alloc] init]; - fetchCompletionHandlers = [[NSMutableDictionary alloc] init]; -} - -// PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side -// The bridge is initialised after the module is created -// When the bridge is set, check if we have any pending events to send, and send them -/* - (void)setValue:(nullable id)value forKey:(NSString *)key { - [super setValue:value forKey:key]; - if ([key isEqualToString:@"bridge"] && value) { - for (NSDictionary* event in pendingEvents) { - [RNFirebaseUtil sendJSEvent:self name:event[@"name"] body:event[@"body"]]; - } - [pendingEvents removeAllObjects]; - } -} */ - -// ******************************************************* -// ** Start AppDelegate methods -// ** iOS 8/9 Only -// ******************************************************* -- (void)didReceiveLocalNotification:(nonnull UILocalNotification *)localNotification { - if ([self isIOS89]) { - NSString *event; - if (RCTSharedApplication().applicationState == UIApplicationStateBackground) { - event = NOTIFICATIONS_NOTIFICATION_DISPLAYED; - } else if (RCTSharedApplication().applicationState == UIApplicationStateInactive) { - event = NOTIFICATIONS_NOTIFICATION_OPENED; - } else { - event = NOTIFICATIONS_NOTIFICATION_RECEIVED; - } - - NSDictionary *notification = [self parseUILocalNotification:localNotification]; - if (event == NOTIFICATIONS_NOTIFICATION_OPENED) { - notification = @{ - @"action": DEFAULT_ACTION, - @"notification": notification - }; - } - [self sendJSEvent:self name:event body:notification]; - } -} - -RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchResult)fetchResult) { - if (handlerKey != nil) { - void (^fetchCompletionHandler)(UIBackgroundFetchResult) = fetchCompletionHandlers[handlerKey]; - if (fetchCompletionHandler != nil) { - fetchCompletionHandlers[handlerKey] = nil; - fetchCompletionHandler(fetchResult); - } else { - void(^completionHandler)(void) = completionHandlers[handlerKey]; - if (completionHandler != nil) { - completionHandlers[handlerKey] = nil; - completionHandler(); - } - } - } -} - -// Listen for background messages -- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo - fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { - // FCM Data messages come through here if they specify content-available=true - // Pass them over to the RNFirebaseMessaging handler instead - if (userInfo[@"aps"] && ((NSDictionary*)userInfo[@"aps"]).count == 1 && userInfo[@"aps"][@"content-available"]) { - [[RNFirebaseMessaging instance] didReceiveRemoteNotification:userInfo]; - completionHandler(UIBackgroundFetchResultNoData); - return; - } - - NSDictionary *notification = [self parseUserInfo:userInfo]; - NSString *handlerKey = notification[@"notificationId"]; - - NSString *event; - if (RCTSharedApplication().applicationState == UIApplicationStateBackground) { - event = NOTIFICATIONS_NOTIFICATION_DISPLAYED; - } else if ([self isIOS89]) { - if (RCTSharedApplication().applicationState == UIApplicationStateInactive) { - event = NOTIFICATIONS_NOTIFICATION_OPENED; - } else { - event = NOTIFICATIONS_NOTIFICATION_RECEIVED; - } - } else { - // On IOS 10: - // - foreground notifications also go through willPresentNotification - // - background notification presses also go through didReceiveNotificationResponse - // This prevents duplicate messages from hitting the JS app - completionHandler(UIBackgroundFetchResultNoData); - return; - } - - // For onOpened events, we set the default action name as iOS 8/9 has no concept of actions - if (event == NOTIFICATIONS_NOTIFICATION_OPENED) { - notification = @{ - @"action": DEFAULT_ACTION, - @"notification": notification - }; - } - - if (handlerKey != nil) { - fetchCompletionHandlers[handlerKey] = completionHandler; - } else { - completionHandler(UIBackgroundFetchResultNoData); - } - - [self sendJSEvent:self name:event body:notification]; -} - -// ******************************************************* -// ** Finish AppDelegate methods -// ******************************************************* - -// ******************************************************* -// ** Start UNUserNotificationCenterDelegate methods -// ** iOS 10+ -// ******************************************************* - -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 -// Handle incoming notification messages while app is in the foreground. -- (void)userNotificationCenter:(UNUserNotificationCenter *)center - willPresentNotification:(UNNotification *)notification - withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler NS_AVAILABLE_IOS(10_0) { - UNNotificationTrigger *trigger = notification.request.trigger; - BOOL isFcm = trigger && [notification.request.trigger class] == [UNPushNotificationTrigger class]; - BOOL isScheduled = trigger && [notification.request.trigger class] == [UNCalendarNotificationTrigger class]; - - NSString *event; - UNNotificationPresentationOptions options; - NSDictionary *message = [self parseUNNotification:notification]; - - if (isFcm || isScheduled) { - // If app is in the background - if (RCTSharedApplication().applicationState == UIApplicationStateBackground - || RCTSharedApplication().applicationState == UIApplicationStateInactive) { - // display the notification - options = UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound; - // notification_displayed - event = NOTIFICATIONS_NOTIFICATION_DISPLAYED; - } else { - // don't show notification - options = UNNotificationPresentationOptionNone; - // notification_received - event = NOTIFICATIONS_NOTIFICATION_RECEIVED; - } - } else { - // Triggered by `notifications().displayNotification(notification)` - // Display the notification - options = UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound; - // notification_displayed - event = NOTIFICATIONS_NOTIFICATION_DISPLAYED; - } - - [self sendJSEvent:self name:event body:message]; - completionHandler(options); -} - -// Handle notification messages after display notification is tapped by the user. -- (void)userNotificationCenter:(UNUserNotificationCenter *)center -didReceiveNotificationResponse:(UNNotificationResponse *)response -#if defined(__IPHONE_11_0) - withCompletionHandler:(void(^)(void))completionHandler NS_AVAILABLE_IOS(10_0) { -#else - withCompletionHandler:(void(^)())completionHandler NS_AVAILABLE_IOS(10_0) { -#endif - NSDictionary *message = [self parseUNNotificationResponse:response]; - - NSString *handlerKey = message[@"notification"][@"notificationId"]; - - [self sendJSEvent:self name:NOTIFICATIONS_NOTIFICATION_OPENED body:message]; - if (handlerKey != nil) { - completionHandlers[handlerKey] = completionHandler; - } else { - completionHandler(); - } -} - -#endif - -// ******************************************************* -// ** Finish UNUserNotificationCenterDelegate methods -// ******************************************************* - -RCT_EXPORT_METHOD(cancelAllNotifications:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - [RCTSharedApplication() cancelAllLocalNotifications]; - } else { - if (@available(iOS 10.0, *)) { - UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; - if (notificationCenter != nil) { - [[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests]; - } - } - } - resolve(nil); -} - -RCT_EXPORT_METHOD(cancelNotification:(NSString*) notificationId - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - for (UILocalNotification *notification in RCTSharedApplication().scheduledLocalNotifications) { - NSDictionary *notificationInfo = notification.userInfo; - if ([notificationId isEqualToString:notificationInfo[@"notificationId"]]) { - [RCTSharedApplication() cancelLocalNotification:notification]; - } - } - } else { - if (@available(iOS 10.0, *)) { - UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; - if (notificationCenter != nil) { - [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[notificationId]]; - } - } - } - resolve(nil); -} - -RCT_EXPORT_METHOD(displayNotification:(NSDictionary*) notification - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - UILocalNotification* notif = [self buildUILocalNotification:notification withSchedule:false]; - [RCTSharedApplication() presentLocalNotificationNow:notif]; - resolve(nil); - } else { - if (@available(iOS 10.0, *)) { - UNNotificationRequest* request = [self buildUNNotificationRequest:notification withSchedule:false]; - [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { - if (!error) { - resolve(nil); - } else{ - reject(@"notifications/display_notification_error", @"Failed to display notificaton", error); - } - }]; - } - } -} - -RCT_EXPORT_METHOD(getBadge: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^{ - resolve(@([RCTSharedApplication() applicationIconBadgeNumber])); - }); -} - -RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - // Check if we've cached an initial notification as this will contain the accurate action - if (initialNotification) { - resolve(initialNotification); - } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { - UILocalNotification *localNotification = self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; - resolve(@{ - @"action": DEFAULT_ACTION, - @"notification": [self parseUILocalNotification:localNotification] - }); - } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) { - NSDictionary *remoteNotification = [self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; - resolve(@{ - @"action": DEFAULT_ACTION, - @"notification": [self parseUserInfo:remoteNotification] - }); - } else { - resolve(nil); - } -} - -RCT_EXPORT_METHOD(getScheduledNotifications:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - NSMutableArray* notifications = [[NSMutableArray alloc] init]; - for (UILocalNotification *notif in [RCTSharedApplication() scheduledLocalNotifications]){ - NSDictionary *notification = [self parseUILocalNotification:notif]; - [notifications addObject:notification]; - } - resolve(notifications); - } else { - if (@available(iOS 10.0, *)) { - [[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray * _Nonnull requests) { - NSMutableArray* notifications = [[NSMutableArray alloc] init]; - for (UNNotificationRequest *notif in requests){ - NSDictionary *notification = [self parseUNNotificationRequest:notif]; - [notifications addObject:notification]; - } - resolve(notifications); - }]; - } - } -} - -RCT_EXPORT_METHOD(removeAllDeliveredNotifications:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - // No such functionality on iOS 8/9 - } else { - if (@available(iOS 10.0, *)) { - UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; - if (notificationCenter != nil) { - [[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications]; - } - } - } - resolve(nil); -} - -RCT_EXPORT_METHOD(removeDeliveredNotification:(NSString*) notificationId - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - // No such functionality on iOS 8/9 - } else { - if (@available(iOS 10.0, *)) { - UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; - if (notificationCenter != nil) { - [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notificationId]]; - } - } - } - resolve(nil); -} - -RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if ([self isIOS89]) { - UILocalNotification* notif = [self buildUILocalNotification:notification withSchedule:true]; - [RCTSharedApplication() scheduleLocalNotification:notif]; - resolve(nil); - } else { - if (@available(iOS 10.0, *)) { - UNNotificationRequest* request = [self buildUNNotificationRequest:notification withSchedule:true]; - [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { - if (!error) { - resolve(nil); - } else{ - reject(@"notification/schedule_notification_error", @"Failed to schedule notificaton", error); - } - }]; - } - } -} - -RCT_EXPORT_METHOD(setBadge:(NSInteger) number - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^{ - [RCTSharedApplication() setApplicationIconBadgeNumber:number]; - resolve(nil); - }); -} - -RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - jsReady = TRUE; - resolve(nil); -} - -// Because of the time delay between the app starting and the bridge being initialised -// we create a temporary instance of RNFirebaseNotifications. -// With this temporary instance, we cache any events to be sent as soon as the bridge is set on the module -- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body { - if (emitter.bridge && jsReady) { - [RNFirebaseUtil sendJSEvent:emitter name:name body:body]; - } else { - if ([name isEqualToString:NOTIFICATIONS_NOTIFICATION_OPENED] && !initialNotification) { - initialNotification = body; - } else if ([name isEqualToString:NOTIFICATIONS_NOTIFICATION_OPENED]) { - DLog(@"Multiple notification open events received before the JS Notifications module has been initialised"); - } - // PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side - // [pendingEvents addObject:@{@"name":name, @"body":body}]; - } -} - -- (BOOL)isIOS89 { - return floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max; -} - -- (UILocalNotification*) buildUILocalNotification:(NSDictionary *) notification - withSchedule:(BOOL) withSchedule { - UILocalNotification *localNotification = [[UILocalNotification alloc] init]; - if (notification[@"body"]) { - localNotification.alertBody = notification[@"body"]; - } - if (notification[@"data"]) { - localNotification.userInfo = notification[@"data"]; - } - if (notification[@"sound"]) { - localNotification.soundName = notification[@"sound"]; - } - if (notification[@"title"]) { - localNotification.alertTitle = notification[@"title"]; - } - if (notification[@"ios"]) { - NSDictionary *ios = notification[@"ios"]; - if (ios[@"alertAction"]) { - localNotification.alertAction = ios[@"alertAction"]; - } - if (ios[@"badge"]) { - NSNumber *badge = ios[@"badge"]; - localNotification.applicationIconBadgeNumber = badge.integerValue; - } - if (ios[@"category"]) { - localNotification.category = ios[@"category"]; - } - if (ios[@"hasAction"]) { - localNotification.hasAction = ios[@"hasAction"]; - } - if (ios[@"launchImage"]) { - localNotification.alertLaunchImage = ios[@"launchImage"]; - } - } - if (withSchedule) { - NSDictionary *schedule = notification[@"schedule"]; - NSNumber *fireDateNumber = schedule[@"fireDate"]; - NSDate *fireDate = [NSDate dateWithTimeIntervalSince1970:([fireDateNumber doubleValue] / 1000.0)]; - localNotification.fireDate = fireDate; - - NSString *interval = schedule[@"repeatInterval"]; - if (interval) { - if ([interval isEqualToString:@"minute"]) { - localNotification.repeatInterval = NSCalendarUnitMinute; - } else if ([interval isEqualToString:@"hour"]) { - localNotification.repeatInterval = NSCalendarUnitHour; - } else if ([interval isEqualToString:@"day"]) { - localNotification.repeatInterval = NSCalendarUnitDay; - } else if ([interval isEqualToString:@"week"]) { - localNotification.repeatInterval = NSCalendarUnitWeekday; - } - } - - } - - return localNotification; -} - -- (UNNotificationRequest*) buildUNNotificationRequest:(NSDictionary *) notification - withSchedule:(BOOL) withSchedule NS_AVAILABLE_IOS(10_0) { - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; - if (notification[@"body"]) { - content.body = notification[@"body"]; - } - if (notification[@"data"]) { - content.userInfo = notification[@"data"]; - } - if (notification[@"sound"]) { - if ([@"default" isEqualToString:notification[@"sound"]]) { - content.sound = [UNNotificationSound defaultSound]; - } else { - content.sound = [UNNotificationSound soundNamed:notification[@"sound"]]; - } - } - if (notification[@"subtitle"]) { - content.subtitle = notification[@"subtitle"]; - } - if (notification[@"title"]) { - content.title = notification[@"title"]; - } - if (notification[@"ios"]) { - NSDictionary *ios = notification[@"ios"]; - if (ios[@"attachments"]) { - NSMutableArray *attachments = [[NSMutableArray alloc] init]; - for (NSDictionary *a in ios[@"attachments"]) { - NSString *identifier = a[@"identifier"]; - NSURL *url = [NSURL fileURLWithPath:a[@"url"]]; - NSMutableDictionary *attachmentOptions = nil; - - if (a[@"options"]) { - NSDictionary *options = a[@"options"]; - attachmentOptions = [[NSMutableDictionary alloc] init]; - - for (id key in options) { - if ([key isEqualToString:@"typeHint"]) { - attachmentOptions[UNNotificationAttachmentOptionsTypeHintKey] = options[key]; - } else if ([key isEqualToString:@"thumbnailHidden"]) { - attachmentOptions[UNNotificationAttachmentOptionsThumbnailHiddenKey] = options[key]; - } else if ([key isEqualToString:@"thumbnailClippingRect"]) { - attachmentOptions[UNNotificationAttachmentOptionsThumbnailClippingRectKey] = options[key]; - } else if ([key isEqualToString:@"thumbnailTime"]) { - attachmentOptions[UNNotificationAttachmentOptionsThumbnailTimeKey] = options[key]; - } - } - } - - NSError *error; - UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:identifier URL:url options:attachmentOptions error:&error]; - if (attachment) { - [attachments addObject:attachment]; - } else { - DLog(@"Failed to create attachment: %@", error); - } - } - content.attachments = attachments; - } - - if (ios[@"badge"]) { - content.badge = ios[@"badge"]; - } - if (ios[@"category"]) { - content.categoryIdentifier = ios[@"category"]; - } - if (ios[@"launchImage"]) { - content.launchImageName = ios[@"launchImage"]; - } - if (ios[@"threadIdentifier"]) { - content.threadIdentifier = ios[@"threadIdentifier"]; - } - } - - if (withSchedule) { - NSDictionary *schedule = notification[@"schedule"]; - NSNumber *fireDateNumber = schedule[@"fireDate"]; - NSString *interval = schedule[@"repeatInterval"]; - NSDate *fireDate = [NSDate dateWithTimeIntervalSince1970:([fireDateNumber doubleValue] / 1000.0)]; - - NSCalendarUnit calendarUnit; - if (interval) { - if ([interval isEqualToString:@"minute"]) { - calendarUnit = NSCalendarUnitSecond; - } else if ([interval isEqualToString:@"hour"]) { - calendarUnit = NSCalendarUnitMinute | NSCalendarUnitSecond; - } else if ([interval isEqualToString:@"day"]) { - calendarUnit = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; - } else if ([interval isEqualToString:@"week"]) { - calendarUnit = NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; - } else { - calendarUnit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; - } - } else { - // Needs to match exactly to the second - calendarUnit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; - } - - NSDateComponents *components = [[NSCalendar currentCalendar] components:calendarUnit fromDate:fireDate]; - UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:interval]; - return [UNNotificationRequest requestWithIdentifier:notification[@"notificationId"] content:content trigger:trigger]; - } else { - return [UNNotificationRequest requestWithIdentifier:notification[@"notificationId"] content:content trigger:nil]; - } -} - -- (NSDictionary*) parseUILocalNotification:(UILocalNotification *) localNotification { - NSMutableDictionary *notification = [[NSMutableDictionary alloc] init]; - - if (localNotification.alertBody) { - notification[@"body"] = localNotification.alertBody; - } - if (localNotification.userInfo) { - notification[@"data"] = localNotification.userInfo; - } - if (localNotification.soundName) { - notification[@"sound"] = localNotification.soundName; - } - if (localNotification.alertTitle) { - notification[@"title"] = localNotification.alertTitle; - } - - NSMutableDictionary *ios = [[NSMutableDictionary alloc] init]; - if (localNotification.alertAction) { - ios[@"alertAction"] = localNotification.alertAction; - } - if (localNotification.applicationIconBadgeNumber) { - ios[@"badge"] = @(localNotification.applicationIconBadgeNumber); - } - if (localNotification.category) { - ios[@"category"] = localNotification.category; - } - if (localNotification.hasAction) { - ios[@"hasAction"] = @(localNotification.hasAction); - } - if (localNotification.alertLaunchImage) { - ios[@"launchImage"] = localNotification.alertLaunchImage; - } - notification[@"ios"] = ios; - - return notification; -} - -- (NSDictionary*)parseUNNotificationResponse:(UNNotificationResponse *)response NS_AVAILABLE_IOS(10_0) { - NSMutableDictionary *notificationResponse = [[NSMutableDictionary alloc] init]; - NSDictionary *notification = [self parseUNNotification:response.notification]; - notificationResponse[@"notification"] = notification; - notificationResponse[@"action"] = response.actionIdentifier; - if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) { - notificationResponse[@"results"] = @{@"resultKey": ((UNTextInputNotificationResponse *)response).userText}; - } - - return notificationResponse; -} - -- (NSDictionary*)parseUNNotification:(UNNotification *)notification NS_AVAILABLE_IOS(10_0) { - return [self parseUNNotificationRequest:notification.request]; -} - -- (NSDictionary*) parseUNNotificationRequest:(UNNotificationRequest *) notificationRequest NS_AVAILABLE_IOS(10_0) { - NSMutableDictionary *notification = [[NSMutableDictionary alloc] init]; - - notification[@"notificationId"] = notificationRequest.identifier; - - if (notificationRequest.content.body) { - notification[@"body"] = notificationRequest.content.body; - } - if (notificationRequest.content.userInfo) { - NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; - for (id k in notificationRequest.content.userInfo) { - if ([k isEqualToString:@"aps"] - || [k isEqualToString:@"gcm.message_id"]) { - // ignore as these are handled by the OS - } else { - data[k] = notificationRequest.content.userInfo[k]; - } - } - notification[@"data"] = data; - } - if (notificationRequest.content.sound) { - notification[@"sound"] = notificationRequest.content.sound; - } - if (notificationRequest.content.subtitle) { - notification[@"subtitle"] = notificationRequest.content.subtitle; - } - if (notificationRequest.content.title) { - notification[@"title"] = notificationRequest.content.title; - } - - NSMutableDictionary *ios = [[NSMutableDictionary alloc] init]; - - if (notificationRequest.content.attachments) { - NSMutableArray *attachments = [[NSMutableArray alloc] init]; - for (UNNotificationAttachment *a in notificationRequest.content.attachments) { - NSMutableDictionary *attachment = [[NSMutableDictionary alloc] init]; - attachment[@"identifier"] = a.identifier; - attachment[@"type"] = a.type; - attachment[@"url"] = [a.URL absoluteString]; - [attachments addObject:attachment]; - } - ios[@"attachments"] = attachments; - } - - if (notificationRequest.content.badge) { - ios[@"badge"] = notificationRequest.content.badge; - } - if (notificationRequest.content.categoryIdentifier) { - ios[@"category"] = notificationRequest.content.categoryIdentifier; - } - if (notificationRequest.content.launchImageName) { - ios[@"launchImage"] = notificationRequest.content.launchImageName; - } - if (notificationRequest.content.threadIdentifier) { - ios[@"threadIdentifier"] = notificationRequest.content.threadIdentifier; - } - notification[@"ios"] = ios; - - return notification; -} - -- (NSDictionary*)parseUserInfo:(NSDictionary *)userInfo { - - NSMutableDictionary *notification = [[NSMutableDictionary alloc] init]; - NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; - NSMutableDictionary *ios = [[NSMutableDictionary alloc] init]; - - for (id k1 in userInfo) { - if ([k1 isEqualToString:@"aps"]) { - NSDictionary *aps = userInfo[k1]; - for (id k2 in aps) { - if ([k2 isEqualToString:@"alert"]) { - // alert can be a plain text string rather than a dictionary - if ([aps[k2] isKindOfClass:[NSDictionary class]]) { - NSDictionary *alert = aps[k2]; - for (id k3 in alert) { - if ([k3 isEqualToString:@"body"]) { - notification[@"body"] = alert[k3]; - } else if ([k3 isEqualToString:@"subtitle"]) { - notification[@"subtitle"] = alert[k3]; - } else if ([k3 isEqualToString:@"title"]) { - notification[@"title"] = alert[k3]; - } else if ([k3 isEqualToString:@"loc-args"] - || [k3 isEqualToString:@"loc-key"] - || [k3 isEqualToString:@"title-loc-args"] - || [k3 isEqualToString:@"title-loc-key"]) { - // Ignore known keys - } else { - DLog(@"Unknown alert key: %@", k2); - } - } - } else { - notification[@"title"] = aps[k2]; - } - } else if ([k2 isEqualToString:@"badge"]) { - ios[@"badge"] = aps[k2]; - } else if ([k2 isEqualToString:@"category"]) { - ios[@"category"] = aps[k2]; - } else if ([k2 isEqualToString:@"sound"]) { - notification[@"sound"] = aps[k2]; - } else { - DLog(@"Unknown aps key: %@", k2); - } - } - } else if ([k1 isEqualToString:@"gcm.message_id"]) { - notification[@"notificationId"] = userInfo[k1]; - } else if ([k1 isEqualToString:@"gcm.n.e"] - || [k1 isEqualToString:@"gcm.notification.sound2"] - || [k1 isEqualToString:@"google.c.a.c_id"] - || [k1 isEqualToString:@"google.c.a.c_l"] - || [k1 isEqualToString:@"google.c.a.e"] - || [k1 isEqualToString:@"google.c.a.udt"] - || [k1 isEqualToString:@"google.c.a.ts"]) { - // Ignore known keys - } else { - // Assume custom data - data[k1] = userInfo[k1]; - } - } - - notification[@"data"] = data; - notification[@"ios"] = ios; - - return notification; -} - -- (NSArray *)supportedEvents { - return @[NOTIFICATIONS_NOTIFICATION_DISPLAYED, NOTIFICATIONS_NOTIFICATION_OPENED, NOTIFICATIONS_NOTIFICATION_RECEIVED]; -} - -- (NSDictionary *) constantsToExport { - return @{ @"backgroundFetchResultNoData" : @(UIBackgroundFetchResultNoData), - @"backgroundFetchResultNewData" : @(UIBackgroundFetchResultNewData), - @"backgroundFetchResultFailed" : @(UIBackgroundFetchResultFailed)}; -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else -@implementation RNFirebaseNotifications -@end -#endif diff --git a/ios/RNFirebase/perf/RNFirebasePerformance.h b/ios/RNFirebase/perf/RNFirebasePerformance.h deleted file mode 100644 index 4871b158..00000000 --- a/ios/RNFirebase/perf/RNFirebasePerformance.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef RNFirebasePerformance_h -#define RNFirebasePerformance_h -#import - -#if __has_include() -#import - -@interface RNFirebasePerformance : NSObject { - -} - -@property NSMutableDictionary *traces; -@property NSMutableDictionary *httpMetrics; - -@end - -#else -@interface RNFirebasePerformance : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/perf/RNFirebasePerformance.m b/ios/RNFirebase/perf/RNFirebasePerformance.m deleted file mode 100644 index bdb6a68d..00000000 --- a/ios/RNFirebase/perf/RNFirebasePerformance.m +++ /dev/null @@ -1,270 +0,0 @@ -#import "RNFirebasePerformance.h" - -#if __has_include() -#import -#import -@implementation RNFirebasePerformance -RCT_EXPORT_MODULE(); - -- (id)init { - self = [super init]; - if (self != nil) { - _traces = [[NSMutableDictionary alloc] init]; - _httpMetrics = [[NSMutableDictionary alloc] init]; - } - return self; -} - -- (FIRHTTPMethod) mapStringToMethod:(NSString *) value { - if ([value compare:@"get" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodGET; - if ([value compare:@"put" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPUT; - if ([value compare:@"post" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPUT; - if ([value compare:@"delete" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodDELETE; - if ([value compare:@"head" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodHEAD; - if ([value compare:@"patch" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPATCH; - if ([value compare:@"options" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodOPTIONS; - if ([value compare:@"trace" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodTRACE; - if ([value compare:@"connect" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodCONNECT; - return FIRHTTPMethodGET; -} - - -- (FIRTrace *)getOrCreateTrace:(NSString *)identifier { - if (_traces[identifier]) { - return _traces[identifier]; - } - FIRTrace *trace = [[FIRPerformance sharedInstance] traceWithName:identifier]; - _traces[identifier] = trace; - return trace; -} - -- (FIRHTTPMetric *)getOrCreateHttpMetric:(NSString *)url httpMethod:(NSString *) httpMethod { - NSString *identifier = [NSString stringWithFormat:@"%@%@", url, httpMethod]; - if (_httpMetrics[identifier]) { - return _httpMetrics[identifier]; - } - NSURL * toURL = [NSURL URLWithString:url]; - FIRHTTPMethod method = [self mapStringToMethod:httpMethod]; - FIRHTTPMetric *httpMetric = [[FIRHTTPMetric alloc] initWithURL:toURL HTTPMethod:method]; - _httpMetrics[identifier] = httpMetric; - return httpMetric; -} - -RCT_EXPORT_METHOD(setPerformanceCollectionEnabled: - (BOOL *) enabled) { - [FIRPerformance sharedInstance].dataCollectionEnabled = (BOOL) enabled; -} - -/** - * Trace - */ - -RCT_EXPORT_METHOD(startTrace: - (NSString *) identifier - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateTrace:identifier] start]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(stopTrace: - (NSString *) identifier - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateTrace:identifier] stop]; - [_traces removeObjectForKey:identifier]; - - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(getTraceAttribute: - (NSString *) identifier - attribute:(NSString *) attribute - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *value = [[self getOrCreateTrace:identifier] valueForAttribute:attribute]; - resolve(value ? value : [NSNull null]); -} - -RCT_EXPORT_METHOD(getTraceAttributes: - (NSString *) identifier - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve([[self getOrCreateTrace:identifier] attributes]); -} - -RCT_EXPORT_METHOD(getTraceLongMetric: - (NSString *) identifier - metricName:(NSString *) metricName - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - int64_t value = [[self getOrCreateTrace:identifier] valueForIntMetric:metricName]; - resolve(@(value)); -} - -RCT_EXPORT_METHOD(incrementTraceMetric: - (NSString *) identifier - metricName:(NSString *) metricName - incrementBy:(nonnull NSNumber *) incrementBy - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - int64_t byInt = [incrementBy intValue]; - [[self getOrCreateTrace:identifier] incrementMetric:metricName byInt:byInt]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(putTraceAttribute: - (NSString *) identifier - attribute:(NSString *) attribute - value:(NSString *) value - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRTrace * trace = [self getOrCreateTrace:identifier]; - [trace setValue:value forAttribute:attribute]; - - if (trace.attributes[attribute] != nil) { - resolve(@(YES)); - } else { - resolve(@(NO)); - } -} - -RCT_EXPORT_METHOD(putTraceMetric: - (NSString *) identifier - attribute:(NSString *) attribute - value:(nonnull NSNumber *) value - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - int64_t byInt = [value intValue]; - [[self getOrCreateTrace:identifier] setIntValue:byInt forMetric:attribute]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(removeTraceAttribute: - (NSString *) identifier - attribute:(NSString *) attribute - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateTrace:identifier] removeAttribute:attribute]; - resolve([NSNull null]); -} - -/** - * HTTP Metric - */ - -RCT_EXPORT_METHOD(startHttpMetric: - (NSString *) url - httpMethod:(NSString *) httpMethod - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] start]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(stopHttpMetric: - (NSString *) url - httpMethod:(NSString *) httpMethod - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] stop]; - [_httpMetrics removeObjectForKey:[NSString stringWithFormat:@"%@%@", url, httpMethod]]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(getHttpMetricAttribute: - (NSString *) url - httpMethod:(NSString *) httpMethod - attribute:(NSString *) attribute - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *value = [[self getOrCreateHttpMetric:url httpMethod:httpMethod] valueForAttribute:attribute]; - resolve(value ? value : [NSNull null]); -} - -RCT_EXPORT_METHOD(getHttpMetricAttributes: - (NSString *) url - httpMethod:(NSString *) httpMethod - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve([[self getOrCreateHttpMetric:url httpMethod:httpMethod] attributes]); -} - -RCT_EXPORT_METHOD(putHttpMetricAttribute: - (NSString *) url - httpMethod:(NSString *) httpMethod - attribute:(NSString *) attribute - value:(NSString *) value - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - FIRHTTPMetric * httpMetric = [self getOrCreateHttpMetric:url httpMethod:httpMethod]; - [httpMetric setValue:value forAttribute:attribute]; - - if (httpMetric.attributes[attribute] != nil) { - resolve(@(YES)); - } else { - resolve(@(NO)); - } -} - -RCT_EXPORT_METHOD(removeHttpMetricAttribute: - (NSString *) url - httpMethod:(NSString *) httpMethod - attribute:(NSString *) attribute - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] removeAttribute:attribute]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(setHttpMetricResponseCode: - (NSString *) url - httpMethod:(NSString *) httpMethod - code:(nonnull NSNumber *) code - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponseCode:[code integerValue]]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(setHttpMetricRequestPayloadSize: - (NSString *) url - httpMethod:(NSString *) httpMethod - bytes:(nonnull NSNumber *) bytes - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] setRequestPayloadSize:[bytes longLongValue]]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(setHttpMetricResponseContentType: - (NSString *) url - httpMethod:(NSString *) httpMethod - type:(NSString *) type - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponseContentType:type]; - resolve([NSNull null]); -} - -RCT_EXPORT_METHOD(setHttpMetricResponsePayloadSize: - (NSString *) url - httpMethod:(NSString *) httpMethod - bytes:(nonnull NSNumber *) bytes - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponsePayloadSize:[bytes longLongValue]]; - resolve([NSNull null]); -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else -@implementation RNFirebasePerformance -@end -#endif diff --git a/ios/RNFirebase/storage/RNFirebaseStorage.h b/ios/RNFirebase/storage/RNFirebaseStorage.h deleted file mode 100644 index 202bf98d..00000000 --- a/ios/RNFirebase/storage/RNFirebaseStorage.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef RNFirebaseStorage_h -#define RNFirebaseStorage_h -#import - -#if __has_include() -#import -#import - -@interface RNFirebaseStorage : RCTEventEmitter { - -} - -@end - -#else -@interface RNFirebaseStorage : NSObject -@end -#endif - -#endif diff --git a/ios/RNFirebase/storage/RNFirebaseStorage.m b/ios/RNFirebase/storage/RNFirebaseStorage.m deleted file mode 100644 index 7d879724..00000000 --- a/ios/RNFirebase/storage/RNFirebaseStorage.m +++ /dev/null @@ -1,547 +0,0 @@ -#import "RNFirebaseStorage.h" - -#if __has_include() - -#import "RNFirebaseEvents.h" -#import "RNFirebaseUtil.h" -#import -#import -#import -#import - -@implementation RNFirebaseStorage - -RCT_EXPORT_MODULE(RNFirebaseStorage); - -// Run on a different thread -- (dispatch_queue_t)methodQueue { - return dispatch_queue_create("io.invertase.react-native-firebase.storage", DISPATCH_QUEUE_SERIAL); -} - -/** - delete - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete - @param NSString path - */ -RCT_EXPORT_METHOD(delete:(NSString *) appDisplayName - path:(NSString *) path - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - - [fileRef deleteWithCompletion:^(NSError *_Nullable error) { - if (error != nil) { - [self promiseRejectStorageException:reject error:error]; - } else { - resolve([NSNull null]); - } - }]; -} - -/** - getDownloadURL - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL - @param NSString path - */ -RCT_EXPORT_METHOD(getDownloadURL:(NSString *) appDisplayName - path:(NSString *) path - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - - [fileRef downloadURLWithCompletion:^(NSURL *_Nullable URL, NSError *_Nullable error) { - if (error != nil) { - [self promiseRejectStorageException:reject error:error]; - } else { - resolve([URL absoluteString]); - } - }]; -} - -/** - getMetadata - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata - @param NSString path - */ -RCT_EXPORT_METHOD(getMetadata:(NSString *) appDisplayName - path:(NSString *) path - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - - [fileRef metadataWithCompletion:^(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error) { - if (error != nil) { - [self promiseRejectStorageException:reject error:error]; - } else { - resolve([metadata dictionaryRepresentation]); - } - }]; -} - -/** - updateMetadata - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata - @param NSString path - @param NSDictionary metadata - */ -RCT_EXPORT_METHOD(updateMetadata:(NSString *) appDisplayName - path:(NSString *) path - metadata:(NSDictionary *) metadata - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - FIRStorageMetadata *firmetadata = [self buildMetadataFromMap:metadata]; - - [fileRef updateMetadata:firmetadata completion:^(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error) { - if (error != nil) { - [self promiseRejectStorageException:reject error:error]; - } else { - resolve([metadata dictionaryRepresentation]); - } - }]; -} - -/** - downloadFile - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#downloadFile - @param NSString path - @param NSString localPath - */ -RCT_EXPORT_METHOD(downloadFile:(NSString *) appDisplayName - path:(NSString *) path - localPath:(NSString *) localPath - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - NSURL *localFile = [NSURL fileURLWithPath:localPath]; - - __block FIRStorageDownloadTask *downloadTask; - RCTUnsafeExecuteOnMainQueueSync(^{ - downloadTask = [fileRef writeToFile:localFile]; - }); - - // listen for state changes, errors, and completion of the download. - [downloadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) { - // download resumed, also fires when the upload starts - NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - - [downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { - // download paused - NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - - [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { - // download reported progress - NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - - [downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { - // download completed successfully - NSDictionary *resp = [self getDownloadTaskAsDictionary:snapshot]; - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_DOWNLOAD_SUCCESS props:resp]; - resolve(resp); - }]; - - [downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { - // download task failed - // TODO sendJSError event - if (snapshot.error != nil) { - [self promiseRejectStorageException:reject error:snapshot.error]; - } - }]; -} - -/** - setMaxDownloadRetryTime - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxDownloadRetryTime - @param NSNumber milliseconds - */ -RCT_EXPORT_METHOD(setMaxDownloadRetryTime:(NSString *) appDisplayName - milliseconds:(nonnull NSNumber *) milliseconds) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [[FIRStorage storageForApp:firApp] setMaxDownloadRetryTime:[milliseconds doubleValue]]; -} - -/** - setMaxOperationRetryTime - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime - @param NSNumber milliseconds - */ -RCT_EXPORT_METHOD(setMaxOperationRetryTime:(NSString *) appDisplayName - milliseconds:(nonnull NSNumber *) milliseconds) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [[FIRStorage storageForApp:firApp] setMaxOperationRetryTime:[milliseconds doubleValue]]; -} - -/** - setMaxUploadRetryTime - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime - */ -RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSString *) appDisplayName - milliseconds:(nonnull NSNumber *) milliseconds) { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - [[FIRStorage storageForApp:firApp] setMaxUploadRetryTime:[milliseconds doubleValue]]; -} - -/** - putFile - - @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putFile - @param NSString path - @param NSString localPath - @param NSDictionary metadata - */ -RCT_EXPORT_METHOD(putFile:(NSString *) appDisplayName - path:(NSString *) path - localPath:(NSString *) localPath - metadata:(NSDictionary *) metadata - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - FIRStorageMetadata *firmetadata = [self buildMetadataFromMap:metadata]; - - if ([localPath hasPrefix:@"assets-library://"] || [localPath hasPrefix:@"ph://"]) { - PHFetchResult *assets; - - if ([localPath hasPrefix:@"assets-library://"]) { - NSURL *localFile = [[NSURL alloc] initWithString:localPath]; - assets = [PHAsset fetchAssetsWithALAssetURLs:@[localFile] options:nil]; - } else { - NSString *assetId = [localPath substringFromIndex:@"ph://".length]; - assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]; - } - - PHAsset *asset = [assets firstObject]; - - // this is based on http://stackoverflow.com/questions/35241449 - if (asset.mediaType == PHAssetMediaTypeImage) { - // images - PHImageRequestOptions *options = [PHImageRequestOptions new]; - options.networkAccessAllowed = true; - [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { - if (info[PHImageErrorKey] == nil) { - if ( - UTTypeConformsTo((__bridge CFStringRef) dataUTI, kUTTypeJPEG) || - UTTypeConformsTo((__bridge CFStringRef) dataUTI, kUTTypePNG) || - UTTypeConformsTo((__bridge CFStringRef) dataUTI, kUTTypeGIF) - ) { - firmetadata.contentType = [self utiToMimeType:dataUTI]; - [self uploadData:appDisplayName data:imageData firmetadata:firmetadata path:path resolver:resolve rejecter:reject]; - } else { - // all other image types are converted to JPEG, e.g. HEI - CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); - NSDictionary *imageInfo = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); - NSDictionary *imageMetadata = [imageInfo copy]; - NSMutableData *imageDataJPEG = [NSMutableData data]; - CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageDataJPEG, kUTTypeJPEG, 1, NULL); - CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)imageMetadata); - CGImageDestinationFinalize(destination); - // Manually set mimetype to JPEG - firmetadata.contentType = @"image/jpeg"; - [self uploadData:appDisplayName data:[NSData dataWithData:imageDataJPEG] firmetadata:firmetadata path:path resolver:resolve rejecter:reject]; - } - } else { - reject(@"storage/request-image-data-failed", @"Could not obtain image data for the specified file.", nil); - } - }]; - } else if (asset.mediaType == PHAssetMediaTypeVideo) { - // video - PHVideoRequestOptions *options = [PHVideoRequestOptions new]; - options.networkAccessAllowed = true; - [[PHImageManager defaultManager] requestExportSessionForVideo:asset options:options exportPreset:AVAssetExportPresetHighestQuality resultHandler:^(AVAssetExportSession *_Nullable exportSession, NSDictionary *_Nullable info) { - if (info[PHImageErrorKey] == nil) { - NSURL *tempUrl = [self temporaryFileUrl]; - exportSession.outputURL = tempUrl; - - NSArray *resources = [PHAssetResource assetResourcesForAsset:asset]; - for (PHAssetResource *resource in resources) { - exportSession.outputFileType = resource.uniformTypeIdentifier; - if (exportSession.outputFileType != nil) break; - } - - [exportSession exportAsynchronouslyWithCompletionHandler:^{ - if (exportSession.status == AVAssetExportSessionStatusCompleted) { - firmetadata.contentType = [self utiToMimeType:exportSession.outputFileType]; - [self uploadFile:appDisplayName url:tempUrl firmetadata:firmetadata path:path resolver:resolve rejecter:reject]; - // TODO we're not cleaning up the temporary file at the moment, relying on the OS to do it - } else { - reject(@"storage/temporary-file-failure", @"Unable to create temporary file for upload.", nil); - } - }]; - } else { - reject(@"storage/export-session-failure", @"Unable to create export session for asset.", nil); - } - }]; - } - } else { - if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) { - reject(@"storage/file-not-found", @"File specified at path does not exist.", nil); - return; - } - - // TODO large files should not go through 'data', should use file directly - // TODO heic conversion not working here UIImageJPEGRepresentation -> returns nil - - // BOOL isHeic = [self isHeic:localPath]; - NSData *data = [NSData dataWithContentsOfFile:localPath]; - - if ([firmetadata valueForKey:@"contentType"] == nil) { - firmetadata.contentType = [self mimeTypeForPath:localPath]; - } - - // if (isHeic) { - // UIImage *image = [UIImage imageWithData: data]; - // data = UIImageJPEGRepresentation(image, 1); - // firmetadata.contentType = @"image/jpeg"; - // } - - [self uploadData:appDisplayName data:data firmetadata:firmetadata path:path resolver:resolve rejecter:reject]; - } -} - --(BOOL) isHeic: (NSString*) path { - return [[path pathExtension] caseInsensitiveCompare:@"heic"] == NSOrderedSame; -} - -- (NSString *)utiToMimeType:(NSString *) dataUTI { - return (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)dataUTI, kUTTagClassMIMEType); -} - -- (NSURL *)temporaryFileUrl { - NSString *filename = [NSString stringWithFormat:@"%@.tmp", [[NSProcessInfo processInfo] globallyUniqueString]]; - return [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:filename]; -} - -- (NSString*) mimeTypeForPath: (NSString *) path { - CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL); - CFStringRef mimeType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType); - CFRelease(UTI); - - if (!mimeType) { - return @"application/octet-stream"; - } - - return (__bridge_transfer NSString *) mimeType; -} - -- (void)uploadFile:(NSString *)appDisplayName url:(NSURL *)url firmetadata:(FIRStorageMetadata *)firmetadata path:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - __block FIRStorageUploadTask *uploadTask; - RCTUnsafeExecuteOnMainQueueSync(^{ - uploadTask = [fileRef putFile:url metadata:firmetadata]; - }); - [self addUploadObservers:appDisplayName uploadTask:uploadTask path:path resolver:resolve rejecter:reject]; -} - -- (void)uploadData:(NSString *)appDisplayName data:(NSData *)data firmetadata:(FIRStorageMetadata *)firmetadata path:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { - FIRStorageReference *fileRef = [self getReference:path appDisplayName:appDisplayName]; - __block FIRStorageUploadTask *uploadTask; - RCTUnsafeExecuteOnMainQueueSync(^{ - uploadTask = [fileRef putData:data metadata:firmetadata]; - }); - [self addUploadObservers:appDisplayName uploadTask:uploadTask path:path resolver:resolve rejecter:reject]; -} - -- (void)addUploadObservers:(NSString *)appDisplayName uploadTask:(FIRStorageUploadTask *)uploadTask path:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { - // listen for state changes, errors, and completion of the upload. - [uploadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) { - // upload resumed, also fires when the upload starts - [self getUploadTaskAsDictionary:snapshot handler:^(NSDictionary *event) { - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - }]; - - [uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { - // upload paused - [self getUploadTaskAsDictionary:snapshot handler:^(NSDictionary *event) { - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - }]; - [uploadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { - // upload reported progress - [self getUploadTaskAsDictionary:snapshot handler:^(NSDictionary *event) { - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - }]; - }]; - - [uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { - // upload completed successfully - [self getUploadTaskAsDictionary:snapshot handler:^(NSDictionary *event) { - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; - [self sendJSEvent:appDisplayName type:STORAGE_EVENT path:path title:STORAGE_UPLOAD_SUCCESS props:event]; - resolve(event); - }]; - }]; - - [uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { - if (snapshot.error != nil) { - [self promiseRejectStorageException:reject error:snapshot.error]; - } - }]; -} - -- (FIRStorageReference *)getReference:(NSString *)path - appDisplayName:(NSString *)appDisplayName { - FIRApp *firApp = [RNFirebaseUtil getApp:appDisplayName]; - if ([path hasPrefix:@"url::"]) { - NSString *url = [path substringFromIndex:5]; - return [[FIRStorage storageForApp:firApp] referenceForURL:url]; - } else { - return [[FIRStorage storageForApp:firApp] referenceWithPath:path]; - } -} - -- (NSDictionary *)getDownloadTaskAsDictionary:(FIRStorageTaskSnapshot *)task { - return @{@"bytesTransferred": @(task.progress.completedUnitCount), @"ref": task.reference.fullPath, @"state": [self getTaskStatus:task.status], @"totalBytes": @(task.progress.totalUnitCount)}; -} - -- (void)getUploadTaskAsDictionary:(FIRStorageTaskSnapshot *)task - handler:(void(^)(NSDictionary *))handler { - [[task reference] downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) { - NSString *downloadUrl = [URL absoluteString]; - NSDictionary *metadata = [task.metadata dictionaryRepresentation]; - NSDictionary *dictionary = @{@"bytesTransferred": @(task.progress.completedUnitCount), @"downloadURL": downloadUrl != nil ? downloadUrl : [NSNull null], @"metadata": metadata != nil ? metadata : [NSNull null], @"ref": task.reference.fullPath, @"state": [self getTaskStatus:task.status], @"totalBytes": @(task.progress.totalUnitCount)}; - handler(dictionary); - }]; -} - -- (FIRStorageMetadata *)buildMetadataFromMap:(NSDictionary *)metadata { - FIRStorageMetadata *storageMetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; - storageMetadata.customMetadata = [metadata[@"customMetadata"] mutableCopy]; - return storageMetadata; -} - -- (NSString *)getTaskStatus:(FIRStorageTaskStatus)status { - if (status == FIRStorageTaskStatusResume || status == FIRStorageTaskStatusProgress) { - return @"running"; - } else if (status == FIRStorageTaskStatusPause) { - return @"paused"; - } else if (status == FIRStorageTaskStatusSuccess) { - return @"success"; - } else if (status == FIRStorageTaskStatusFailure) { - return @"error"; - } else { - return @"unknown"; - } -} - -- (NSString *)getPathForDirectory:(int)directory { - NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES); - return [paths firstObject]; -} - -- (NSDictionary *)constantsToExport { - return @{@"MAIN_BUNDLE_PATH": [[NSBundle mainBundle] bundlePath], @"CACHES_DIRECTORY_PATH": [self getPathForDirectory:NSCachesDirectory], @"DOCUMENT_DIRECTORY_PATH": [self getPathForDirectory:NSDocumentDirectory], @"EXTERNAL_DIRECTORY_PATH": [NSNull null], @"EXTERNAL_STORAGE_DIRECTORY_PATH": [NSNull null], @"TEMP_DIRECTORY_PATH": NSTemporaryDirectory(), @"LIBRARY_DIRECTORY_PATH": [self getPathForDirectory:NSLibraryDirectory], @"FILETYPE_REGULAR": NSFileTypeRegular, @"FILETYPE_DIRECTORY": NSFileTypeDirectory}; -} - -- (NSArray *)supportedEvents { - return @[STORAGE_EVENT, STORAGE_ERROR]; -} - -- (void)sendJSError:(NSString *)appDisplayName error:(NSError *)error path:(NSString *)path { - NSDictionary *evt = @{@"path": path, @"message": [error debugDescription]}; - [self sendJSEvent:appDisplayName type:STORAGE_ERROR path:path title:STORAGE_ERROR props:evt]; -} - -- (void)sendJSEvent:(NSString *)appDisplayName type:(NSString *)type path:(NSString *)path title:(NSString *)title props:(NSDictionary *)props { - [RNFirebaseUtil sendJSEvent:self name:type body:@{@"eventName": title, @"appName": appDisplayName, @"path": path, @"body": props}]; -} - -/** - Reject a promise with a storage exception - - @param reject RCTPromiseRejectBlock - @param error NSError - */ -- (void)promiseRejectStorageException:(RCTPromiseRejectBlock)reject error:(NSError *)error { - NSString *code = @"storage/unknown"; - NSString *message = [error localizedDescription]; - - NSDictionary *userInfo = [error userInfo]; - NSError *underlyingError = userInfo[NSUnderlyingErrorKey]; - NSString *underlyingErrorDescription = [underlyingError localizedDescription]; - - switch (error.code) { - case FIRStorageErrorCodeUnknown: - if ([underlyingErrorDescription isEqualToString:@"The operation couldn’t be completed. Permission denied"]) { - code = @"storage/invalid-device-file-path"; - message = @"The specified device file path is invalid or is restricted."; - } else { - code = @"storage/unknown"; - message = @"An unknown error has occurred."; - } - break; - case FIRStorageErrorCodeObjectNotFound: - code = @"storage/object-not-found"; - message = @"No object exists at the desired reference."; - break; - case FIRStorageErrorCodeBucketNotFound: - code = @"storage/bucket-not-found"; - message = @"No bucket is configured for Firebase Storage."; - break; - case FIRStorageErrorCodeProjectNotFound: - code = @"storage/project-not-found"; - message = @"No project is configured for Firebase Storage."; - break; - case FIRStorageErrorCodeQuotaExceeded: - code = @"storage/quota-exceeded"; - message = @"Quota on your Firebase Storage bucket has been exceeded."; - break; - case FIRStorageErrorCodeUnauthenticated: - code = @"storage/unauthenticated"; - message = @"User is unauthenticated. Authenticate and try again."; - break; - case FIRStorageErrorCodeUnauthorized: - code = @"storage/unauthorized"; - message = @"User is not authorized to perform the desired action."; - break; - case FIRStorageErrorCodeRetryLimitExceeded: - code = @"storage/retry-limit-exceeded"; - message = @"The maximum time limit on an operation (upload, download, delete, etc.) has been exceeded."; - break; - case FIRStorageErrorCodeNonMatchingChecksum: - code = @"storage/non-matching-checksum"; - message = @"File on the client does not match the checksum of the file received by the server."; - break; - case FIRStorageErrorCodeDownloadSizeExceeded: - code = @"storage/download-size-exceeded"; - message = @"Size of the downloaded file exceeds the amount of memory allocated for the download."; - break; - case FIRStorageErrorCodeCancelled: - code = @"storage/cancelled"; - message = @"User cancelled the operation."; - break; - default: - break; - } - - if (userInfo != nil && userInfo[@"data"]) { - // errors with 'data' are unserializable - it breaks react so we send nil instead - reject(code, message, nil); - } else { - reject(code, message, error); - } -} - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -@end - -#else -@implementation RNFirebaseStorage -@end -#endif diff --git a/lerna.json b/lerna.json new file mode 100644 index 00000000..f629f79b --- /dev/null +++ b/lerna.json @@ -0,0 +1,22 @@ +{ + "npmClient": "yarn", + "npmClientArgs": [ + "--no-lockfile" + ], + "packages": [ + "packages/*", + "tests" + ], + "useWorkspaces": true, + "command": { + "publish": { + "ignoreChanges": [ + "*.md" + ] + }, + "bootstrap": { + "ignore": "*-template-*" + } + }, + "version": "6.0.0-alpha.1" +} diff --git a/metro.config.js b/metro.config.js new file mode 100644 index 00000000..4c276fd6 --- /dev/null +++ b/metro.config.js @@ -0,0 +1 @@ +module.exports = require('./tests/metro.config'); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2e06a9f5..00000000 --- a/package-lock.json +++ /dev/null @@ -1,9131 +0,0 @@ -{ - "name": "react-native-firebase", - "version": "5.2.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/cli": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.1.5.tgz", - "integrity": "sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw==", - "dev": true, - "requires": { - "chokidar": "^2.0.3", - "commander": "^2.8.1", - "convert-source-map": "^1.1.0", - "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", - "lodash": "^4.17.10", - "mkdirp": "^0.5.1", - "output-file-sync": "^2.0.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" - } - }, - "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.1.6.tgz", - "integrity": "sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.1.6", - "@babel/helpers": "^7.1.5", - "@babel/parser": "^7.1.6", - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.6", - "@babel/types": "^7.1.6", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.10", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz", - "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==", - "dev": true, - "requires": { - "@babel/types": "^7.2.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.10", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz", - "integrity": "sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "esutils": "^2.0.0" - } - }, - "@babel/helper-call-delegate": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", - "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.0.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.2.3.tgz", - "integrity": "sha512-xO/3Gn+2C7/eOUeb0VRnSP1+yvWHNxlpAot1eMhtoKDCN7POsyQP5excuT5UsV5daHxMWBeIIOeI5cmB8vMRgQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.2.3" - } - }, - "@babel/helper-define-map": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", - "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.0.0", - "lodash": "^4.17.10" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", - "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", - "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/template": "^7.2.2", - "@babel/types": "^7.2.2", - "lodash": "^4.17.10" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", - "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz", - "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.2.3", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, - "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } - }, - "@babel/helpers": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz", - "integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==", - "dev": true, - "requires": { - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.5", - "@babel/types": "^7.2.0" - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz", - "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==", - "dev": true - }, - "@babel/plugin-external-helpers": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz", - "integrity": "sha512-QFmtcCShFkyAsNtdCM3lJPmRe1iB+vPZymlB4LnDIKEBj2yKQLQKtoxXxJ8ePT5fwMl4QGg303p4mB0UsSI2/g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.2.3.tgz", - "integrity": "sha512-FVuQngLoN2iDrpW7LmhPZ2sO4DJxf35FOcwidwB9Ru9tMvI5URthnkVHuG14IStV+TzkMTyLMoOUlSTtrdVwqw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.2.3", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-proposal-export-default-from": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.2.0.tgz", - "integrity": "sha512-NVfNe7F6nsasG1FnvcFxh2FN0l04ZNe75qTOAVOILWPam0tw9a63RtT/Dab8dPjedZa4fTQaQ83yMMywF9OSug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-export-default-from": "^7.2.0" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.2.0.tgz", - "integrity": "sha512-QXj/YjFuFJd68oDvoc1e8aqLr2wz7Kofzvp6Ekd/o7MWZl+nZ0/cpStxND+hlZ7DpRWAp7OmuyT2areZ2V3YUA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.2.0" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.2.0.tgz", - "integrity": "sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-chaining": "^7.2.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz", - "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-export-default-from": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz", - "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", - "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", - "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz", - "integrity": "sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz", - "integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.2.0.tgz", - "integrity": "sha512-WhKr6yu6yGpGcNMVgIBuI9MkredpVc7Y3YR4UzEZmDztHoL6wV56YBHLhWnjO1EvId1B32HrD3DRFc+zSoKI1g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz", - "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz", - "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.10" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz", - "integrity": "sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.1.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz", - "integrity": "sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-flow-comments": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-comments/-/plugin-transform-flow-comments-7.2.0.tgz", - "integrity": "sha512-o0EyefxfyCn9GhwvXMPP6P/DKmcHDwJ5UcUussaLUDSuPOU78YOUU76u/QIucOv/1wtMdLmepWZeYvnyoOSuyw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.2.0" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.2.3.tgz", - "integrity": "sha512-xnt7UIk9GYZRitqCnsVMjQK1O2eKZwFB3CvvHjf5SGx6K6vr/MScCKQDnf1DxRaj501e3pXjti+inbSXX2ZUoQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.2.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", - "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", - "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", - "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/plugin-transform-object-assign": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz", - "integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz", - "integrity": "sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.1.0", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", - "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.2.0.tgz", - "integrity": "sha512-h/fZRel5wAfCqcKgq3OhbmYaReo7KkoJBpt8XnvpS7wqaNMqtw5xhxutzcm35iMUWucfAdT/nvGTsWln0JTg2Q==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", - "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz", - "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", - "dev": true, - "requires": { - "regenerator-transform": "^0.13.3" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", - "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.2.0.tgz", - "integrity": "sha512-EnI7i2/gJ7ZNr2MuyvN2Hu+BHJENlxWte5XygPvfj/MbvtOkWor9zcnHpMMQL2YYaaCcqtIvJUyJ7QVfoGs7ew==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-typescript": "^7.2.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", - "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0", - "regexpu-core": "^4.1.3" - } - }, - "@babel/register": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.0.0.tgz", - "integrity": "sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g==", - "dev": true, - "requires": { - "core-js": "^2.5.7", - "find-cache-dir": "^1.0.0", - "home-or-tmp": "^3.0.0", - "lodash": "^4.17.10", - "mkdirp": "^0.5.1", - "pirates": "^4.0.0", - "source-map-support": "^0.5.9" - }, - "dependencies": { - "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==", - "dev": true - }, - "home-or-tmp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz", - "integrity": "sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.1.5.tgz", - "integrity": "sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.12.0" - } - }, - "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" - } - }, - "@babel/traverse": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", - "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.2.3", - "@babel/types": "^7.2.2", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.10" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz", - "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.10", - "to-fast-properties": "^2.0.0" - } - }, - "@invertase/babel-preset-react-native-syntax": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@invertase/babel-preset-react-native-syntax/-/babel-preset-react-native-syntax-0.1.3.tgz", - "integrity": "sha512-c5Wl6mxaik2eXd6XbnvCPNNJehLncd1uDnHvy5Dx45VWEV3BG/7My5KKDLgBdxrigyQy50Jog0qLZm+92pOyRA==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.0.0", - "@babel/plugin-syntax-class-properties": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.0.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.0.0", - "@babel/plugin-syntax-optional-chaining": "^7.0.0", - "@babel/plugin-syntax-typescript": "^7.0.0", - "@babel/plugin-transform-flow-comments": "^7.0.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0" - } - }, - "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", - "dev": true, - "requires": { - "any-observable": "^0.3.0" - } - }, - "absolute-path": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", - "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", - "dev": true - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "acorn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", - "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", - "dev": true - }, - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", - "dev": true - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "any-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", - "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "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.2" - } - }, - "argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", - "dev": true - }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "art": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/art/-/art-0.10.3.tgz", - "integrity": "sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "axios": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", - "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", - "dev": true, - "requires": { - "follow-redirects": "^1.3.0", - "is-buffer": "^1.1.5" - } - }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, - "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": { - "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 - }, - "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.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "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 - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "babel-eslint": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-9.0.0.tgz", - "integrity": "sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, - "babel-helper-builder-react-jsx": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", - "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "esutils": "^2.0.2" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "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": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "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": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "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": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", - "dev": true - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", - "dev": true - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "dev": true, - "requires": { - "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-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "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": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "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": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "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-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "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": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es3-member-expression-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es3-member-expression-literals/-/babel-plugin-transform-es3-member-expression-literals-6.22.0.tgz", - "integrity": "sha1-cz00RPPsxBvvjtGmpOCWV7iWnrs=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es3-property-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es3-property-literals/-/babel-plugin-transform-es3-property-literals-6.22.0.tgz", - "integrity": "sha1-sgeNWELiKr9A9z6M3pzTcRq9V1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", - "dev": true, - "requires": { - "babel-plugin-syntax-flow": "^6.18.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-react-display-name": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", - "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", - "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", - "dev": true, - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-fbjs": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-2.3.0.tgz", - "integrity": "sha512-ZOpAI1/bN0Y3J1ZAK9gRsFkHy9gGgJoDRUjtUCla/129LC7uViq9nIK22YdHfey8szohYoZY3f9L2lGOv0Edqw==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.8.0", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-plugin-syntax-flow": "^6.8.0", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-plugin-syntax-trailing-function-commas": "^6.8.0", - "babel-plugin-transform-class-properties": "^6.8.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.8.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.8.0", - "babel-plugin-transform-es2015-block-scoping": "^6.8.0", - "babel-plugin-transform-es2015-classes": "^6.8.0", - "babel-plugin-transform-es2015-computed-properties": "^6.8.0", - "babel-plugin-transform-es2015-destructuring": "^6.8.0", - "babel-plugin-transform-es2015-for-of": "^6.8.0", - "babel-plugin-transform-es2015-function-name": "^6.8.0", - "babel-plugin-transform-es2015-literals": "^6.8.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.8.0", - "babel-plugin-transform-es2015-object-super": "^6.8.0", - "babel-plugin-transform-es2015-parameters": "^6.8.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.8.0", - "babel-plugin-transform-es2015-spread": "^6.8.0", - "babel-plugin-transform-es2015-template-literals": "^6.8.0", - "babel-plugin-transform-es3-member-expression-literals": "^6.8.0", - "babel-plugin-transform-es3-property-literals": "^6.8.0", - "babel-plugin-transform-flow-strip-types": "^6.8.0", - "babel-plugin-transform-object-rest-spread": "^6.8.0", - "babel-plugin-transform-react-display-name": "^6.8.0", - "babel-plugin-transform-react-jsx": "^6.8.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "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": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "big-integer": { - "version": "1.6.40", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.40.tgz", - "integrity": "sha512-CjhtJp0BViLzP1ZkEnoywjgtFQXS2pomKjAJtIISTCnuHILkLcAXLdFLG/nxsHc4s9kJfc+82Xpg8WNyhfACzQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", - "dev": true - }, - "bplist-creator": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", - "integrity": "sha1-N98VNgkoJLh8QvlXsBNEEXNyrkU=", - "dev": true, - "requires": { - "stream-buffers": "~2.2.0" - } - }, - "bplist-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", - "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", - "dev": true, - "requires": { - "big-integer": "^1.6.7" - } - }, - "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" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "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 - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "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" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "capture-exit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", - "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", - "dev": true, - "requires": { - "rsvp": "^3.3.3" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "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.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "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" - } - }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "codecov": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.1.0.tgz", - "integrity": "sha512-aWQc/rtHbcWEQLka6WmBAOpV58J2TwyXqlpAQGhQaSiEUoigTTUk6lLd2vB3kXkhnDyzyH74RXfmV4dq2txmdA==", - "dev": true, - "requires": { - "argv": "^0.0.2", - "ignore-walk": "^3.0.1", - "js-yaml": "^3.12.0", - "request": "^2.87.0", - "urlgrey": "^0.4.4" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", - "dev": true, - "requires": { - "mime-db": ">= 1.36.0 < 2" - } - }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "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 - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - } - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", - "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "create-react-class": { - "version": "15.6.3", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", - "dev": true, - "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "damerau-levenshtein": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", - "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true - }, - "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "envinfo": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.12.1.tgz", - "integrity": "sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "errorhandler": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.0.tgz", - "integrity": "sha1-6rpkyl1UKjEayUX1gt78M2Fl2fQ=", - "dev": true, - "requires": { - "accepts": "~1.3.3", - "escape-html": "~1.0.3" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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 - }, - "eslint": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.9.0.tgz", - "integrity": "sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.5.3", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "imurmurhash": "^0.1.4", - "inquirer": "^6.1.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.12.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.0.2", - "text-table": "^0.2.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "eslint-config-airbnb": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz", - "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^13.1.0", - "object.assign": "^4.1.0", - "object.entries": "^1.0.4" - } - }, - "eslint-config-airbnb-base": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", - "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", - "dev": true, - "requires": { - "eslint-restricted-globals": "^0.1.1", - "object.assign": "^4.1.0", - "object.entries": "^1.0.4" - } - }, - "eslint-config-prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz", - "integrity": "sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - } - }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" - } - }, - "eslint-plugin-flowtype": { - "version": "2.50.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", - "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "eslint-plugin-import": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", - "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", - "dev": true, - "requires": { - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0", - "resolve": "^1.6.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz", - "integrity": "sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw==", - "dev": true, - "requires": { - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", - "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.1", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^6.5.1", - "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1" - } - }, - "eslint-plugin-prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", - "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", - "dev": true, - "requires": { - "fast-diff": "^1.1.1", - "jest-docblock": "^21.0.0" - } - }, - "eslint-plugin-react": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz", - "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1", - "prop-types": "^15.6.2" - } - }, - "eslint-restricted-globals": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", - "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", - "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", - "dev": true, - "requires": { - "acorn": "^6.0.2", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-target-shim": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz", - "integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=", - "dev": true - }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", - "dev": true - }, - "exec-sh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", - "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", - "dev": true, - "requires": { - "merge": "^1.2.0" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.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": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", - "dev": true, - "requires": { - "bser": "^2.0.0" - } - }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "dev": true, - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, - "fbjs-scripts": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz", - "integrity": "sha512-aUJ/uEzMIiBYuj/blLp4sVNkQQ7ZEB/lyplG1IzzOmZ83meiWecrGg5jBo4wWrxXmO4RExdtsSV1QkTjPt2Gag==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "babel-core": "^6.7.2", - "babel-preset-fbjs": "^2.1.2", - "core-js": "^2.4.1", - "cross-spawn": "^5.1.0", - "fancy-log": "^1.3.2", - "object-assign": "^4.0.1", - "plugin-error": "^0.1.2", - "semver": "^5.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "find-package": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-package/-/find-package-1.0.0.tgz", - "integrity": "sha1-13ONpn48XwVcJNPhmqGu7QY8PoM=", - "dev": true, - "requires": { - "parents": "^1.0.1" - } - }, - "find-parent-dir": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", - "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "firstline": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.3.1.tgz", - "integrity": "sha512-ycwgqtoxujz1dm0kjkBFOPQMESxB9uKc/PlD951dQDIG+tBXRpYZC2UmJb0gDxopQ1ZX6oyRQN3goRczYu7Deg==", - "dev": true - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - } - }, - "flow-bin": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.80.0.tgz", - "integrity": "sha512-0wRnqvXErQRPrx6GBLB5swgndfWkotd9MgfePgT7Z+VsE046c8Apzl7KKTCypB/pzn0pZF2g5Jurxxb2umET8g==", - "dev": true - }, - "flow-copy-source": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flow-copy-source/-/flow-copy-source-2.0.2.tgz", - "integrity": "sha512-IHKgy45Q+Xs7UanUZyFFJae/ubMKtzj0dU4vs1YoqlfKl2wzLTaqehyTpjqO4vLAnL48yGvLfnttncX5Utn/4g==", - "dev": true, - "requires": { - "chokidar": "^2.0.0", - "fs-extra": "^7.0.0", - "glob": "^7.0.0", - "kefir": "^3.7.3", - "yargs": "^12.0.1" - } - }, - "follow-redirects": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", - "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "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" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", - "dev": true, - "requires": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - } - }, - "genversion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/genversion/-/genversion-2.1.0.tgz", - "integrity": "sha512-BBhXZASvA8i+0vcgQOCtTVVtCRJRDNintm7xfmxX8p4NA/LTncHwzX4+AmKFuSX4K2/nLIBjYAvSEZXeGK6AZA==", - "dev": true, - "requires": { - "commander": "^2.11.0", - "find-package": "^1.0.0", - "firstline": "^1.2.1", - "mkdirp": "^0.5.1" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", - "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", - "dev": true - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "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" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - } - }, - "globals": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", - "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", - "dev": true - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "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.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "dependencies": { - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "husky": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", - "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", - "dev": true, - "requires": { - "is-ci": "^1.0.10", - "normalize-path": "^1.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", - "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", - "dev": true - } - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "image-size": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", - "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "dependencies": { - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "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.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", - "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", - "dev": true - }, - "strip-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", - "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", - "dev": true, - "requires": { - "ansi-regex": "^4.0.0" - } - } - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "requires": { - "ci-info": "^1.5.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-observable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", - "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", - "dev": true, - "requires": { - "symbol-observable": "^1.1.0" - }, - "dependencies": { - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - } - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - }, - "dependencies": { - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true - }, - "jest-get-type": { - "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", - "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", - "dev": true - }, - "jest-haste-map": { - "version": "23.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-23.5.0.tgz", - "integrity": "sha512-bt9Swigb6KZ6ZQq/fQDUwdUeHenVvZ6G/lKwJjwRGp+Fap8D4B3bND3FaeJg7vXVsLX8hXshRArbVxLop/5wLw==", - "dev": true, - "requires": { - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.1.11", - "invariant": "^2.2.4", - "jest-docblock": "^23.2.0", - "jest-serializer": "^23.0.1", - "jest-worker": "^23.2.0", - "micromatch": "^2.3.11", - "sane": "^2.0.0" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "jest-docblock": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-23.2.0.tgz", - "integrity": "sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - } - } - }, - "jest-serializer": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-23.0.1.tgz", - "integrity": "sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=", - "dev": true - }, - "jest-validate": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", - "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "leven": "^2.1.0", - "pretty-format": "^23.6.0" - } - }, - "jest-worker": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", - "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", - "dev": true, - "requires": { - "merge-stream": "^1.0.1" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "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.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", - "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", - "dev": true, - "requires": { - "array-includes": "^3.0.3" - } - }, - "kefir": { - "version": "3.8.5", - "resolved": "https://registry.npmjs.org/kefir/-/kefir-3.8.5.tgz", - "integrity": "sha512-u4UxHyIvdOOM62Y/yAtYPeYEg/yUfwl5/QF3ksrTRxEdhpa7LAFChntZxVqbcf0gCGblZzL/JnV/gZYWOps3Qw==", - "dev": true, - "requires": { - "symbol-observable": "1.0.4" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lint-staged": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-7.3.0.tgz", - "integrity": "sha512-AXk40M9DAiPi7f4tdJggwuKIViUplYtVj1os1MVEteW7qOkU50EOehayCfO9TsoGK24o/EsWb41yrEgfJDDjCw==", - "dev": true, - "requires": { - "chalk": "^2.3.1", - "commander": "^2.14.1", - "cosmiconfig": "^5.0.2", - "debug": "^3.1.0", - "dedent": "^0.7.0", - "execa": "^0.9.0", - "find-parent-dir": "^0.3.0", - "is-glob": "^4.0.0", - "is-windows": "^1.0.2", - "jest-validate": "^23.5.0", - "listr": "^0.14.1", - "lodash": "^4.17.5", - "log-symbols": "^2.2.0", - "micromatch": "^3.1.8", - "npm-which": "^3.0.1", - "p-map": "^1.1.1", - "path-is-inside": "^1.0.2", - "pify": "^3.0.0", - "please-upgrade-node": "^3.0.2", - "staged-git-files": "1.1.1", - "string-argv": "^0.0.2", - "stringify-object": "^3.2.2" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "execa": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", - "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", - "dev": true, - "requires": { - "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" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "listr": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", - "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", - "dev": true, - "requires": { - "@samverschueren/stream-to-observable": "^0.3.0", - "is-observable": "^1.1.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.5.0", - "listr-verbose-renderer": "^0.5.0", - "p-map": "^2.0.0", - "rxjs": "^6.3.3" - }, - "dependencies": { - "p-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.0.0.tgz", - "integrity": "sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w==", - "dev": true - } - } - }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", - "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^2.3.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "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 - }, - "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.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-verbose-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", - "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "date-fns": "^1.27.2", - "figures": "^2.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", - "dev": true - }, - "lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", - "dev": true - }, - "lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", - "dev": true - }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "log-update": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", - "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "cli-cursor": "^2.0.0", - "wrap-ansi": "^3.0.1" - }, - "dependencies": { - "wrap-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", - "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - } - } - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" - } - }, - "merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", - "dev": true - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "metro": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro/-/metro-0.45.6.tgz", - "integrity": "sha512-+RinU6Qcea/zX9xxfrgmeFBwJ3tsdgLyBJm4tQOmusU4kE8YEE4LQ3IGG60qk3wzYloflMB/8ilIGG4Z/gz2Ew==", - "dev": true, - "requires": { - "@babel/core": "^7.0.0", - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/plugin-external-helpers": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "absolute-path": "^0.0.0", - "async": "^2.4.0", - "babel-preset-fbjs": "2.3.0", - "chalk": "^1.1.1", - "concat-stream": "^1.6.0", - "connect": "^3.6.5", - "debug": "^2.2.0", - "denodeify": "^1.2.1", - "eventemitter3": "^3.0.0", - "fbjs": "0.8.17", - "fs-extra": "^1.0.0", - "graceful-fs": "^4.1.3", - "image-size": "^0.6.0", - "jest-docblock": "23.2.0", - "jest-haste-map": "23.5.0", - "jest-worker": "23.2.0", - "json-stable-stringify": "^1.0.1", - "lodash.throttle": "^4.1.1", - "merge-stream": "^1.0.1", - "metro-cache": "0.45.6", - "metro-config": "0.45.6", - "metro-core": "0.45.6", - "metro-minify-uglify": "0.45.6", - "metro-react-native-babel-preset": "0.45.6", - "metro-resolver": "0.45.6", - "metro-source-map": "0.45.6", - "mime-types": "2.1.11", - "mkdirp": "^0.5.1", - "node-fetch": "^2.2.0", - "nullthrows": "^1.1.0", - "react-transform-hmr": "^1.0.4", - "resolve": "^1.5.0", - "rimraf": "^2.5.4", - "serialize-error": "^2.1.0", - "source-map": "^0.5.6", - "temp": "0.8.3", - "throat": "^4.1.0", - "wordwrap": "^1.0.0", - "write-file-atomic": "^1.2.0", - "ws": "^1.1.0", - "xpipe": "^1.0.5", - "yargs": "^9.0.0" - }, - "dependencies": { - "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 - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "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.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "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" - } - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jest-docblock": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-23.2.0.tgz", - "integrity": "sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=", - "dev": true, - "requires": { - "detect-newline": "^2.1.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.6" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mime-db": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", - "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=", - "dev": true - }, - "mime-types": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", - "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", - "dev": true, - "requires": { - "mime-db": "~1.23.0" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "metro-babel-register": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.45.6.tgz", - "integrity": "sha512-Io8JinYIzGcXiTaO7o0DGw8wFcAiITTb7mLh3lbuJd9PndbPOo+jhrHkTsNtXc9MRHiT4KbEheXJ/QoeLKJK/Q==", - "dev": true, - "requires": { - "@babel/core": "^7.0.0", - "@babel/plugin-proposal-class-properties": "^7.0.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", - "@babel/plugin-proposal-optional-chaining": "^7.0.0", - "@babel/plugin-transform-async-to-generator": "^7.0.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0", - "@babel/plugin-transform-modules-commonjs": "^7.0.0", - "@babel/register": "^7.0.0", - "core-js": "^2.2.2", - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==", - "dev": true - } - } - }, - "metro-babel7-plugin-react-transform": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.45.6.tgz", - "integrity": "sha512-NsVKqiBaF+Tm3FXzqiEExl9iJG+EimbpQP5h9ygxBE4AsYRc2S3X/YD/1ds3RTHMgfhinWVaus+DrG5OqK5mTA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0" - } - }, - "metro-cache": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.45.6.tgz", - "integrity": "sha512-v7q2pLsI7oABEjpwPJwTd7ufwKvpctVOddcffI/2hRhuJC/seLlqkRt7kv+Q/WfaR9X4KLcEoIjZmgNy4cw1ag==", - "dev": true, - "requires": { - "jest-serializer": "23.0.1", - "metro-core": "0.45.6", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4" - } - }, - "metro-config": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.45.6.tgz", - "integrity": "sha512-ZhVtkpXhOi+qWi7vdE3HGIhyyBT1wtIukQuxTMwLTUluv2/1DClo/uX9inmf++CmOhOpU7QpqrMzl6vf+AwnOg==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.5", - "metro": "0.45.6", - "metro-cache": "0.45.6", - "metro-core": "0.45.6" - } - }, - "metro-core": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.45.6.tgz", - "integrity": "sha512-M0YkGnkjStdCsSNYVW+aVlJ4WjwcqjIhQV+VzEnGZYdyo6cMi9MxUZ69iV2jIxd3LAeaQQaNe8OQtQp8dfIh/g==", - "dev": true, - "requires": { - "jest-haste-map": "23.5.0", - "lodash.throttle": "^4.1.1", - "metro-resolver": "0.45.6", - "wordwrap": "^1.0.0" - } - }, - "metro-memory-fs": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-memory-fs/-/metro-memory-fs-0.45.6.tgz", - "integrity": "sha512-YAGoNQVTM/vl65jR/ztucAZJIk0ejD3INZT0LiISRULBt6Rxfiqa22v5GG0Enq+95vlgmt26g+auHM2nxTUInQ==", - "dev": true - }, - "metro-minify-uglify": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.45.6.tgz", - "integrity": "sha512-l+lZ7Gg6CN9XddgmwAbo7zOLT2QB9a6VALXLzmvr6gB1mc6SBZwtAh+hARvdymtcr1CgbaWADZPAA+W3oQZH4g==", - "dev": true, - "requires": { - "uglify-es": "^3.1.9" - } - }, - "metro-react-native-babel-preset": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.45.6.tgz", - "integrity": "sha512-qh+iXlV2tDfvHYbhh1meihxnzXXXB8nF1fi8z2HFxqYDkFBM48XewXO6mLz97PL8lmuTGvX/2dYVuFtriENw1w==", - "dev": true, - "requires": { - "@babel/plugin-proposal-class-properties": "^7.0.0", - "@babel/plugin-proposal-export-default-from": "^7.0.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", - "@babel/plugin-proposal-optional-chaining": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/plugin-syntax-export-default-from": "^7.0.0", - "@babel/plugin-transform-arrow-functions": "^7.0.0", - "@babel/plugin-transform-block-scoping": "^7.0.0", - "@babel/plugin-transform-classes": "^7.0.0", - "@babel/plugin-transform-computed-properties": "^7.0.0", - "@babel/plugin-transform-destructuring": "^7.0.0", - "@babel/plugin-transform-exponentiation-operator": "^7.0.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0", - "@babel/plugin-transform-for-of": "^7.0.0", - "@babel/plugin-transform-function-name": "^7.0.0", - "@babel/plugin-transform-literals": "^7.0.0", - "@babel/plugin-transform-modules-commonjs": "^7.0.0", - "@babel/plugin-transform-object-assign": "^7.0.0", - "@babel/plugin-transform-parameters": "^7.0.0", - "@babel/plugin-transform-react-display-name": "^7.0.0", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/plugin-transform-react-jsx-source": "^7.0.0", - "@babel/plugin-transform-regenerator": "^7.0.0", - "@babel/plugin-transform-shorthand-properties": "^7.0.0", - "@babel/plugin-transform-spread": "^7.0.0", - "@babel/plugin-transform-sticky-regex": "^7.0.0", - "@babel/plugin-transform-template-literals": "^7.0.0", - "@babel/plugin-transform-typescript": "^7.0.0", - "@babel/plugin-transform-unicode-regex": "^7.0.0", - "@babel/template": "^7.0.0", - "metro-babel7-plugin-react-transform": "0.45.6", - "react-transform-hmr": "^1.0.4" - } - }, - "metro-resolver": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.45.6.tgz", - "integrity": "sha512-RY4tqKxSEz4ahLPaJlx30x6vG8HVyLT3w5aUDcyB5B2eQH3ckLnyUYUpd0sT7HFoJ1T5U5DFtWvS3P4yJcRB7A==", - "dev": true, - "requires": { - "absolute-path": "^0.0.0" - } - }, - "metro-source-map": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.45.6.tgz", - "integrity": "sha512-FBubSEEitGrvUeuCPVwXTJX7Y1WjFhsUHickqQE+mXplOgREyeZ7o80ffqEWitfsMUQN9385LxIPmAdPzQXLsQ==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "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": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "dev": true, - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "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.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "dev": true, - "requires": { - "basic-auth": "~2.0.0", - "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "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-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" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", - "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-notifier": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz", - "integrity": "sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==", - "dev": true, - "requires": { - "growly": "^1.3.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "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": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-path": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", - "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", - "dev": true, - "requires": { - "which": "^1.2.10" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "npm-which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", - "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", - "dev": true, - "requires": { - "commander": "^2.9.0", - "npm-path": "^2.0.2", - "which": "^1.2.10" - } - }, - "npmlog": { - "version": "2.0.4", - "resolved": "http://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", - "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", - "dev": true, - "requires": { - "ansi": "~0.3.1", - "are-we-there-yet": "~1.1.2", - "gauge": "~1.2.5" - } - }, - "nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "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" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.1.tgz", - "integrity": "sha512-saQQ9hjLwu/oS0492eyYotoh+bra1819cfAT5rjY/e4REWwuc8IgZ844Oo44SiftWcJuBiqp0SA0BFVbmLX0IQ==" - }, - "opn": { - "version": "3.0.3", - "resolved": "http://registry.npmjs.org/opn/-/opn-3.0.3.tgz", - "integrity": "sha1-ttmec5n3jWXDuq/+8fsojpuFJDo=", - "dev": true, - "requires": { - "object-assign": "^4.0.1" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", - "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "is-plain-obj": "^1.1.0", - "mkdirp": "^0.5.1" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", - "dev": true - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.0.tgz", - "integrity": "sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg==", - "dev": true - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pegjs": { - "version": "0.10.0", - "resolved": "http://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz", - "integrity": "sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "please-upgrade-node": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", - "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "plist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", - "dev": true, - "requires": { - "base64-js": "^1.2.3", - "xmlbuilder": "^9.0.7", - "xmldom": "0.1.x" - } - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz", - "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==", - "dev": true - }, - "pretty-format": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "~2.0.3" - } - }, - "prop-types": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", - "requires": { - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "react": { - "version": "16.6.3", - "resolved": "https://registry.npmjs.org/react/-/react-16.6.3.tgz", - "integrity": "sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.11.2" - } - }, - "react-clone-referenced-element": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz", - "integrity": "sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg==", - "dev": true - }, - "react-deep-force-update": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz", - "integrity": "sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==", - "dev": true - }, - "react-devtools-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-3.3.4.tgz", - "integrity": "sha512-6lsBDRInT9jU8Ya8bnKWJSsnaGg/xk1ZSfvhc/dHc3n2CUTMfGlqm2tGeZQ9WEoe0Y2K7Lg90Kvb1E8anLePaQ==", - "dev": true, - "requires": { - "shell-quote": "^1.6.1", - "ws": "^3.3.1" - }, - "dependencies": { - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "react-dom": { - "version": "16.6.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", - "integrity": "sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.11.2" - } - }, - "react-native": { - "version": "0.57.1", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.57.1.tgz", - "integrity": "sha512-d+bRxIFjCrvXVbvPhuyLvE8NSiYKzldBzL+sJjSGxNqOOb2UIjLfB1BGUkI3n3X7KAYEUp4KUhT7YfA2qsRi/w==", - "dev": true, - "requires": { - "absolute-path": "^0.0.0", - "art": "^0.10.0", - "base64-js": "^1.1.2", - "chalk": "^1.1.1", - "commander": "^2.9.0", - "compression": "^1.7.1", - "connect": "^3.6.5", - "create-react-class": "^15.6.3", - "debug": "^2.2.0", - "denodeify": "^1.2.1", - "envinfo": "^5.7.0", - "errorhandler": "^1.5.0", - "escape-string-regexp": "^1.0.5", - "event-target-shim": "^1.0.5", - "fbjs": "0.8.17", - "fbjs-scripts": "^0.8.1", - "fs-extra": "^1.0.0", - "glob": "^7.1.1", - "graceful-fs": "^4.1.3", - "inquirer": "^3.0.6", - "lodash": "^4.17.5", - "metro": "^0.45.6", - "metro-babel-register": "^0.45.6", - "metro-core": "^0.45.6", - "metro-memory-fs": "^0.45.6", - "mime": "^1.3.4", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "morgan": "^1.9.0", - "node-fetch": "^2.2.0", - "node-notifier": "^5.2.1", - "npmlog": "^2.0.4", - "opn": "^3.0.2", - "optimist": "^0.6.1", - "plist": "^3.0.0", - "pretty-format": "^4.2.1", - "promise": "^7.1.1", - "prop-types": "^15.5.8", - "react-clone-referenced-element": "^1.0.1", - "react-devtools-core": "3.3.4", - "react-timer-mixin": "^0.13.2", - "regenerator-runtime": "^0.11.0", - "rimraf": "^2.5.4", - "semver": "^5.0.3", - "serve-static": "^1.13.1", - "shell-quote": "1.6.1", - "stacktrace-parser": "^0.1.3", - "ws": "^1.1.0", - "xcode": "^0.9.1", - "xmldoc": "^0.4.0", - "yargs": "^9.0.0" - }, - "dependencies": { - "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 - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "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.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "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" - } - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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.3.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.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.6" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "pretty-format": { - "version": "4.3.1", - "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-4.3.1.tgz", - "integrity": "sha1-UwvlxCs8BbNkFKeipDN6qArNDo0=", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "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" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "react-proxy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-1.1.8.tgz", - "integrity": "sha1-nb/Z2SdSjDqp9ETkVYw3gwq4wmo=", - "dev": true, - "requires": { - "lodash": "^4.6.1", - "react-deep-force-update": "^1.0.0" - } - }, - "react-timer-mixin": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz", - "integrity": "sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q==", - "dev": true - }, - "react-transform-hmr": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz", - "integrity": "sha1-4aQL0Krvxy6N/Xp82gmvhQZjl7s=", - "dev": true, - "requires": { - "global": "^4.3.0", - "react-proxy": "^1.1.7" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "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" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", - "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz", - "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", - "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^7.0.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.0.2" - } - }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, - "resolve": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", - "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "rsvp": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", - "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", - "dev": true - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sane": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", - "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "capture-exit": "^1.2.0", - "exec-sh": "^0.2.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.3", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5", - "watch": "~0.18.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "sax": { - "version": "1.1.6", - "resolved": "http://registry.npmjs.org/sax/-/sax-1.1.6.tgz", - "integrity": "sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA=", - "dev": true - }, - "scheduler": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.3.tgz", - "integrity": "sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - }, - "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - } - } - }, - "serialize-error": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", - "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", - "dev": true - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shell-quote": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", - "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", - "dev": true, - "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" - } - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-plist": { - "version": "0.2.1", - "resolved": "http://registry.npmjs.org/simple-plist/-/simple-plist-0.2.1.tgz", - "integrity": "sha1-cXZts1IyaSjPOoByQrp2IyJjZyM=", - "dev": true, - "requires": { - "bplist-creator": "0.0.7", - "bplist-parser": "0.1.1", - "plist": "2.0.1" - }, - "dependencies": { - "base64-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.1.2.tgz", - "integrity": "sha1-1kAMrBxMZgl22Q0HoENR2JOV9eg=", - "dev": true - }, - "plist": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz", - "integrity": "sha1-CjLKlIGxw2TpLhjcVch23p0B2os=", - "dev": true, - "requires": { - "base64-js": "1.1.2", - "xmlbuilder": "8.2.2", - "xmldom": "0.1.x" - } - }, - "xmlbuilder": { - "version": "8.2.2", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", - "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "slice-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", - "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "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": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", - "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stacktrace-parser": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz", - "integrity": "sha1-ATl5IuX2Ls8whFUiyVxP4dJefU4=", - "dev": true - }, - "staged-git-files": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/staged-git-files/-/staged-git-files-1.1.1.tgz", - "integrity": "sha512-H89UNKr1rQJvI1c/PIR3kiAMBV23yvR7LItZiV74HWZwzt7f3YHuujJ9nJZlt58WlFox7XQsOahexwk7nTe69A==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "stream-buffers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", - "dev": true - }, - "string-argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz", - "integrity": "sha1-2sMECGkMIfPDYwo/86BYd73L1zY=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "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": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "symbol-observable": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", - "dev": true - }, - "table": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/table/-/table-5.1.1.tgz", - "integrity": "sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw==", - "dev": true, - "requires": { - "ajv": "^6.6.1", - "lodash": "^4.17.11", - "slice-ansi": "2.0.0", - "string-width": "^2.1.1" - } - }, - "temp": { - "version": "0.8.3", - "resolved": "http://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", - "dev": true, - "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" - }, - "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz", - "integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.19", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", - "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==", - "dev": true - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", - "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", - "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", - "dev": true - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "urlgrey": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", - "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "requires": { - "makeerror": "1.0.x" - } - }, - "watch": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", - "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", - "dev": true, - "requires": { - "exec-sh": "^0.2.0", - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - }, - "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, - "xcode": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/xcode/-/xcode-0.9.3.tgz", - "integrity": "sha1-kQqJwWrubMC0LKgFptC0z4chHPM=", - "dev": true, - "requires": { - "pegjs": "^0.10.0", - "simple-plist": "^0.2.1", - "uuid": "3.0.1" - }, - "dependencies": { - "uuid": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", - "dev": true - } - } - }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - }, - "xmldoc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-0.4.0.tgz", - "integrity": "sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg=", - "dev": true, - "requires": { - "sax": "~1.1.1" - } - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", - "dev": true - }, - "xpipe": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz", - "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.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 || ^4.0.0", - "yargs-parser": "^11.1.1" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } -} diff --git a/package.json b/package.json index 6fbae061..943e2b55 100644 --- a/package.json +++ b/package.json @@ -1,129 +1,113 @@ { - "name": "react-native-firebase", - "version": "5.2.1", - "author": "Invertase (http://invertase.io)", - "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Functions, Messaging (FCM), Remote Config, Storage and more.", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "name": "root", + "private": true, "scripts": { - "build": "genversion src/version.js && npm run build-src", - "build-src": "BABEL_ENV=publish babel src -d dist --ignore __tests__ --copy-files", - "build-flow": "flow-copy-source -i */__tests__* src dist", - "build-src-watch": "genversion src/version.js && BABEL_ENV=development babel src -d dist --ignore __tests__ --copy-files --watch", - "lint": "eslint ./src", - "clean": "rimraf dist/", - "validate-ts-declarations": "tsc --project ./", - "validate-flow-declarations": "flow", - "format": "npm run format:assets && npm run lint -- --fix", - "format:assets": "prettier --ignore-path .gitignore --write \"**/*.{json,md}\"", - "prepare": "npm run clean && npm run build && npm run build-flow", - "precommit": "lint-staged", - "postinstall": "opencollective-postinstall || exit 0", - "prepublishOnly": "npm run validate-ts-declarations && npm run validate-flow-declarations" - }, - "repository": { - "type": "git", - "url": "https://github.com/invertase/react-native-firebase.git" - }, - "jest": { - "preset": "jest-react-native", - "setupFiles": [], - "unmockedModulePathPatterns": [ - "./node_modules/react", - "./node_modules/react-native", - "./node_modules/react-native-mock", - "./node_modules/react-addons-test-utils" - ] - }, - "license": "Apache-2.0", - "keywords": [ - "react", - "admob", - "auth", - "config", - "digits", - "fabric", - "functions", - "phone-auth", - "sms", - "firestore", - "cloud-firestore", - "datastore", - "remote-config", - "transactions", - "react-native", - "react-native-firebase", - "firebase", - "fcm", - "apn", - "gcm", - "analytics", - "messaging", - "database", - "android", - "ios", - "crash", - "firestack", - "performance", - "firestore", - "dynamic-links", - "crashlytics" - ], - "peerDependencies": { - "react": ">= 16.5.0", - "react-native": ">= 0.57.0 < 1" + "prepare": "yarn run lerna:link && lerna run prepare", + "build:all:clean": "lerna run build:clean", + "build:all:build": "lerna run build", + "build:all:src": "lerna run build:src", + "validate:all:js": "eslint ./", + "validate:all:ts": "tsc --project ./", + "validate:all:flow": "flow", + "lerna:boostrap": "lerna bootstrap", + "lerna:link": "lerna link && lerna exec -- yarn link", + "gen:reference": "typedoc --json typedoc.json --mode file --includeDeclarations --excludeExternals", + "tests:packager:chrome": "cd tests && react-native start --platforms ios,android", + "tests:packager:jet": "REACT_DEBUGGER='echo nope' cd tests && react-native start", + "tests:packager:jet-reset-cache": "REACT_DEBUGGER='echo nope' cd tests && react-native start --reset-cache", + "tests:android:build": "cd tests && detox build --configuration android.emu.debug", + "tests:android:build-release": "cd tests && detox build --configuration android.emu.release", + "tests:android:test": "cd tests && detox test --configuration android.emu.debug", + "tests:android:test-reuse": "cd tests && detox test --configuration android.emu.debug --reuse", + "tests:android:test-cover": "cd tests && nyc ./node_modules/.bin/detox test --configuration android.emu.debug", + "tests:android:test-cover-reuse": "cd tests && nyc detox test --configuration android.emu.debug --reuse", + "tests:ios:build": "cd tests && detox build --configuration ios.sim.debug", + "tests:ios:build-release": "cd tests && detox build --configuration ios.sim.release", + "tests:ios:test": "cd tests && detox test --configuration ios.sim.debug --loglevel warn", + "tests:ios:test-reuse": "cd tests && detox test --configuration ios.sim.debug --reuse --loglevel warn", + "tests:ios:test-cover": "cd tests && nyc ./node_modules/.bin/detox test --configuration ios.sim.debug", + "tests:ios:test-cover-reuse": "cd tests && nyc detox test --configuration ios.sim.debug --reuse --loglevel warn", + "tests:ios:pod:install": "cd tests && cd ios && rm -rf ReactNativeFirebaseDemo.xcworkspace && pod install && cd ..", + "npm:version:release:patch": "echo '!!\uD83D\uDD34!! RELEASE !!\uD83D\uDD34!!' && lerna version patch --exact --force-publish=*", + "npm:version:release:minor": "echo '!!\uD83D\uDD34!! RELEASE !!\uD83D\uDD34!!' && lerna version minor --exact --force-publish=*", + "npm:version:release:major": "echo '!!\uD83D\uDD34!! RELEASE !!\uD83D\uDD34!!' && lerna version major --exact --force-publish=*", + "npm:version:6:alpha": "lerna version prerelease --preid alpha --no-git-tag-version --no-push --force-publish=*", + "npm:version:6:beta": "lerna version prerelease --exact --preid beta --no-git-tag-version --no-push --force-publish=*", + "npm:version:6:rc": "lerna version prerelease --exact --preid rc --no-git-tag-version --no-push --force-publish=*", + "npm:publish:6:alpha": "lerna publish from-package --dist-tag alpha --no-git-reset", + "npm:publish:6:beta": "lerna publish from-package --dist-tag beta --no-git-reset", + "npm:publish:6:rc": "lerna publish from-package --dist-tag rc --no-git-reset", + "npm:publish:alpha:nightly": "lerna publish from-package --canary --preid alpha --dist-tag alpha --no-git-reset", + "npm:publish:release": "echo '!!\uD83D\uDD34!! RELEASE !!\uD83D\uDD34!!' && echo '!!!!! RELEASE !!!!!!' && lerna publish from-package" }, "devDependencies": { - "@babel/cli": "^7.0.0", - "@babel/core": "^7.0.0", - "@babel/runtime": "^7.0.0", - "@invertase/babel-preset-react-native-syntax": "^0.1.3", - "axios": "^0.18.0", - "babel-eslint": "^9.0.0", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.2.2", "codecov": "^3.1.0", - "eslint": "^5.5.0", - "eslint-config-airbnb": "^17.0.0", - "eslint-config-prettier": "^3.0.1", - "eslint-plugin-flowtype": "^2.50.1", + "@babel/plugin-transform-runtime": "^7.2.0", + "@babel/runtime": "^7.2.0", + "@invertase/babel-preset-react-native-syntax": "^0.1.3", + "babel-eslint": "^10.0.1", + "eslint": "^5.12.1", + "eslint-config-airbnb": "^17.1.0", + "eslint-config-prettier": "^3.6.0", + "eslint-plugin-flowtype": "^3.2.1", "eslint-plugin-import": "^2.14.0", - "eslint-plugin-jsx-a11y": "^6.1.1", - "eslint-plugin-prettier": "^2.6.2", - "eslint-plugin-react": "^7.10.0", - "flow-bin": "^0.80.0", - "flow-copy-source": "^2.0.2", - "genversion": "^2.1.0", - "husky": "^0.14.3", - "lint-staged": "^7.2.2", - "prettier": "^1.14.2", - "react": "^16.5.0", - "react-dom": "^16.5.0", - "react-native": "0.57.1", - "rimraf": "^2.6.2", - "typescript": "^3.0.3" - }, - "dependencies": { - "opencollective-postinstall": "^2.0.0", - "prop-types": "^15.6.2" - }, - "rnpm": { - "android": { - "buildPatch": " implementation project(':react-native-firebase')", - "packageImportPath": "import io.invertase.firebase.RNFirebasePackage;", - "packageInstance": "new RNFirebasePackage()" - } - }, - "collective": { - "type": "opencollective", - "url": "https://opencollective.com/react-native-firebase" + "eslint-plugin-jsx-a11y": "^6.1.2", + "eslint-plugin-prettier": "^3.0.1", + "eslint-plugin-react": "^7.11.1", + "flow-bin": "^0.89.0", + "genversion": "^2.1.1", + "husky": "^1.2.1", + "lerna": "^3.6.0", + "lint-staged": "^8.1.0", + "prettier": "^1.15.3", + "rimraf": "^2.6.3", + "tslint": "^5.12.1", + "tslint-config-airbnb": "^5.11.1", + "tslint-config-prettier": "^1.17.0", + "tslint-plugin-prettier": "^2.0.1", + "typedoc": "^0.14.1", + "typescript": "^3.2.4" }, "lint-staged": { - "src/**/*.js": [ + "packages/**/*.js": [ "eslint --fix", "git add" ], - "*.{json,md,scss}": [ + "tests/**/*.js": [ + "eslint --fix", + "git add" + ], + "*.{json,md}": [ "prettier --write", "git add" ] + }, + "workspaces": { + "packages": [ + "packages/*", + "tests" + ], + "nohoist": [ + "detox", + "**/detox", + "**/detox/**", + "**/babel-plugin-istanbul", + "**/babel-plugin-istanbul/**", + "**/patch-package", + "**/patch-package/**", + "**/jet", + "**/jet/**", + "**/nyc", + "**/nyc/**", + "**/react", + "**/react/**", + "**/react-native", + "**/react-native/**" + ] + }, + "dependencies": { + "axios": "^0.18.0" } } diff --git a/.npmignore b/packages/analytics/.npmignore similarity index 69% rename from .npmignore rename to packages/analytics/.npmignore index bea7b66f..d9fa30e5 100644 --- a/.npmignore +++ b/packages/analytics/.npmignore @@ -1,30 +1,3 @@ -node_modules -coverage.android.json -coverage.ios.json -coverage -npm-debug.log -*.DS_Store -.github -# Xcode -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 -*.xcuserstate -project.xcworkspace/ -xcuserdata/ - -# Config files -# .babelrc -.editorconfig -.eslintrc -.flowconfig -.watchmanconfig -jsconfig.json - -# Example -example/ - # Built application files android/*/build/ @@ -54,7 +27,17 @@ android/.idea/modules.xml android/.idea/scopes/scope_settings.xml android/.idea/vcs.xml android/*.iml -ios/RnFirebase.xcodeproj/xcuserdata + +# Xcode +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.xcuserstate +ios/Pods +ios/build +*project.xcworkspace* +*xcuserdata* # OS-specific files .DS_Store @@ -68,26 +51,15 @@ android/gradlew android/build android/gradlew.bat android/gradle/ -docs + .idea coverage yarn.lock -tests/ -buddybuild_postclone.sh -bin/test.js +e2e/ .github -example -codorials .vscode .nyc_output -React-Native-Firebase.svg -CONTRIBUTING.md -CODE_OF_CONDUCT.md android/.settings -README.md -/src *.coverage.json -.opensource .circleci .eslintignore -codecov.yml diff --git a/packages/analytics/LICENSE b/packages/analytics/LICENSE new file mode 100644 index 00000000..ef3ed44f --- /dev/null +++ b/packages/analytics/LICENSE @@ -0,0 +1,32 @@ +Apache-2.0 License +------------------ + +Copyright (c) 2016-present Invertase Limited & Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this library except in compliance with the License. + +You may obtain a copy of the Apache-2.0 License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Creative Commons Attribution 3.0 License +---------------------------------------- + +Copyright (c) 2016-present Invertase Limited & Contributors + +Documentation and other instructional materials provided for this project +(including on a separate documentation repository or it's documentation website) are +licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks +contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above. + +You may obtain a copy of the Creative Commons Attribution 3.0 License at + + https://creativecommons.org/licenses/by/3.0/ diff --git a/packages/analytics/README.md b/packages/analytics/README.md new file mode 100644 index 00000000..974bb3c7 --- /dev/null +++ b/packages/analytics/README.md @@ -0,0 +1,52 @@ +

+ +
+
+

React Native Firebase - Analytics

+

+ +

+ NPM downloads + NPM version + License + Backers on Open Collective + Sponsors on Open Collective + Chat + Follow on Twitter +

+ +---- + +Analytics integrates across Firebase features and provides +you with unlimited reporting for up to 500 distinct events +that you can define using the Firebase SDK. Analytics reports +help you understand clearly how your users behave, which enables +you to make informed decisions regarding app marketing and +performance optimizations. + +[> Learn More](https://firebase.google.com/products/analytics/) + +## Installation + +```bash +yarn add @react-native-firebase/analytics +react-native link @react-native-firebase/analytics +``` + +## Documentation + + - [Guides](#TODO) + - [Installation](#TODO) + - [Reference](#TODO) + +## License + +- See [LICENSE](/LICENSE) + +---- + +Built and maintained with 💛 by [Invertase](https://invertase.io). + +- [💼 Hire Us](https://invertase.io/hire-us) +- [☕️ Sponsor Us](https://opencollective.com/react-native-firebase) +- [👩‍💻 Work With Us](https://invertase.io/jobs) diff --git a/packages/analytics/android/build.gradle b/packages/analytics/android/build.gradle new file mode 100644 index 00000000..e7e93e5f --- /dev/null +++ b/packages/analytics/android/build.gradle @@ -0,0 +1,66 @@ +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +plugins { + id "io.invertase.gradle.build" version "1.3" +} + +project.ext { + set('react-native', [ + versions: [ + android : [ + minSdk : 16, + targetSdk : 28, + compileSdk: 28, + // optional as gradle.buildTools comes with one by default + // overriding here though to match the version RN uses + buildTools: "28.0.3" + ], + + googlePlayServices: [ + base: "16.0.1", + ], + + firebase : [ + analytics: "16.0.6" + ], + ], + ]) +} + +android { + defaultConfig { + multiDexEnabled true + } + lintOptions { + disable 'GradleCompatible' + abortOnError false + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +repositories { + google() + jcenter() +} + +dependencies { + api project(':@react-native-firebase/app') + implementation "com.google.firebase:firebase-analytics:${ReactNative.ext.getVersion("firebase", "analytics")}" + implementation "com.google.android.gms:play-services-base:${ReactNative.ext.getVersion("googlePlayServices", "base")}" +} + +ReactNative.shared.applyPackageVersion() +ReactNative.shared.applyDefaultExcludes() +ReactNative.module.applyAndroidVersions() +ReactNative.module.applyReactNativeDependency("api") diff --git a/packages/analytics/android/gradle/wrapper/gradle-wrapper.jar b/packages/analytics/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/packages/analytics/android/gradle/wrapper/gradle-wrapper.properties b/packages/analytics/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..5c8a6d6f --- /dev/null +++ b/packages/analytics/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Oct 09 01:55:27 BST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/analytics/android/gradlew b/packages/analytics/android/gradlew new file mode 100644 index 00000000..9d82f789 --- /dev/null +++ b/packages/analytics/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/packages/analytics/android/gradlew.bat b/packages/analytics/android/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/packages/analytics/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/analytics/android/lint.xml b/packages/analytics/android/lint.xml new file mode 100644 index 00000000..c3dd72ac --- /dev/null +++ b/packages/analytics/android/lint.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/analytics/android/settings.gradle b/packages/analytics/android/settings.gradle new file mode 100644 index 00000000..953994e0 --- /dev/null +++ b/packages/analytics/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = '@react-native-firebase/analytics' diff --git a/packages/analytics/android/src/main/AndroidManifest.xml b/packages/analytics/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f3d81450 --- /dev/null +++ b/packages/analytics/android/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java b/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java new file mode 100644 index 00000000..43064d8c --- /dev/null +++ b/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java @@ -0,0 +1,151 @@ +package io.invertase.firebase.analytics; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.app.Activity; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableMapKeySetIterator; +import com.google.firebase.analytics.FirebaseAnalytics; + +import javax.annotation.Nullable; + +import io.invertase.firebase.common.ReactNativeFirebaseModule; + +public class ReactNativeFirebaseAnalyticsModule extends ReactNativeFirebaseModule { + private static final String TAG = "Analytics"; + + ReactNativeFirebaseAnalyticsModule(ReactApplicationContext reactContext) { + super(reactContext, TAG); + } + + @ReactMethod + public void logEvent(String name, @Nullable ReadableMap params, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).logEvent(name, Arguments.toBundle(params)); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setAnalyticsCollectionEnabled(Boolean enabled, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).setAnalyticsCollectionEnabled(enabled); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setCurrentScreen(String screenName, String screenClassOverride, Promise promise) { + Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + try { + FirebaseAnalytics + .getInstance(getContext()) + .setCurrentScreen(activity, screenName, screenClassOverride); + + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + }); + } else { + promise.resolve(null); + } + } + + @ReactMethod + public void setMinimumSessionDuration(double milliseconds, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).setMinimumSessionDuration((long) milliseconds); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setSessionTimeoutDuration(double milliseconds, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).setSessionTimeoutDuration((long) milliseconds); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setUserId(String id, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).setUserId(id); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setUserProperty(String name, String value, Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).setUserProperty(name, value); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void setUserProperties(ReadableMap properties, Promise promise) { + try { + ReadableMapKeySetIterator iterator = properties.keySetIterator(); + FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(getContext()); + + while (iterator.hasNextKey()) { + String name = iterator.nextKey(); + String value = properties.getString(name); + firebaseAnalytics.setUserProperty(name, value); + } + + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } + + @ReactMethod + public void resetAnalyticsData(Promise promise) { + try { + FirebaseAnalytics.getInstance(getContext()).resetAnalyticsData(); + promise.resolve(null); + } catch (Exception exception) { + rejectPromiseWithExceptionMap(promise, exception); + } + } +} diff --git a/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsPackage.java b/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsPackage.java new file mode 100644 index 00000000..f46feecf --- /dev/null +++ b/packages/analytics/android/src/main/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsPackage.java @@ -0,0 +1,42 @@ +package io.invertase.firebase.analytics; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("unused") +public class ReactNativeFirebaseAnalyticsPackage implements ReactPackage { + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new ReactNativeFirebaseAnalyticsModule(reactContext)); + return modules; + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/packages/analytics/e2e/analytics.e2e.js b/packages/analytics/e2e/analytics.e2e.js new file mode 100644 index 00000000..66359fb8 --- /dev/null +++ b/packages/analytics/e2e/analytics.e2e.js @@ -0,0 +1,210 @@ +// TODO all try catch tests can give false positives as there's no +// TODO checks that it actually threw, only does tests in the catch + +describe('analytics()', () => { + describe('namespace', () => { + it('accessible from firebase.app()', () => { + const app = firebase.app(); + should.exist(app.analytics); + app.analytics().logEvent.should.be.a.Function(); + }); + + xit('throws if app arg provided to firebase.analytics(APP)', { + // TODO + }); + + xit('throws if args provided to firebase.app().analytics(ARGS)', { + // TODO + }); + }); + + describe('logEvent()', () => { + xit('errors on using a reserved name', () => { + try { + firebase.analytics().logEvent('session_start'); + } catch (e) { + e.message.should.containEql('reserved event'); + } + }); + + xit('errors if name not alphanumeric', () => { + try { + firebase.analytics().logEvent('!@£$%^&*'); + } catch (e) { + e.message.should.containEql('is invalid'); + } + }); + + xit('errors if more than 25 params provided', () => { + try { + firebase.analytics().logEvent('fooby', { + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + 7: 7, + 8: 8, + 9: 9, + 10: 10, + 11: 11, + 12: 12, + 13: 13, + 14: 14, + 15: 15, + 16: 16, + 17: 17, + 18: 18, + 19: 19, + 20: 20, + 21: 21, + 22: 22, + 23: 23, + 24: 24, + 25: 25, + 26: 26, + }); + } catch (e) { + e.message.should.containEql('Maximum number of parameters exceeded'); + } + }); + + it('errors if name is not a string', () => { + (() => { + firebase.analytics().logEvent(123456); + }).should.throw( + `analytics.logEvent(): First argument 'name' is required and must be a string value.`, + ); + }); + + it('errors if params is not an object', () => { + (() => { + firebase.analytics().logEvent('test_event', 'this should be an object'); + }).should.throw( + `analytics.logEvent(): Second optional argument 'params' must be an object if provided.`, + ); + }); + + it('log an event without parameters', async () => { + await firebase.analytics().logEvent('test_event'); + }); + + it('log an event with parameters', async () => { + await firebase.analytics().logEvent('test_event', { + boolean: true, + number: 1, + string: 'string', + }); + }); + }); + + describe('setAnalyticsCollectionEnabled()', () => { + it('true', async () => { + await firebase.analytics().setAnalyticsCollectionEnabled(true); + }); + + it('false', async () => { + await firebase.analytics().setAnalyticsCollectionEnabled(false); + }); + }); + + describe('setCurrentScreen()', () => { + it('screenName only', async () => { + await firebase.analytics().setCurrentScreen('test screen'); + }); + + it('screenName with screenClassOverride', async () => { + await firebase.analytics().setCurrentScreen('test screen', 'test class override'); + }); + + xit('errors if screenName not a string', () => { + // TODO needs validations adding to lib + }); + + xit('errors if screenClassOverride not a string', () => { + // TODO needs validations adding to lib + }); + }); + + describe('setMinimumSessionDuration()', () => { + it('default duration', async () => { + await firebase.analytics().setMinimumSessionDuration(); + }); + + it('custom duration', async () => { + await firebase.analytics().setMinimumSessionDuration(10001); + }); + }); + + describe('setSessionTimeoutDuration()', () => { + it('default duration', async () => { + await firebase.analytics().setSessionTimeoutDuration(); + }); + + it('custom duration', async () => { + await firebase.analytics().setSessionTimeoutDuration(1800001); + }); + }); + + describe('setUserId()', () => { + // nulls remove the field on firebase + it('allows a null values to be set', async () => { + await firebase.analytics().setUserId(null); + }); + + it('accepts string values', async () => { + await firebase.analytics().setUserId('test-id'); + }); + + xit('rejects none string none null values', async () => { + try { + await firebase.analytics().setUserId(33.3333); + } catch (e) { + e.message.should.containEql('must be a string'); + } + }); + }); + + describe('setUserProperty()', () => { + // nulls remove the field on firebase + it('allows a null values to be set', async () => { + await firebase.analytics().setUserProperty('fooby', null); + }); + + it('accepts string values', async () => { + await firebase.analytics().setUserProperty('fooby2', 'test-id'); + }); + + xit('rejects none string none null values', async () => { + try { + await firebase.analytics().setUserProperty('fooby3', 33.3333); + } catch (e) { + e.message.should.containEql('must be a string'); + } + }); + + xit('errors if property name not a string', () => { + // TODO needs validations adding to lib + }); + }); + + describe('setUserProperties()', () => { + // nulls remove the field on firebase + it('allows a null values to be set', async () => { + await firebase.analytics().setUserProperties({ fooby: null }); + }); + + it('accepts string values', async () => { + await firebase.analytics().setUserProperties({ fooby2: 'test-id' }); + }); + + xit('rejects none string none null values', async () => { + try { + await firebase.analytics().setUserProperties({ fooby3: 33.3333 }); + } catch (e) { + e.message.should.containEql('must be a string'); + } + }); + }); +}); diff --git a/packages/analytics/ios/RNFBAnalytics.podspec b/packages/analytics/ios/RNFBAnalytics.podspec new file mode 100644 index 00000000..28ed43b6 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.podspec @@ -0,0 +1,20 @@ +require 'json' +package = JSON.parse(File.read('../package.json')) + +Pod::Spec.new do |s| + s.name = "RNFBAnalytics" + s.version = package["version"] + s.description = package["description"] + s.summary = <<-DESC + A well tested feature rich Firebase implementation for React Native, supporting iOS & Android. + DESC + s.homepage = "http://invertase.io/oss/react-native-firebase" + s.license = package['license'] + s.authors = "Invertase Limited" + s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" } + s.social_media_url = 'http://twitter.com/invertaseio' + s.platform = :ios, "10.0" + s.source_files = 'RNFBAnalytics/**/*.{h,m}' + s.dependency 'React' + s.dependency 'Firebase/Core', '~> 5.15.0' +end diff --git a/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.pbxproj b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.pbxproj new file mode 100644 index 00000000..9cc3dd13 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 2744B98621F45429004F8E3F /* RNFBAnalyticsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 2744B98021F45429004F8E3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 2744B98221F45429004F8E3F /* libRNFBAnalytics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBAnalytics.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2744B98421F45429004F8E3F /* RNFBAnalyticsModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBAnalyticsModule.h; path = RNFBAnalytics/RNFBAnalyticsModule.h; sourceTree = SOURCE_ROOT; }; + 2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBAnalyticsModule.m; path = RNFBAnalytics/RNFBAnalyticsModule.m; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2744B97F21F45429004F8E3F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2744B97521F452B8004F8E3F /* Products */ = { + isa = PBXGroup; + children = ( + 2744B98221F45429004F8E3F /* libRNFBAnalytics.a */, + ); + name = Products; + sourceTree = ""; + }; + 2744B98321F45429004F8E3F /* RNFBAnalytics */ = { + isa = PBXGroup; + children = ( + 2744B9A121F48736004F8E3F /* converters */, + 2744B98C21F45C64004F8E3F /* common */, + 2744B98421F45429004F8E3F /* RNFBAnalyticsModule.h */, + 2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */, + ); + path = RNFBAnalytics; + sourceTree = ""; + }; + 3323F52AAFE26B7384BE4DE3 = { + isa = PBXGroup; + children = ( + 2744B98321F45429004F8E3F /* RNFBAnalytics */, + 2744B97521F452B8004F8E3F /* Products */, + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2744B98121F45429004F8E3F /* RNFBAnalytics */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBAnalytics" */; + buildPhases = ( + 2744B97E21F45429004F8E3F /* Sources */, + 2744B97F21F45429004F8E3F /* Frameworks */, + 2744B98021F45429004F8E3F /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RNFBAnalytics; + productName = RNFBAnalytics; + productReference = 2744B98221F45429004F8E3F /* libRNFBAnalytics.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3323F95273A95DB34F55C6D7 /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = RNFBAnalytics; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Invertase; + TargetAttributes = { + 2744B98121F45429004F8E3F = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBAnalytics" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 3323F52AAFE26B7384BE4DE3; + productRefGroup = 2744B97521F452B8004F8E3F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2744B98121F45429004F8E3F /* RNFBAnalytics */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2744B97E21F45429004F8E3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2744B98621F45429004F8E3F /* RNFBAnalyticsModule.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 2744B98921F45429004F8E3F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2744B98A21F45429004F8E3F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3323F77D701E1896E6D239CF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseAnalytics/Frameworks", + "$(SRCROOT)/../../../tests/ios/Pods/FirebaseAnalytics/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-firebase/ios/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**", + "$(SRCROOT)/../../../packages/app/ios/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 3323F7E33E1559A2B9826720 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseAnalytics/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-firebase/ios/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**", + "$(SRCROOT)/../../../packages/app/ios/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBAnalytics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2744B98921F45429004F8E3F /* Debug */, + 2744B98A21F45429004F8E3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBAnalytics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3323F7E33E1559A2B9826720 /* Debug */, + 3323F77D701E1896E6D239CF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3323F95273A95DB34F55C6D7 /* Project object */; +} diff --git a/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/analytics/ios/RNFBAnalytics.xcodeproj/xcshareddata/IDETemplateMacros.plist b/packages/analytics/ios/RNFBAnalytics.xcodeproj/xcshareddata/IDETemplateMacros.plist new file mode 100644 index 00000000..63f0a6e5 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1,24 @@ + + + + + FILEHEADER + +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + diff --git a/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.h b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.h new file mode 100644 index 00000000..8f0268e2 --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#import + +@interface RNFBAnalyticsModule : NSObject + +@end diff --git a/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m new file mode 100644 index 00000000..1f6fd18e --- /dev/null +++ b/packages/analytics/ios/RNFBAnalytics/RNFBAnalyticsModule.m @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + +#import "RNFBAnalyticsModule.h" +#import "RNFBApp/RNFBSharedUtils.h" + + +@implementation RNFBAnalyticsModule +#pragma mark - +#pragma mark Module Setup + + RCT_EXPORT_MODULE(); + + - (dispatch_queue_t)methodQueue { + return dispatch_get_main_queue(); + } + +#pragma mark - +#pragma mark Firebase Analytics Methods + + RCT_EXPORT_METHOD(logEvent: + (NSString *) name + params: + (NSDictionary *) params + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [FIRAnalytics logEventWithName:name parameters:params]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setAnalyticsCollectionEnabled: + (BOOL) enabled + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [[FIRAnalyticsConfiguration sharedInstance] setAnalyticsCollectionEnabled:enabled]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setCurrentScreen: + (NSString *) screenName + screenClass: + (NSString *) screenClassOverview + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + RCTUnsafeExecuteOnMainQueueSync(^{ + @try { + [FIRAnalytics setScreenName:screenName screenClass:screenClassOverview]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + return resolve([NSNull null]); + }); + } + + RCT_EXPORT_METHOD(setUserId: + (NSString *) id + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [FIRAnalytics setUserID:id]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setUserProperty: + (NSString *) name + value: + (NSString *) value + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [FIRAnalytics setUserPropertyString:value forName:name]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setUserProperties: + (NSDictionary *) properties + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [properties enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + [FIRAnalytics setUserPropertyString:value forName:key]; + }]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(resetAnalyticsData: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + @try { + [FIRAnalytics resetAnalyticsData]; + } @catch (NSException *exception) { + return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception]; + } + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setMinimumSessionDuration: + (double) milliseconds + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + // Do nothing - this only exists in android + return resolve([NSNull null]); + } + + RCT_EXPORT_METHOD(setSessionTimeoutDuration: + (double) milliseconds + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + // Do nothing - this only exists in android + return resolve([NSNull null]); + } + +@end diff --git a/packages/analytics/lib/index.d.ts b/packages/analytics/lib/index.d.ts new file mode 100644 index 00000000..67b1c202 --- /dev/null +++ b/packages/analytics/lib/index.d.ts @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + ReactNativeFirebaseModule, + ReactNativeFirebaseNamespace, + ReactNativeFirebaseModuleAndStatics, +} from '@react-native-firebase/app-types'; + +/** + * Analytics integrates across Firebase features and provides + * you with unlimited reporting for up to 500 distinct events + * that you can define using the Firebase SDK. Analytics reports + * help you understand clearly how your users behave, which enables + * you to make informed decisions regarding app marketing and + * performance optimizations. + * + * @firebase analytics + */ +export namespace Analytics { + export interface Statics {} + + export interface Module extends ReactNativeFirebaseModule { + /** + * Log a custom event with optional params. + * @note 100 characters is the maximum length for param key names. + * + * @param name + * @param params + */ + logEvent(name: string, params: { [key: string]: string }): Promise; + + /** + * If true, allows the device to collect analytical data and send it to Firebase. + * Useful for GDPR. + * + * @param enabled + */ + setAnalyticsCollectionEnabled(enabled: boolean): Promise; + + /** + * Sets the current screen name. + * + * @note Whilst screenClassOverride is optional, it is recommended it is + * always sent as your current class name. For example on Android it will always + * show as 'MainActivity' if you do not specify it. + * + * @param screenName + * @param screenClassOverride + */ + setCurrentScreen(screenName: string, screenClassOverride?: string): Promise; + + /** + * Sets the minimum engagement time required before starting a session. + * + * @param milliseconds The default value is 10000 (10 seconds). + */ + setMinimumSessionDuration(milliseconds: number): Promise; + + /** + * Sets the duration of inactivity that terminates the current session. + * + * @param milliseconds The default value is 1800000 (30 minutes). + */ + setSessionTimeoutDuration(milliseconds: number): Promise; + + /** + * Gives a user a unique identification. + * + * + * @param id Set to null to remove a previously assigned id from analytics events + */ + setUserId(id: string | null): Promise; + + /** + * Sets a key/value pair of data on the current user. + * + * @param name + * @param value Set to null to remove a previously assigned id from analytics events. + */ + setUserProperty(name: string, value: string | null): Promise; + + /** + * Sets multiple key/value pair of data on the current user. + * + * @param properties Set a property value to null to remove it. + */ + setUserProperties(properties: { [key: string]: string | null }): Promise; + + /** + * Clears all analytics data for this instance from the device and resets the app instance ID. + */ + resetAnalyticsData(): Promise; + } +} + +declare module '@react-native-firebase/analytics' { + import { ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types'; + + const FirebaseNamespaceExport: {} & ReactNativeFirebaseNamespace; + + /** + * @example + * ```js + * import { firebase } from '@react-native-firebase/analytics'; + * firebase.analytics().logEvent(...); + * ``` + */ + export const firebase = FirebaseNamespaceExport; + + const AnalyticsDefaultExport: ReactNativeFirebaseModuleAndStatics< + Analytics.Module, + Analytics.Statics + >; + /** + * @example + * ```js + * import analytics from '@react-native-firebase/analytics'; + * analytics().logEvent(...); + * ``` + */ + export default AnalyticsDefaultExport; +} + +/** + * Attach namespace to `firebase.` and `FirebaseApp.`. + */ +declare module '@react-native-firebase/app-types' { + interface ReactNativeFirebaseNamespace { + /** + * Analytics integrates across Firebase features and provides + * you with unlimited reporting for up to 500 distinct events + * that you can define using the Firebase SDK. Analytics reports + * help you understand clearly how your users behave, which enables + * you to make informed decisions regarding app marketing and + * performance optimizations. + */ + analytics: ReactNativeFirebaseModuleAndStatics< + Analytics.Module, + Analytics.Statics + >; + } + + interface FirebaseApp { + /** + * Analytics integrates across Firebase features and provides + * you with unlimited reporting for up to 500 distinct events + * that you can define using the Firebase SDK. Analytics reports + * help you understand clearly how your users behave, which enables + * you to make informed decisions regarding app marketing and + * performance optimizations. + */ + analytics(): Analytics.Module; + } +} diff --git a/packages/analytics/lib/index.js b/packages/analytics/lib/index.js new file mode 100644 index 00000000..abc71a91 --- /dev/null +++ b/packages/analytics/lib/index.js @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + createModuleNamespace, + FirebaseModule, + getFirebaseRoot, +} from '@react-native-firebase/app/lib/internal'; + +import { + isNull, + isObject, + isUndefined, + isString, + isOneOf, + isAlphaNumericUnderscore, +} from '@react-native-firebase/common'; + +import version from './version'; + +const ReservedEventNames = [ + 'app_clear_data', + 'app_uninstall', + 'app_update', + 'error', + 'first_open', + 'in_app_purchase', + 'notification_dismiss', + 'notification_foreground', + 'notification_open', + 'notification_receive', + 'os_update', + 'session_start', + 'user_engagement', +]; + +const statics = {}; + +const namespace = 'analytics'; + +const nativeModuleName = 'RNFBAnalyticsModule'; + +class FirebaseAnalyticsModule extends FirebaseModule { + logEvent(name, params = {}) { + if (!isString(name)) { + throw new Error( + `analytics.logEvent(): First argument 'name' is required and must be a string value.`, + ); + } + + if (!isUndefined(params) && !isObject(params)) { + throw new Error( + `analytics.logEvent(): Second optional argument 'params' must be an object if provided.`, + ); + } + + // check name is not a reserved event name + if (isOneOf(name, ReservedEventNames)) { + throw new Error( + `analytics.logEvent(): event name '${name}' is a reserved event name and can not be used.`, + ); + } + + // name format validation + if (!isAlphaNumericUnderscore(name)) { + throw new Error( + `analytics.logEvent(): Event name '${name}' is invalid. Names should contain 1 to 32 alphanumeric characters or underscores.`, + ); + } + + // maximum number of allowed params check + if (params && Object.keys(params).length > 25) + throw new Error('analytics.logEvent(): Maximum number of parameters exceeded (25).'); + + // Parameter names can be up to 24 characters long and must start with an alphabetic character + // and contain only alphanumeric characters and underscores. Only String, long and double param + // types are supported. String parameter values can be up to 36 characters long. The "firebase_" + // prefix is reserved and should not be used for parameter names. + return this.native.logEvent(name, params); + } + + setAnalyticsCollectionEnabled(enabled) { + return this.native.setAnalyticsCollectionEnabled(enabled); + } + + setCurrentScreen(screenName, screenClassOverride) { + return this.native.setCurrentScreen(screenName, screenClassOverride); + } + + setMinimumSessionDuration(milliseconds = 10000) { + return this.native.setMinimumSessionDuration(milliseconds); + } + + setSessionTimeoutDuration(milliseconds = 1800000) { + return this.native.setSessionTimeoutDuration(milliseconds); + } + + setUserId(id) { + if (!isNull(id) && !isString(id)) { + throw new Error('analytics.setUserId(): The supplied userId must be a string value or null.'); + } + + return this.native.setUserId(id); + } + + setUserProperty(name, value) { + if (value !== null && !isString(value)) { + throw new Error( + 'analytics.setUserProperty(): The supplied property must be a string value or null.', + ); + } + + return this.native.setUserProperty(name, value); + } + + setUserProperties(object) { + return this.native.setUserProperties(object); + } + + resetAnalyticsData() { + return this.native.resetAnalyticsData(); + } +} + +// import { SDK_VERSION } from '@react-native-firebase/analytics'; +export const SDK_VERSION = version; + +// import analytics from '@react-native-firebase/analytics'; +// analytics().logEvent(...); +export default createModuleNamespace({ + statics, + version, + namespace, + nativeModuleName, + nativeEvents: false, + hasMultiAppSupport: false, + hasCustomUrlOrRegionSupport: false, + ModuleClass: FirebaseAnalyticsModule, +}); + +// import analytics, { firebase } from '@react-native-firebase/analytics'; +// analytics().logEvent(...); +// firebase.analytics().logEvent(...); +export const firebase = getFirebaseRoot(); diff --git a/packages/analytics/lib/index.js.flow b/packages/analytics/lib/index.js.flow new file mode 100644 index 00000000..7f7a1b7f --- /dev/null +++ b/packages/analytics/lib/index.js.flow @@ -0,0 +1,150 @@ +/* eslint-disable import/no-duplicates */ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { ReactNativeFirebaseModule } from '@react-native-firebase/app-types/index.js.flow'; + +export interface Statics {} + +export interface Module extends ReactNativeFirebaseModule { + /** + * Log a custom event with optional params. + * @note 100 characters is the maximum length for param key names. + * + * @param name + * @param params + */ + logEvent(name: string, params: { [key: string]: string }): Promise; + + /** + * If true, allows the device to collect analytical data and send it to Firebase. + * Useful for GDPR. + * + * @param enabled + */ + setAnalyticsCollectionEnabled(enabled: boolean): Promise; + + /** + * Sets the current screen name. + * + * @note Whilst screenClassOverride is optional, it is recommended it is + * always sent as your current class name. For example on Android it will always + * show as 'MainActivity' if you do not specify it. + * + * @param screenName + * @param screenClassOverride + */ + setCurrentScreen(screenName: string, screenClassOverride: string): Promise; + + /** + * Sets the minimum engagement time required before starting a session. + * + * @param milliseconds The default value is 10000 (10 seconds). + */ + setMinimumSessionDuration(milliseconds: number): Promise; + + /** + * Sets the duration of inactivity that terminates the current session. + * + * @param milliseconds The default value is 1800000 (30 minutes). + */ + setSessionTimeoutDuration(milliseconds: number): Promise; + + /** + * Gives a user a unique identification. + * + * + * @param id Set to null to remove a previously assigned id from analytics events + */ + setUserId(id: string | null): Promise; + + /** + * Sets a key/value pair of data on the current user. + * + * @param name + * @param value Set to null to remove a previously assigned id from analytics events. + */ + setUserProperty(name: string, value: string | null): Promise; + + /** + * Sets multiple key/value pair of data on the current user. + * + * @react-native-firebase + * @param properties Set a property value to null to remove it. + */ + setUserProperties(properties: { [key: string]: string | null }): Promise; + + /** + * Clears all analytics data for this instance from the device and resets the app instance ID. + */ + resetAnalyticsData(): Promise; +} + +declare module '@react-native-firebase/analytics' { + import type { + ReactNativeFirebaseNamespace, + ReactNativeFirebaseModuleAndStatics, + } from '@react-native-firebase/app-types/index.js.flow'; + /** + * @example + * ```js + * import { firebase } from '@react-native-firebase/analytics'; + * firebase.analytics().logEvent(...); + * ``` + */ + declare export var firebase: {} & ReactNativeFirebaseNamespace; + + /** + * @example + * ```js + * import analytics from '@react-native-firebase/analytics'; + * analytics().logEvent(...); + * ``` + */ + declare export default ReactNativeFirebaseModuleAndStatics; +} + +/** + * Attach namespace to `firebase.` and `FirebaseApp.`. + */ +declare module '@react-native-firebase/app-types' { + import type { ReactNativeFirebaseModuleAndStatics } from '@react-native-firebase/app-types/index.js.flow'; + + declare interface ReactNativeFirebaseNamespace { + /** + * Analytics integrates across Firebase features and provides + * you with unlimited reporting for up to 500 distinct events + * that you can define using the Firebase SDK. Analytics reports + * help you understand clearly how your users behave, which enables + * you to make informed decisions regarding app marketing and + * performance optimizations. + */ + analytics: ReactNativeFirebaseModuleAndStatics; + } + + declare interface FirebaseApp { + /** + * Analytics integrates across Firebase features and provides + * you with unlimited reporting for up to 500 distinct events + * that you can define using the Firebase SDK. Analytics reports + * help you understand clearly how your users behave, which enables + * you to make informed decisions regarding app marketing and + * performance optimizations. + */ + analytics(): Module; + } +} diff --git a/packages/analytics/package.json b/packages/analytics/package.json new file mode 100644 index 00000000..fc508370 --- /dev/null +++ b/packages/analytics/package.json @@ -0,0 +1,42 @@ +{ + "name": "@react-native-firebase/analytics", + "version": "6.0.0-alpha.1", + "author": "Invertase (http://invertase.io)", + "description": "React Native Firebase - Analytics", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "build": "genversion --semi lib/version.js", + "build:clean": "rimraf android/build && rimraf ios/build", + "prepare": "yarn run build" + }, + "repository": { + "type": "git", + "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/analytics" + }, + "license": "Apache-2.0", + "keywords": [ + "react", + "react-native", + "firebase", + "analytics" + ], + "peerDependencies": { + "@react-native-firebase/app": "0.0.5-alpha.0" + }, + "dependencies": { + "@react-native-firebase/app-types": "^6.0.0-alpha.1", + "@react-native-firebase/common": "^6.0.0-alpha.1" + }, + "rnpm": { + "android": { + "buildPatch": "implementation project(':@react-native-firebase_analytics')", + "packageImportPath": "import io.invertase.firebase.analytics.ReactNativeFirebaseAnalyticsPackage;", + "packageInstance": "new ReactNativeFirebaseAnalyticsPackage()" + } + }, + "gitHead": "5024081214e6cebd3a918274d502d56522f6b3e7", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/app-types/index.d.ts b/packages/app-types/index.d.ts new file mode 100644 index 00000000..c1a3e756 --- /dev/null +++ b/packages/app-types/index.d.ts @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import {FirebaseApp} from "./index"; + +export interface NativeFirebaseError extends Error { + /** + * Firebase error code, e.g. `auth/invalid-email` + */ + readonly code: string; + + /** + * Firebase error message + */ + readonly message: string; + + /** + * The firebase module namespace that this error originated from, e.g. 'analytics' + */ + readonly namespace: string; + + /** + * The native sdks returned error code, different per platform + */ + readonly nativeErrorCode: string | number; + + /** + * The native sdks returned error message, different per platform + */ + readonly nativeErrorMessage: string; +} + +export type ReactNativeFirebaseModuleAndStatics = { + (): M; + + /** + * This React Native Firebase module version. + */ + readonly SDK_VERSION: string; +} & S; + +export type FirebaseOptions = { + /** + * The Google App ID that is used to uniquely identify an instance of an app. + */ + appId: string; + + /** + * An API key used for authenticating requests from your app, e.g. + * "AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", used to identify your app to Google servers. + */ + apiKey?: string; + + /** + * The database root URL, e.g. "http://abc-xyz-123.firebaseio.com". + */ + databaseURL?: string; + + /** + * The Project ID from the Firebase console, for example "abc-xyz-123". + */ + projectId: string; + + /** + * The tracking ID for Google Analytics, e.g. "UA-12345678-1", used to configure Google Analytics. + */ + gaTrackingId?: string; + + /** + * The Google Cloud Storage bucket name, e.g. "abc-xyz-123.storage.firebase.com". + */ + storageBucket?: string; + + + /** + * The Project Number from the Google Developer's console, for example "012345678901", used to + * configure Google Cloud Messaging. + */ + messagingSenderId?: string; + + /** + * iOS only - The OAuth2 client ID for iOS application used to authenticate Google users, for example + * "12345.apps.googleusercontent.com", used for signing in with Google. + */ + clientId?: string; + + /** + * iOS only - The Android client ID used in Google AppInvite when an iOS app has its Android version, for + * example "12345.apps.googleusercontent.com". + */ + androidClientId?: string; + + /** + * iOS only - The URL scheme used to set up Durable Deep Link service. + */ + deepLinkURLScheme?: string; + [name: string]: any; +}; + +export interface FirebaseAppConfig { + /** + * The Firebase App name, defaults to [DEFAULT] if none provided. + */ + name?: string; + + /** + * + */ + automaticDataCollectionEnabled?: boolean; + + /** + * If set to true it indicates that Firebase should close database connections + * automatically when the app is in the background. Disabled by default. + */ + automaticResourceManagement?: boolean; +} + +export interface FirebaseApp { + /** + * The name (identifier) for this App. '[DEFAULT]' is the default App. + */ + readonly name: string; + + /** + * The (read-only) configuration options from the app initialization. + */ + readonly options: FirebaseOptions; + + /** + * Make this app unusable and free up resources. + */ + delete(): Promise; +} + +export interface ReactNativeFirebaseNamespace { + /** + * Create (and initialize) a FirebaseApp. + * + * @param options Options to configure the services used in the App. + * @param config The optional config for your firebase app + */ + initializeApp(options: FirebaseOptions, config?: FirebaseAppConfig): FirebaseApp; + + /** + * Create (and initialize) a FirebaseApp. + * + * @param options Options to configure the services used in the App. + * @param name The optional name of the app to initialize ('[DEFAULT]' if + * omitted) + */ + initializeApp(options: FirebaseOptions, name?: string): FirebaseApp; + + /** + * Retrieve an instance of a FirebaseApp. + * + * @example + * ```js + * const app = firebase.app('foo'); + * ``` + * + * @param name The optional name of the app to return ('[DEFAULT]' if omitted) + */ + app(name?: string): FirebaseApp; + + /** + * A (read-only) array of all the initialized Apps. + */ + apps: FirebaseApp[]; + + /** + * The current React Native Firebase version. + */ + readonly SDK_VERSION: string; +} + +export interface ReactNativeFirebaseModule { + app: FirebaseApp; +} + +/** + * + * @firebase app + */ +export namespace App { + export interface FirebaseApp { + /** + * The name (identifier) for this App. '[DEFAULT]' is the default App. + */ + readonly name: string; + + /** + * The (read-only) configuration options from the app initialization. + */ + readonly options: FirebaseOptions; + + /** + * Make this app unusable and free up resources. + */ + delete(): Promise; + } + + export interface ReactNativeFirebaseNamespace { + /** + * Create (and initialize) a FirebaseApp. + * + * @param options Options to configure the services used in the App. + * @param config The optional config for your firebase app + */ + initializeApp(options: FirebaseOptions, config?: FirebaseAppConfig): FirebaseApp; + + /** + * Create (and initialize) a FirebaseApp. + * + * @param options Options to configure the services used in the App. + * @param name The optional name of the app to initialize ('[DEFAULT]' if + * omitted) + */ + initializeApp(options: FirebaseOptions, name?: string): FirebaseApp; + + /** + * Retrieve an instance of a FirebaseApp. + * + * @example + * ```js + * const app = firebase.app('foo'); + * ``` + * + * @param name The optional name of the app to return ('[DEFAULT]' if omitted) + */ + app(name?: string): FirebaseApp; + + /** + * A (read-only) array of all the initialized Apps. + */ + apps: FirebaseApp[]; + + /** + * The current React Native Firebase version. + */ + readonly SDK_VERSION: string; + } +} diff --git a/packages/app-types/index.js.flow b/packages/app-types/index.js.flow new file mode 100644 index 00000000..84f7a226 --- /dev/null +++ b/packages/app-types/index.js.flow @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +export type ReactNativeFirebaseModuleAndStatics = { + (): M; + +SDK_VERSION: string; +} & S; + +export type FirebaseOptions = { + appId: string; + apiKey?: string; + authDomain?: string; + databaseURL: string; + projectId: string; + gaTrackingId?: string; + storageBucket: string; + messagingSenderId: string; + + /** + * iOS only + */ + clientId?: string; + + /** + * iOS only + */ + androidClientId?: string; + + /** + * iOS only + */ + deepLinkURLScheme?: string; + [name: string]: any; +}; + +export interface FirebaseAppConfig { + name?: string; + automaticDataCollectionEnabled?: boolean; +} + +export interface FirebaseApp { + +name: string; + +options: FirebaseOptions; + delete(): Promise; +} + +export interface ReactNativeFirebaseNamespace { + initializeApp(options: FirebaseOptions, config?: FirebaseAppConfig): FirebaseApp; + initializeApp(options: FirebaseOptions, name?: string): FirebaseApp; + + app: { + (name?: string): FirebaseApp; + }; + + apps: FirebaseApp[]; + + +SDK_VERSION: string; +} + +export interface ReactNativeFirebaseModule { + app: FirebaseApp; +} diff --git a/packages/app-types/package.json b/packages/app-types/package.json new file mode 100644 index 00000000..897ecc2c --- /dev/null +++ b/packages/app-types/package.json @@ -0,0 +1,20 @@ +{ + "name": "@react-native-firebase/app-types", + "version": "6.0.0-alpha.1", + "author": "Invertase (http://invertase.io)", + "description": "@react-native-firebase/app-types", + "files": [ + "index.d.ts", + "index.js.flow", + "private.d.ts" + ], + "repository": { + "type": "git", + "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/app-types" + }, + "license": "Apache-2.0", + "gitHead": "5024081214e6cebd3a918274d502d56522f6b3e7", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/app-types/tsconfig.json b/packages/app-types/tsconfig.json new file mode 100644 index 00000000..7958dfad --- /dev/null +++ b/packages/app-types/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "exclude": ["dist/**/*"] +} diff --git a/packages/app/.npmignore b/packages/app/.npmignore new file mode 100644 index 00000000..d9fa30e5 --- /dev/null +++ b/packages/app/.npmignore @@ -0,0 +1,65 @@ +# Built application files +android/*/build/ + +# Crashlytics configuations +android/com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +android/local.properties + +# Gradle generated files +android/.gradle/ + +# Signing files +android/.signing/ + +# User-specific configurations +android/.idea/gradle.xml +android/.idea/libraries/ +android/.idea/workspace.xml +android/.idea/tasks.xml +android/.idea/.name +android/.idea/compiler.xml +android/.idea/copyright/profiles_settings.xml +android/.idea/encodings.xml +android/.idea/misc.xml +android/.idea/modules.xml +android/.idea/scopes/scope_settings.xml +android/.idea/vcs.xml +android/*.iml + +# Xcode +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.xcuserstate +ios/Pods +ios/build +*project.xcworkspace* +*xcuserdata* + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.dbandroid/gradle +android/gradlew +android/build +android/gradlew.bat +android/gradle/ + +.idea +coverage +yarn.lock +e2e/ +.github +.vscode +.nyc_output +android/.settings +*.coverage.json +.circleci +.eslintignore diff --git a/packages/app/LICENSE b/packages/app/LICENSE new file mode 100644 index 00000000..9a44423e --- /dev/null +++ b/packages/app/LICENSE @@ -0,0 +1,32 @@ +Apache-2.0 License +------------------ + +Copyright (c) 2016-present Invertase Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this library except in compliance with the License. + +You may obtain a copy of the Apache-2.0 License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Creative Commons Attribution 3.0 License +---------------------------------------- + +Copyright (c) 2016-present Invertase Limited + +Documentation and other instructional materials provided for this project +(including on a separate documentation repository or it's documentation website) are +licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks +contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above. + +You may obtain a copy of the Creative Commons Attribution 3.0 License at + + https://creativecommons.org/licenses/by/3.0/ diff --git a/packages/app/README.md b/packages/app/README.md new file mode 100644 index 00000000..5c14590c --- /dev/null +++ b/packages/app/README.md @@ -0,0 +1,41 @@ +

React Native Firebase

+

+ +

+ NPM downloads + NPM version + License + Backers on Open Collective + Sponsors on Open Collective + Chat + Follow on Twitter +

+ +## Installation - DO NOT USE YET + +```bash +yarn add @react-native-firebase/app +react-native link @react-native-firebase/app +``` + +## Documentation + + - [Guides](#TODO) + - [Installation](#TODO) + - [Reference](#TODO) + +## License + +- See [LICENSE](/LICENSE) + +---- + +Built and maintained with 💛 by [Invertase](https://invertase.io). + +- [💼 Hire Us](https://invertase.io/hire-us) +- [☕️ Sponsor Us](https://opencollective.com/react-native-firebase) +- [👩‍💻 Work With Us](https://invertase.io/jobs) diff --git a/packages/app/android/build.gradle b/packages/app/android/build.gradle new file mode 100644 index 00000000..6cc3acf9 --- /dev/null +++ b/packages/app/android/build.gradle @@ -0,0 +1,69 @@ +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +plugins { + id "io.invertase.gradle.build" version "1.3" +} + +project.ext { + set('react-native', [ + versions: [ + android : [ + minSdk : 16, + targetSdk : 28, + compileSdk: 28, + // optional as gradle.buildTools comes with one by default + // overriding here though to match the version RN uses + buildTools: "28.0.3" + ], + + googlePlayServices: [ + base: "16.0.1", + ], + + firebase : [ + core: "16.0.6" + ], + ], + ]) +} + +android { + defaultConfig { + multiDexEnabled true + } + lintOptions { + disable 'GradleCompatible' + abortOnError false + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +repositories { + google() + jcenter() +} + +dependencies { + implementation "com.google.firebase:firebase-core:${ReactNative.ext.getVersion("firebase", "core")}" + implementation "com.google.android.gms:play-services-base:${ReactNative.ext.getVersion("googlePlayServices", "base")}" +} + +if (ReactNative.util.isExpo(project)) { + apply from: file("./expo.gradle") +} + +ReactNative.shared.applyPackageVersion() +ReactNative.shared.applyDefaultExcludes() +ReactNative.module.applyAndroidVersions() +ReactNative.module.applyReactNativeDependency("api") diff --git a/packages/app/android/expo.gradle b/packages/app/android/expo.gradle new file mode 100644 index 00000000..0a4333d1 --- /dev/null +++ b/packages/app/android/expo.gradle @@ -0,0 +1,21 @@ +logger.log(LogLevel.WARN, "") +logger.log(LogLevel.WARN, " -----------------------------------------------------------") +logger.log(LogLevel.WARN, " | WARNING REACT NATIVE FIREBASE WARNING |") +logger.log(LogLevel.WARN, " ----------------------------------------------------------- ") +logger.log(LogLevel.WARN, " | |") +logger.log(LogLevel.WARN, " | It looks like you're using Expo; |") +logger.log(LogLevel.WARN, " | we no longer test for or support Expo - therefore we |") +logger.log(LogLevel.WARN, " | will not offer support or gurantee stability whilst |") +logger.log(LogLevel.WARN, " | using this library on their platform. |") +logger.log(LogLevel.WARN, " | |") +logger.log(LogLevel.WARN, " | We recommend ejecting from Expo entirely should you |") +logger.log(LogLevel.WARN, " | wish to continue using React Native Firebase or if |") +logger.log(LogLevel.WARN, " | want to get official support for it from us. |") +logger.log(LogLevel.WARN, " | |") +logger.log(LogLevel.WARN, " | NOTE: Expo's 'ExpoFirebase' is an outdated, unofficial, |") +logger.log(LogLevel.WARN, " | direct copy of our source code, should you wish to use |") +logger.log(LogLevel.WARN, " | Expo + 'ExpoFirebase' instead then you do so at your |") +logger.log(LogLevel.WARN, " | own risk without support from React Native Firebase. |") +logger.log(LogLevel.WARN, " | |") +logger.log(LogLevel.WARN, " ----------------------------------------------------------- ") +logger.log(LogLevel.WARN, "") \ No newline at end of file diff --git a/packages/app/android/gradle/wrapper/gradle-wrapper.jar b/packages/app/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/packages/app/android/gradle/wrapper/gradle-wrapper.properties b/packages/app/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..5c8a6d6f --- /dev/null +++ b/packages/app/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Oct 09 01:55:27 BST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/app/android/gradlew b/packages/app/android/gradlew new file mode 100644 index 00000000..9d82f789 --- /dev/null +++ b/packages/app/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/packages/app/android/gradlew.bat b/packages/app/android/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/packages/app/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/app/android/lint.xml b/packages/app/android/lint.xml new file mode 100644 index 00000000..c3dd72ac --- /dev/null +++ b/packages/app/android/lint.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/app/android/settings.gradle b/packages/app/android/settings.gradle new file mode 100644 index 00000000..aeaa1880 --- /dev/null +++ b/packages/app/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = '@react-native-firebase/app' diff --git a/packages/app/android/src/main/AndroidManifest.xml b/packages/app/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..8cc00808 --- /dev/null +++ b/packages/app/android/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java new file mode 100644 index 00000000..4b1bd666 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java @@ -0,0 +1,40 @@ +package io.invertase.firebase.app; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.content.Context; + +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; + +public class ReactNativeFirebaseApp { + private static Context applicationContext; + + public static Context getApplicationContext() { + return applicationContext; + } + + public static void setApplicationContext(Context applicationContext) { + ReactNativeFirebaseApp.applicationContext = applicationContext; + } + + public static void initializeSecondaryApp(String name) { + FirebaseOptions options = FirebaseOptions.fromResource(applicationContext); + FirebaseApp.initializeApp(applicationContext, options, name); + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppModule.java b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppModule.java new file mode 100644 index 00000000..7636b429 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppModule.java @@ -0,0 +1,138 @@ +package io.invertase.firebase.app; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.google.firebase.FirebaseApp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.invertase.firebase.common.RCTConvertFirebase; +import io.invertase.firebase.common.ReactNativeFirebaseEvent; +import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter; +import io.invertase.firebase.common.ReactNativeFirebaseModule; +import io.invertase.firebase.common.ReactNativeFirebasePreferences; + +public class ReactNativeFirebaseAppModule extends ReactNativeFirebaseModule { + private static final String TAG = "App"; + + ReactNativeFirebaseAppModule(ReactApplicationContext reactContext) { + super(reactContext, TAG); + } + + @Override + public void initialize() { + super.initialize(); + ReactNativeFirebaseEventEmitter.getSharedInstance().attachReactContext(getContext()); + } + + @ReactMethod + public void initializeApp(ReadableMap options, ReadableMap appConfig, Promise promise) { + FirebaseApp firebaseApp = RCTConvertFirebase.readableMapToFirebaseApp( + options, appConfig, + getContext() + ); + + WritableMap firebaseAppMap = RCTConvertFirebase.firebaseAppToWritableMap(firebaseApp); + promise.resolve(firebaseAppMap); + } + + @ReactMethod + public void setAutomaticDataCollectionEnabled(String appName, Boolean enabled) { + FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); + firebaseApp.setAutomaticResourceManagementEnabled(enabled); + } + + @ReactMethod + public void deleteApp(String appName, Promise promise) { + FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); + + if (firebaseApp != null) { + firebaseApp.delete(); + } + + promise.resolve(null); + } + + @ReactMethod + public void eventsNotifyReady(Boolean ready) { + ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance(); + emitter.notifyJsReady(ready); + } + + @ReactMethod + public void eventsGetListeners(Promise promise) { + ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance(); + promise.resolve(emitter.getListenersMap()); + } + + @ReactMethod + public void eventsPing(String eventName, ReadableMap eventBody, Promise promise) { + ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance(); + emitter.sendEvent(new ReactNativeFirebaseEvent( + eventName, + RCTConvertFirebase.readableMapToWritableMap(eventBody) + )); + promise.resolve(RCTConvertFirebase.readableMapToWritableMap(eventBody)); + } + + @ReactMethod + public void eventsAddListener(String eventName) { + ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance(); + emitter.addListener(eventName); + } + + @ReactMethod + public void eventsRemoveListener(String eventName, Boolean all) { + ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance(); + emitter.removeListener(eventName, all); + } + + @ReactMethod + public void getSavedPreferences(Promise promise) { + promise.resolve(ReactNativeFirebasePreferences.getSharedInstance().getAllAsWritableMap()); + } + + @ReactMethod + public void clearSavedPreferences(Promise promise) { + ReactNativeFirebasePreferences.getSharedInstance().clearAll(); + promise.resolve(null); + } + + + @Override + public Map getConstants() { + Map constants = new HashMap<>(); + List> appsList = new ArrayList<>(); + List firebaseApps = FirebaseApp.getApps(getReactApplicationContext()); + + for (FirebaseApp app : firebaseApps) { + appsList.add(RCTConvertFirebase.firebaseAppToMap(app)); + } + + constants.put("apps", appsList); + return constants; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java new file mode 100644 index 00000000..a8b88a3a --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java @@ -0,0 +1,43 @@ +package io.invertase.firebase.app; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("unused") +public class ReactNativeFirebaseAppPackage implements ReactPackage { + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new ReactNativeFirebaseAppModule(reactContext)); + modules.add(new ReactNativeFirebaseUtilsModule(reactContext)); + return modules; + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseUtilsModule.java b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseUtilsModule.java new file mode 100644 index 00000000..632af789 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/app/ReactNativeFirebaseUtilsModule.java @@ -0,0 +1,137 @@ +package io.invertase.firebase.app; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.app.Activity; +import android.content.IntentSender; +import android.util.Log; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +import java.util.HashMap; +import java.util.Map; + +import io.invertase.firebase.common.ReactNativeFirebaseModule; +import io.invertase.firebase.common.SharedUtils; + +public class ReactNativeFirebaseUtilsModule extends ReactNativeFirebaseModule { + private static final String TAG = "Utils"; + + ReactNativeFirebaseUtilsModule(ReactApplicationContext reactContext) { + super(reactContext, TAG); + } + + @ReactMethod + public void androidGetPlayServicesStatus(Promise promise) { + promise.resolve(getPlayServicesStatusMap()); + } + + /** + * Prompt the device user to update play services + */ + @ReactMethod + public void androidPromptForPlayServices() { + int status = isGooglePlayServicesAvailable(); + + if ( + status != ConnectionResult.SUCCESS && + GoogleApiAvailability.getInstance().isUserResolvableError(status) + ) { + Activity activity = getActivity(); + if (activity != null) { + GoogleApiAvailability.getInstance() + .getErrorDialog(activity, status, status) + .show(); + } + } + } + + /** + * Prompt the device user to update play services + */ + @ReactMethod + public void androidResolutionForPlayServices() { + int status = isGooglePlayServicesAvailable(); + ConnectionResult connectionResult = new ConnectionResult(status); + + if (!connectionResult.isSuccess() && connectionResult.hasResolution()) { + Activity activity = getActivity(); + if (activity != null) { + try { + connectionResult.startResolutionForResult(activity, status); + } catch (IntentSender.SendIntentException error) { + Log.d(TAG, "resolutionForPlayServices", error); + } + } + } + } + + /** + * Prompt the device user to update Play Services + */ + @ReactMethod + public void androidMakePlayServicesAvailable() { + int status = isGooglePlayServicesAvailable(); + + if (status != ConnectionResult.SUCCESS) { + Activity activity = getActivity(); + if (activity != null) { + GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity); + } + } + } + + private int isGooglePlayServicesAvailable() { + GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); + return gapi.isGooglePlayServicesAvailable(getContext()); + } + + private WritableMap getPlayServicesStatusMap() { + WritableMap result = Arguments.createMap(); + GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); + + int status = gapi.isGooglePlayServicesAvailable(getContext()); + result.putInt("status", status); + + if (status == ConnectionResult.SUCCESS) { + result.putBoolean("isAvailable", true); + } else { + result.putBoolean("isAvailable", false); + result.putString("error", gapi.getErrorString(status)); + result.putBoolean("isUserResolvableError", gapi.isUserResolvableError(status)); + result.putBoolean("hasResolution", new ConnectionResult(status).hasResolution()); + } + + return result; + } + + @Override + public Map getConstants() { + Map constants = new HashMap<>(); + constants.put("androidPlayServices", getPlayServicesStatusMap()); + constants.put("isFirebaseTestLab", SharedUtils.isFirebaseTestLab()); + return constants; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/RCTConvertFirebase.java b/packages/app/android/src/main/java/io/invertase/firebase/common/RCTConvertFirebase.java new file mode 100644 index 00000000..0c6d38f7 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/RCTConvertFirebase.java @@ -0,0 +1,193 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.content.Context; +import android.util.Log; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +/** + * Utilities to convert to and from React Native bridge formats. + */ +public class RCTConvertFirebase { + private static String TAG = "RCTConvertFirebase"; + + public static Map firebaseAppToMap(FirebaseApp firebaseApp) { + String name = firebaseApp.getName(); + FirebaseOptions appOptions = firebaseApp.getOptions(); + + Map root = new HashMap<>(); + Map appConfig = new HashMap<>(); + Map options = new HashMap<>(); + + appConfig.put("name", name); + appConfig.put("automaticDataCollectionEnabled", firebaseApp.isDataCollectionDefaultEnabled()); + + // TODO: Salakar: Firebase SDK does not support reading this value + // appConfig.put("automaticResourceManagement", false); + + options.put("apiKey", appOptions.getApiKey()); + options.put("appId", appOptions.getApplicationId()); + options.put("projectId", appOptions.getProjectId()); + options.put("databaseURL", appOptions.getDatabaseUrl()); + options.put("gaTrackingId", appOptions.getGaTrackingId()); + options.put("messagingSenderId", appOptions.getGcmSenderId()); + options.put("storageBucket", appOptions.getStorageBucket()); + + root.put("options", options); + root.put("appConfig", appConfig); + + return root; + } + + public static WritableMap firebaseAppToWritableMap(FirebaseApp firebaseApp) { + return Arguments.makeNativeMap(firebaseAppToMap(firebaseApp)); + } + + public static FirebaseApp readableMapToFirebaseApp( + ReadableMap options, + ReadableMap appConfig, + Context context + ) { + FirebaseOptions.Builder builder = new FirebaseOptions.Builder(); + + String name = appConfig.getString("name"); + + builder.setApiKey(options.getString("apiKey")); + builder.setApplicationId(options.getString("appId")); + builder.setProjectId(options.getString("projectId")); + builder.setDatabaseUrl(options.getString("databaseURL")); + + if (options.hasKey("gaTrackingId")) { + builder.setGaTrackingId(options.getString("gaTrackingId")); + } + + builder.setStorageBucket(options.getString("storageBucket")); + builder.setGcmSenderId(options.getString("messagingSenderId")); + + FirebaseApp firebaseApp; + if (name.equals("[DEFAULT]")) { + firebaseApp = FirebaseApp.initializeApp(context, builder.build()); + } else { + firebaseApp = FirebaseApp.initializeApp(context, builder.build(), name); + } + + if (appConfig.hasKey("automaticDataCollectionEnabled")) { + firebaseApp.setDataCollectionDefaultEnabled( + appConfig.getBoolean("automaticDataCollectionEnabled") + ); + } + + if (appConfig.hasKey("automaticResourceManagement")) { + // https://developers.google.com/android/reference/com/google/firebase/FirebaseApp.html#setAutomaticResourceManagementEnabled(boolean) + firebaseApp.setAutomaticResourceManagementEnabled( + appConfig.getBoolean("automaticResourceManagement") + ); + } + + return firebaseApp; + } + + /** + * Takes a value and calls the appropriate setter for its type on the target map + key + * + * @param key String key to set on target map + * @param value Object value to set on target map + * @param map WritableMap target map to write the value to + */ + @SuppressWarnings("unchecked") + public static void mapPutValue(String key, @Nullable Object value, WritableMap map) { + if (value == null) { + map.putNull(key); + return; + } + + String type = value.getClass().getName(); + + switch (type) { + case "java.lang.Boolean": + map.putBoolean(key, (Boolean) value); + break; + case "java.lang.Long": + Long longVal = (Long) value; + map.putDouble(key, (double) longVal); + break; + case "java.lang.Float": + float floatVal = (float) value; + map.putDouble(key, (double) floatVal); + break; + case "java.lang.Double": + map.putDouble(key, (Double) value); + break; + case "java.lang.Integer": + map.putInt(key, (int) value); + break; + case "java.lang.String": + map.putString(key, (String) value); + break; + case "org.json.JSONObject$1": + map.putString(key, value.toString()); + break; + default: + if (List.class.isAssignableFrom(value.getClass())) { + map.putArray(key, Arguments.makeNativeArray((List) value)); + } else if (Map.class.isAssignableFrom(value.getClass())) { + WritableMap childMap = Arguments.createMap(); + Map valueMap = (Map) value; + + for (Map.Entry entry : valueMap.entrySet()) { + mapPutValue(entry.getKey(), entry.getValue(), childMap); + } + + map.putMap(key, childMap); + } else { + Log.d(TAG, "utils:mapPutValue:unknownType:" + type); + map.putNull(key); + } + } + } + + public static WritableMap readableMapToWritableMap(ReadableMap map) { + WritableMap writableMap = Arguments.createMap(); + // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/WritableNativeMap.java#L54 + writableMap.merge(map); + return writableMap; + } + + public static Map recursivelyDeconstructReadableMap(ReadableMap readableMap) { + // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java#L216 + return readableMap.toHashMap(); + } + + public static List recursivelyDeconstructReadableArray(ReadableArray readableArray) { + // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java#L175 + return readableArray.toArrayList(); + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java new file mode 100644 index 00000000..b3d902ff --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java @@ -0,0 +1,54 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.bridge.WritableMap; + +import io.invertase.firebase.interfaces.NativeEvent; + +public class ReactNativeFirebaseEvent implements NativeEvent { + private String eventName; + private WritableMap eventBody; + private String firebaseAppName; + + public ReactNativeFirebaseEvent(String eventName, WritableMap eventBody) { + this.eventName = eventName; + this.eventBody = eventBody; + } + + public ReactNativeFirebaseEvent(String eventName, WritableMap eventBody, String firebaseAppName) { + this.eventName = eventName; + this.eventBody = eventBody; + this.firebaseAppName = firebaseAppName; + } + + @Override + public String getEventName() { + return eventName; + } + + @Override + public WritableMap getEventBody() { + return eventBody; + } + + @Override + public String getFirebaseAppName() { + return firebaseAppName; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java new file mode 100644 index 00000000..ae0f37f8 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java @@ -0,0 +1,162 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.MainThread; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.invertase.firebase.interfaces.NativeEvent; + +public class ReactNativeFirebaseEventEmitter { + private static ReactNativeFirebaseEventEmitter sharedInstance = new ReactNativeFirebaseEventEmitter(); + private final List queuedEvents = new ArrayList<>(); + private final Handler handler = new Handler(Looper.getMainLooper()); + private final HashMap jsListeners = new HashMap<>(); + private ReactContext reactContext; + private Boolean jsReady = false; + private int jsListenerCount; + + public static ReactNativeFirebaseEventEmitter getSharedInstance() { + return sharedInstance; + } + + public void attachReactContext(final ReactContext reactContext) { + handler.post(new Runnable() { + @Override + public void run() { + ReactNativeFirebaseEventEmitter.this.reactContext = reactContext; + sendQueuedEvents(); + } + }); + } + + public void notifyJsReady(Boolean ready) { + handler.post(new Runnable() { + @Override + public void run() { + jsReady = ready; + sendQueuedEvents(); + } + }); + } + + public void sendEvent(final NativeEvent event) { + handler.post(new Runnable() { + @Override + public void run() { + synchronized (jsListeners) { + if (!jsListeners.containsKey(event.getEventName()) || !emit(event)) { + queuedEvents.add(event); + } + } + } + }); + } + + public void addListener(String eventName) { + synchronized (jsListeners) { + jsListenerCount++; + if (!jsListeners.containsKey(eventName)) { + jsListeners.put(eventName, 1); + } else { + int listenersForEvent = jsListeners.get(eventName); + jsListeners.put(eventName, listenersForEvent + 1); + } + } + + handler.post(new Runnable() { + @Override + public void run() { + sendQueuedEvents(); + } + }); + } + + public void removeListener(String eventName, Boolean all) { + synchronized (jsListeners) { + if (jsListeners.containsKey(eventName)) { + int listenersForEvent = jsListeners.get(eventName); + + if (listenersForEvent <= 1 || all) { + jsListeners.remove(eventName); + } else { + jsListeners.put(eventName, listenersForEvent - 1); + } + + jsListenerCount -= all ? listenersForEvent : 1; + } + } + } + + public WritableMap getListenersMap() { + WritableMap writableMap = Arguments.createMap(); + WritableMap events = Arguments.createMap(); + + writableMap.putInt("listeners", jsListenerCount); + writableMap.putInt("queued", queuedEvents.size()); + + synchronized (jsListeners) { + for (HashMap.Entry entry : jsListeners.entrySet()) { + events.putInt(entry.getKey(), entry.getValue()); + } + } + + writableMap.putMap("events", events); + + return writableMap; + } + + @MainThread + private void sendQueuedEvents() { + synchronized (jsListeners) { + for (NativeEvent event : new ArrayList<>(queuedEvents)) { + if (jsListeners.containsKey(event.getEventName())) { + queuedEvents.remove(event); + sendEvent(event); + } + } + } + } + + @MainThread + private boolean emit(final NativeEvent event) { + if (!jsReady || reactContext == null || !reactContext.hasActiveCatalystInstance()) { + return false; + } + + try { + reactContext.getJSModule( + DeviceEventManagerModule.RCTDeviceEventEmitter.class + ).emit("rnfb_" + event.getEventName(), event.getEventBody()); + } catch (Exception e) { + return false; + } + + return true; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java new file mode 100644 index 00000000..451ad94e --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseInitProvider.java @@ -0,0 +1,102 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.pm.ProviderInfo; +import android.database.Cursor; +import android.net.Uri; +import android.support.annotation.Nullable; + +import io.invertase.firebase.app.ReactNativeFirebaseApp; + +public class ReactNativeFirebaseInitProvider extends ContentProvider { + /** + * Should match the {@link ReactNativeFirebaseInitProvider} authority if $androidId is empty. + */ + static final String EMPTY_APPLICATION_ID_PROVIDER_AUTHORITY = + "io.invertase.firebase.common.reactnativefirebaseinitprovider"; + + /** + * Check that the content provider's authority does not use the common package name. If it + * does, crash in order to alert the developer of the problem before they distribute the app. + */ + private static void checkContentProviderAuthority(ProviderInfo info) { + if (info != null) { + if (EMPTY_APPLICATION_ID_PROVIDER_AUTHORITY.equals(info.authority)) { + throw new IllegalStateException( + "Incorrect provider authority in manifest. This is most likely due to a missing " + + "applicationId variable in application's build.gradle."); + } + } + } + + @Override + public void attachInfo(Context context, ProviderInfo info) { + checkContentProviderAuthority(info); + super.attachInfo(context, info); + } + + /** + * Called before {@link Application#onCreate()}. + */ + @Override + public boolean onCreate() { + Context applicationContext = getContext(); + + if (applicationContext != null && applicationContext.getApplicationContext() != null) { + applicationContext = applicationContext.getApplicationContext(); + } + + ReactNativeFirebaseApp.setApplicationContext(applicationContext); + + return false; + } + + @Nullable + @Override + public Cursor query( + Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder + ) { + return null; + } + + @Nullable + @Override + public String getType(Uri uri) { + return null; + } + + @Nullable + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java new file mode 100644 index 00000000..1c1a88e5 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java @@ -0,0 +1,88 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.app.Activity; +import android.content.Context; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.WritableMap; + +import java.util.HashMap; +import java.util.Map; + +import io.invertase.firebase.interfaces.ContextProvider; + +public class ReactNativeFirebaseModule extends ReactContextBaseJavaModule implements ContextProvider { + private String moduleName; + + public ReactNativeFirebaseModule( + ReactApplicationContext reactContext, + String moduleName + ) { + super(reactContext); + this.moduleName = moduleName; + } + + @Override + public void initialize() { + super.initialize(); + } + + public ReactContext getContext() { + return getReactApplicationContext(); + } + + public Context getApplicationContext() { + return getReactApplicationContext().getApplicationContext(); + } + + public Activity getActivity() { + return getCurrentActivity(); + } + + public WritableMap getExceptionMap(Exception exception) { + WritableMap exceptionMap = Arguments.createMap(); + String code = "unknown"; + String message = exception.getMessage(); + exceptionMap.putString("code", code); + exceptionMap.putString("nativeErrorCode", code); + exceptionMap.putString("message", message); + exceptionMap.putString("nativeErrorMessage", message); + return exceptionMap; + } + + public void rejectPromiseWithExceptionMap(Promise promise, Exception exception) { + // TODO hook into crashlytics - report as handled exception? + promise.reject(exception, getExceptionMap(exception)); + } + + @Override + public String getName() { + return "RNFB" + moduleName + "Module"; + } + + @Override + public Map getConstants() { + return new HashMap<>(); + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java new file mode 100644 index 00000000..707128fe --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java @@ -0,0 +1,62 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.content.Context; +import android.content.SharedPreferences; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; + +import io.invertase.firebase.app.ReactNativeFirebaseApp; + +public class ReactNativeFirebasePreferences { + private static final String PREFERENCES_FILE = "io.invertase.firebase"; + private static ReactNativeFirebasePreferences sharedInstance = new ReactNativeFirebasePreferences(); + private SharedPreferences preferences; + + public static ReactNativeFirebasePreferences getSharedInstance() { + return sharedInstance; + } + + public void setBooleanValue(String key, boolean value) { + getPreferences().edit().putBoolean(key, value).apply(); + } + + public boolean getBooleanValue(String key) { + return getPreferences().getBoolean(key, false); + } + + public WritableMap getAllAsWritableMap() { + // TODO: Salakar: convert to writableMap + return Arguments.createMap(); + } + + public void clearAll() { + getPreferences().edit().clear().apply(); + } + + private SharedPreferences getPreferences() { + if (preferences == null) { + preferences = ReactNativeFirebaseApp + .getApplicationContext() + .getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE); + } + return preferences; + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/common/SharedUtils.java b/packages/app/android/src/main/java/io/invertase/firebase/common/SharedUtils.java new file mode 100644 index 00000000..13aa6a42 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/common/SharedUtils.java @@ -0,0 +1,201 @@ +package io.invertase.firebase.common; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.app.ActivityManager; +import android.content.Context; +import android.provider.Settings; +import android.util.Log; + +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import io.invertase.firebase.app.ReactNativeFirebaseApp; + + +@SuppressWarnings("WeakerAccess") +public class SharedUtils { + private static final String TAG = "Utils"; + private static final String RN_DEVSUPPORT_CLASS = "DevSupportManagerImpl"; + private static final String RN_DEVSUPPORT_PACKAGE = "com.facebook.react.devsupport"; + + private static final String EXPO_REGISTRY_CLASS = "ModuleRegistry"; + private static final String EXPO_CORE_PACKAGE = "expo.core"; + + private static final String FLUTTER_REGISTRY_CLASS = "PluginRegistry"; + private static final String FLUTTER_CORE_PACKAGE = "io.flutter.plugin.common"; + + private static final String REACT_NATIVE_REGISTRY_CLASS = "NativeModuleRegistry"; + private static final String REACT_NATIVE_CORE_PACKAGE = "com.facebook.react.bridge"; + + + private static final String FIREBASE_TEST_LAB = "firebase.test.lab"; + + public static String timestampToUTC(long timestamp) { + Calendar calendar = Calendar.getInstance(); + Date date = new Date((timestamp + calendar.getTimeZone().getOffset(timestamp)) * 1000); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + format.setTimeZone(TimeZone.getTimeZone("UTC")); + return format.format(date); + } + + /** + * send a JS event + **/ + public static void sendEvent(final ReactContext context, final String eventName, Object body) { + if (context != null) { + context + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, body); + } else { + Log.d(TAG, "Missing context - cannot send event!"); + } + } + + /** + * We need to check if app is in foreground otherwise the app will crash. + * http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not + * + * @param context Context + * @return boolean + */ + public static boolean isAppInForeground(Context context) { + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + if (activityManager == null) return false; + + List appProcesses = activityManager.getRunningAppProcesses(); + if (appProcesses == null) return false; + + final String packageName = context.getPackageName(); + for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { + if ( + appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + && appProcess.processName.equals(packageName) + ) { + ReactContext reactContext; + + try { + reactContext = (ReactContext) context; + } catch (ClassCastException exception) { + // Not react context so default to true + return true; + } + + return reactContext.getLifecycleState() == LifecycleState.RESUMED; + } + } + + return false; + } + + public static int getResId(Context ctx, String resName) { + int resourceId = ctx + .getResources() + .getIdentifier(resName, "string", ctx.getPackageName()); + + if (resourceId == 0) { + Log.e(TAG, "resource " + resName + " could not be found"); + } + + return resourceId; + } + + /** + * Is this app running in Firebase Test Lab + * + * @return Boolean + */ + public static Boolean isFirebaseTestLab() { + String testLabSetting = + Settings.System.getString( + ReactNativeFirebaseApp.getApplicationContext().getContentResolver(), + FIREBASE_TEST_LAB + ); + + return "true".equals(testLabSetting); + } + + /** + * Checks for dev support availability - so we can ignore in release builds for example. + * + * @return Boolean + */ + public static Boolean reactNativeHasDevSupport() { + return hasPackageClass(RN_DEVSUPPORT_PACKAGE, RN_DEVSUPPORT_CLASS); + } + + /** + * Is the build platform Expo? + * + * @return Boolean + */ + public static Boolean isExpo() { + return hasPackageClass(EXPO_CORE_PACKAGE, EXPO_REGISTRY_CLASS); + } + + /** + * Is the build platform Flutter? + * + * @return Boolean + */ + public static Boolean isFlutter() { + return hasPackageClass(FLUTTER_CORE_PACKAGE, FLUTTER_REGISTRY_CLASS); + } + + /** + * Is the build platform React Native? + * + * @return Boolean + */ + public static Boolean isReactNative() { + return !isExpo() && hasPackageClass(REACT_NATIVE_CORE_PACKAGE, REACT_NATIVE_REGISTRY_CLASS); + } + + /** + * Returns true/false if a class for a package exists in the app class bundle + * + * @param packageName + * @param className + * @return + */ + @SuppressWarnings("StringBufferReplaceableByString") + public static Boolean hasPackageClass(String packageName, String className) { + // ProGuard is surprisingly smart in this case and will keep a class if it detects a call to + // Class.forName() with a static string. So instead we generate a quasi-dynamic string to + // confuse it. + String fullName = new StringBuilder(packageName) + .append(".") + .append(className) + .toString(); + + try { + Class.forName(fullName); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/interfaces/ContextProvider.java b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/ContextProvider.java new file mode 100644 index 00000000..0a3cbb79 --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/ContextProvider.java @@ -0,0 +1,29 @@ +package io.invertase.firebase.interfaces; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import android.app.Activity; +import android.content.Context; + +import com.facebook.react.bridge.ReactContext; + +public interface ContextProvider { + Activity getActivity(); + ReactContext getContext(); + Context getApplicationContext(); +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeError.java b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeError.java new file mode 100644 index 00000000..c859d71d --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeError.java @@ -0,0 +1,28 @@ +package io.invertase.firebase.interfaces; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.bridge.WritableMap; + +public interface NativeError { + String getErrorCode(); + String getErrorMessage(); + String getFirebaseAppName(); + String getFirebaseServiceName(); + WritableMap getUserInfo(); +} diff --git a/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeEvent.java b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeEvent.java new file mode 100644 index 00000000..6f427b0d --- /dev/null +++ b/packages/app/android/src/main/java/io/invertase/firebase/interfaces/NativeEvent.java @@ -0,0 +1,27 @@ +package io.invertase.firebase.interfaces; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.bridge.WritableMap; + +public interface NativeEvent { + String getEventName(); + WritableMap getEventBody(); + + String getFirebaseAppName(); +} diff --git a/packages/app/e2e/app/app.constants.e2e.js b/packages/app/e2e/app/app.constants.e2e.js new file mode 100644 index 00000000..09b561bc --- /dev/null +++ b/packages/app/e2e/app/app.constants.e2e.js @@ -0,0 +1,25 @@ +describe('App -> NativeModules -> Constants', () => { + describe('.apps', () => { + it('should be an array', () => { + const { apps } = NativeModules.RNFBAppModule; + + apps.should.be.an.Array(); + // secondaryFromNative + apps.length.should.equal(1); + }); + + it('array items contain name, options & state properties', () => { + const { apps } = NativeModules.RNFBAppModule; + + apps.should.be.an.Array(); + apps.length.should.equal(1); + + for (let i = 0; i < apps.length; i++) { + const app = apps[i]; + app.appConfig.should.be.a.Object(); + app.appConfig.name.should.be.a.String(); + app.options.should.be.a.Object(); + } + }); + }); +}); diff --git a/packages/app/e2e/app/app.e2e.js b/packages/app/e2e/app/app.e2e.js new file mode 100644 index 00000000..28ffbc90 --- /dev/null +++ b/packages/app/e2e/app/app.e2e.js @@ -0,0 +1,76 @@ +describe('firebase', () => { + it('it should allow creating the default app in JS', () => { + // app is created in tests app before all hook + should.equal(firebase.app()._nativeInitialized, false); + should.equal(firebase.app().name, '[DEFAULT]'); + }); + + it('it should create js apps for natively initialized apps', () => { + should.equal(firebase.app('secondaryFromNative')._nativeInitialized, true); + should.equal(firebase.app('secondaryFromNative').name, 'secondaryFromNative'); + }); + + it('natively initialized apps should have options available in js', () => { + const platformAppConfig = TestHelpers.core.config(); + should.equal(firebase.app().options.apiKey, platformAppConfig.apiKey); + should.equal(firebase.app().options.appId, platformAppConfig.appId); + should.equal(firebase.app().options.databaseURL, platformAppConfig.databaseURL); + should.equal(firebase.app().options.messagingSenderId, platformAppConfig.messagingSenderId); + should.equal(firebase.app().options.projectId, platformAppConfig.projectId); + should.equal(firebase.app().options.storageBucket, platformAppConfig.storageBucket); + }); + + it('it should initialize dynamic apps', () => { + const name = `testscoreapp${global.testRunId}`; + const platformAppConfig = TestHelpers.core.config(); + return firebase.initializeApp(platformAppConfig, name).then(newApp => { + newApp.name.should.equal(name); + newApp.toString().should.equal(name); + newApp.options.apiKey.should.equal(platformAppConfig.apiKey); + return newApp.delete(); + }); + }); + + it('SDK_VERSION should return a string version', () => { + firebase.SDK_VERSION.should.be.a.String(); + }); +}); + +describe('firebase -> X', () => { + it('apps should provide an array of apps', () => { + should.equal(!!firebase.apps.length, true); + should.equal(firebase.apps.includes(firebase.app('[DEFAULT]')), true); + return Promise.resolve(); + }); + + it('can be deleted', async () => { + const name = `testscoreapp${global.testRunId}`; + const platformAppConfig = TestHelpers.core.config(); + const newApp = await firebase.initializeApp(platformAppConfig, name); + + newApp.name.should.equal(name); + newApp.toString().should.equal(name); + newApp.options.apiKey.should.equal(platformAppConfig.apiKey); + + await newApp.delete(); + + (() => { + firebase.app(name); + }).should.throw(`No Firebase App '${name}' has been created - call firebase.initializeApp()`); + }); + + it('prevents the default app from being deleted', async () => { + firebase + .app() + .delete() + .should.be.rejectedWith('Unable to delete the default native firebase app instance.'); + }); + + it('extendApp should provide additional functionality', () => { + const extension = {}; + firebase.app().extendApp({ + extension, + }); + firebase.app().extension.should.equal(extension); + }); +}); diff --git a/packages/app/e2e/app/events.e2e.js b/packages/app/e2e/app/events.e2e.js new file mode 100644 index 00000000..e2379bbb --- /dev/null +++ b/packages/app/e2e/app/events.e2e.js @@ -0,0 +1,76 @@ +const eventName = 'pong'; +const eventName2 = 'ping'; +const eventBody = { + foo: 'bar', +}; + +describe('Core -> EventEmitter', () => { + describe('ReactNativeFirebaseEventEmitter', () => { + it('queues events before app is ready', async () => { + const { + eventsPing, + eventsNotifyReady, + eventsGetListeners, + } = NativeModules.RNFBAppModule; + await eventsNotifyReady(false); + + let readyToResolve = false; + const { resolve, reject, promise } = Promise.defer(); + const emitter = NativeEventEmitter; + + emitter.addListener(eventName, event => { + event.foo.should.equal(eventBody.foo); + if (!readyToResolve) { + return reject(new Error('Event was received before being ready!')); + } + + return resolve(); + }); + + await eventsPing(eventName, eventBody); + await sleep(100); + const nativeListenersBefore = await eventsGetListeners(); + nativeListenersBefore.events.pong.should.equal(1); + + readyToResolve = true; + await eventsNotifyReady(true); + + await promise; + emitter.removeAllListeners(eventName); + + const nativeListenersAfter = await eventsGetListeners(); + + should.equal(nativeListenersAfter.events.pong, undefined); + }); + + it('queues events before a js listener is registered', async () => { + const { + eventsPing, + eventsNotifyReady, + eventsGetListeners, + eventsRemoveListener, + } = NativeModules.RNFBAppModule; + await eventsNotifyReady(true); + const { resolve, promise } = Promise.defer(); + const emitter = NativeEventEmitter; + + await eventsPing(eventName2, eventBody); + await sleep(500); + const nativeListenersBefore = await eventsGetListeners(); + should.equal(nativeListenersBefore.events.ping, undefined); + + emitter.addListener(eventName2, event => { + event.foo.should.equal(eventBody.foo); + return resolve(); + }); + + await promise; + emitter.removeAllListeners(eventName2); + + await eventsRemoveListener(eventName2, true); + const nativeListenersAfter = await eventsGetListeners(); + + should.equal(nativeListenersAfter.events.ping, undefined); + }); + }); +}); diff --git a/packages/app/e2e/utils/util.e2e.js b/packages/app/e2e/utils/util.e2e.js new file mode 100644 index 00000000..f6f716b6 --- /dev/null +++ b/packages/app/e2e/utils/util.e2e.js @@ -0,0 +1,3 @@ +describe('Util', () => { + +}); diff --git a/packages/app/e2e/utils/utils.constants.e2e.js b/packages/app/e2e/utils/utils.constants.e2e.js new file mode 100644 index 00000000..26d14ff9 --- /dev/null +++ b/packages/app/e2e/utils/utils.constants.e2e.js @@ -0,0 +1,16 @@ +describe('Utils -> NativeModules -> Constants', () => { + xdescribe('.androidPlayServices', () => { + it('should be an object', () => { + const { androidPlayServices } = NativeModules.RNFBUtils; + androidPlayServices.should.be.an.Object(); + }); + }); + + xdescribe('.isFirebaseTestLab', () => { + it('should be a boolean', () => { + const { isFirebaseTestLab } = NativeModules.RNFBUtils; + isFirebaseTestLab.should.be.a.Boolean(); + isFirebaseTestLab.should.equal(false); + }); + }); +}); diff --git a/ios/RNFirebase.podspec b/packages/app/ios/RNFBApp.podspec similarity index 81% rename from ios/RNFirebase.podspec rename to packages/app/ios/RNFBApp.podspec index a22dd998..08aadfa4 100644 --- a/ios/RNFirebase.podspec +++ b/packages/app/ios/RNFBApp.podspec @@ -2,7 +2,7 @@ require 'json' package = JSON.parse(File.read('../package.json')) Pod::Spec.new do |s| - s.name = "RNFirebase" + s.name = "RNFBApp" s.version = package["version"] s.description = package["description"] s.summary = <<-DESC @@ -13,8 +13,8 @@ Pod::Spec.new do |s| s.authors = "Invertase Limited" s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" } s.social_media_url = 'http://twitter.com/invertaseio' - s.platform = :ios, "9.0" - s.source_files = 'RNFirebase/**/*.{h,m}' + s.platform = :ios, "10.0" + s.source_files = 'RNFBApp/**/*.{h,m}' s.dependency 'React' - s.dependency 'Firebase/Core' + s.dependency 'Firebase/Core', '~> 5.15.0' end diff --git a/packages/app/ios/RNFBApp.xcodeproj/project.pbxproj b/packages/app/ios/RNFBApp.xcodeproj/project.pbxproj new file mode 100644 index 00000000..5d3bc9f8 --- /dev/null +++ b/packages/app/ios/RNFBApp.xcodeproj/project.pbxproj @@ -0,0 +1,384 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 2744B98621F45429004F8E3F /* RNFBAppModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBAppModule.m */; }; + 2744B99121F46140004F8E3F /* RNFBRCTEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B99021F46140004F8E3F /* RNFBRCTEventEmitter.m */; }; + 2744B9A421F48A4F004F8E3F /* RCTConvert+FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B9A321F48A4F004F8E3F /* RCTConvert+FIROptions.m */; }; + 2744B9A721F57C2F004F8E3F /* RCTConvert+FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B9A621F57C2F004F8E3F /* RCTConvert+FIRApp.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 2744B98021F45429004F8E3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 2744B98221F45429004F8E3F /* libRNFBApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBApp.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2744B98421F45429004F8E3F /* RNFBAppModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBAppModule.h; path = RNFBApp/RNFBAppModule.h; sourceTree = SOURCE_ROOT; }; + 2744B98521F45429004F8E3F /* RNFBAppModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBAppModule.m; path = RNFBApp/RNFBAppModule.m; sourceTree = SOURCE_ROOT; }; + 2744B98D21F45E8B004F8E3F /* RNFBRCTEventEmitter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFBRCTEventEmitter.h; sourceTree = ""; }; + 2744B99021F46140004F8E3F /* RNFBRCTEventEmitter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBRCTEventEmitter.m; sourceTree = ""; }; + 2744B9A221F48826004F8E3F /* RCTConvert+FIROptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+FIROptions.h"; sourceTree = ""; }; + 2744B9A321F48A4F004F8E3F /* RCTConvert+FIROptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+FIROptions.m"; sourceTree = ""; }; + 2744B9A521F57BD9004F8E3F /* RCTConvert+FIRApp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+FIRApp.h"; sourceTree = ""; }; + 2744B9A621F57C2F004F8E3F /* RCTConvert+FIRApp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+FIRApp.m"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2744B97F21F45429004F8E3F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2744B97521F452B8004F8E3F /* Products */ = { + isa = PBXGroup; + children = ( + 2744B98221F45429004F8E3F /* libRNFBApp.a */, + ); + name = Products; + sourceTree = ""; + }; + 2744B98321F45429004F8E3F /* RNFBApp */ = { + isa = PBXGroup; + children = ( + 2744B9A121F48736004F8E3F /* converters */, + 2744B98C21F45C64004F8E3F /* common */, + 2744B98421F45429004F8E3F /* RNFBAppModule.h */, + 2744B98521F45429004F8E3F /* RNFBAppModule.m */, + ); + path = RNFBApp; + sourceTree = ""; + }; + 2744B98C21F45C64004F8E3F /* common */ = { + isa = PBXGroup; + children = ( + 2744B98D21F45E8B004F8E3F /* RNFBRCTEventEmitter.h */, + 2744B99021F46140004F8E3F /* RNFBRCTEventEmitter.m */, + ); + path = common; + sourceTree = ""; + }; + 2744B9A121F48736004F8E3F /* converters */ = { + isa = PBXGroup; + children = ( + 2744B9A221F48826004F8E3F /* RCTConvert+FIROptions.h */, + 2744B9A321F48A4F004F8E3F /* RCTConvert+FIROptions.m */, + 2744B9A521F57BD9004F8E3F /* RCTConvert+FIRApp.h */, + 2744B9A621F57C2F004F8E3F /* RCTConvert+FIRApp.m */, + ); + path = converters; + sourceTree = ""; + }; + 3323F52AAFE26B7384BE4DE3 = { + isa = PBXGroup; + children = ( + 2744B98321F45429004F8E3F /* RNFBApp */, + 2744B97521F452B8004F8E3F /* Products */, + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2744B98121F45429004F8E3F /* RNFBApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBApp" */; + buildPhases = ( + 2744B97E21F45429004F8E3F /* Sources */, + 2744B97F21F45429004F8E3F /* Frameworks */, + 2744B98021F45429004F8E3F /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RNFBApp; + productName = RNFBApp; + productReference = 2744B98221F45429004F8E3F /* libRNFBApp.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3323F95273A95DB34F55C6D7 /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = RNFB; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Invertase; + TargetAttributes = { + 2744B98121F45429004F8E3F = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBApp" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 3323F52AAFE26B7384BE4DE3; + productRefGroup = 2744B97521F452B8004F8E3F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2744B98121F45429004F8E3F /* RNFBApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2744B97E21F45429004F8E3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2744B98621F45429004F8E3F /* RNFBAppModule.m in Sources */, + 2744B9A721F57C2F004F8E3F /* RCTConvert+FIRApp.m in Sources */, + 2744B99121F46140004F8E3F /* RNFBRCTEventEmitter.m in Sources */, + 2744B9A421F48A4F004F8E3F /* RCTConvert+FIROptions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 2744B98921F45429004F8E3F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2744B98A21F45429004F8E3F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3323F77D701E1896E6D239CF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseCore/Frameworks", + "$(SRCROOT)/../../../tests/ios/Pods/FirebaseCore/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 3323F7E33E1559A2B9826720 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseCore/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + ); + "HEADER_SEARCH_PATHS[arch=*]" = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2744B98921F45429004F8E3F /* Debug */, + 2744B98A21F45429004F8E3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3323F7E33E1559A2B9826720 /* Debug */, + 3323F77D701E1896E6D239CF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3323F95273A95DB34F55C6D7 /* Project object */; +} diff --git a/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/packages/app/ios/RNFBApp.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/app/ios/RNFBApp.xcodeproj/xcshareddata/IDETemplateMacros.plist b/packages/app/ios/RNFBApp.xcodeproj/xcshareddata/IDETemplateMacros.plist new file mode 100644 index 00000000..63f0a6e5 --- /dev/null +++ b/packages/app/ios/RNFBApp.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1,24 @@ + + + + + FILEHEADER + +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + diff --git a/packages/app/ios/RNFBApp/RNFBAppModule.h b/packages/app/ios/RNFBApp/RNFBAppModule.h new file mode 100644 index 00000000..e4946fb7 --- /dev/null +++ b/packages/app/ios/RNFBApp/RNFBAppModule.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#import + +@interface RNFBAppModule : NSObject + +@end diff --git a/packages/app/ios/RNFBApp/RNFBAppModule.m b/packages/app/ios/RNFBApp/RNFBAppModule.m new file mode 100644 index 00000000..44c998c9 --- /dev/null +++ b/packages/app/ios/RNFBApp/RNFBAppModule.m @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + +#import "RNFBAppModule.h" +#import "RNFBRCTEventEmitter.h" +#import "RNFBSharedUtils.h" + + +@implementation RNFBAppModule + +#pragma mark - +#pragma mark Module Setup + + RCT_EXPORT_MODULE(); + + - (dispatch_queue_t)methodQueue { + return dispatch_get_main_queue(); + } + + - (void)setBridge:(RCTBridge *)bridge { + [RNFBRCTEventEmitter shared].bridge = bridge; + } + + - (RCTBridge *)bridge { + return [RNFBRCTEventEmitter shared].bridge; + } + +#pragma mark - +#pragma mark Event Methods + + RCT_EXPORT_METHOD(eventsNotifyReady: + (BOOL) ready) { + [[RNFBRCTEventEmitter shared] notifyJsReady:ready]; + } + + RCT_EXPORT_METHOD(eventsGetListeners: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + resolve([[RNFBRCTEventEmitter shared] getListenersDictionary]); + } + + RCT_EXPORT_METHOD(eventsPing: + (NSString *) eventName + eventBody: + (NSDictionary *) eventBody + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + [[RNFBRCTEventEmitter shared] sendEventWithName:eventName body:eventBody]; + resolve(eventBody); + } + + RCT_EXPORT_METHOD(eventsAddListener: + (NSString *) eventName) { + [[RNFBRCTEventEmitter shared] addListener:eventName]; + } + + RCT_EXPORT_METHOD(eventsRemoveListener: + (NSString *) eventName + all: + (BOOL *) all) { + [[RNFBRCTEventEmitter shared] removeListeners:eventName all:all]; + } + +#pragma mark - +#pragma mark Events Unused + + RCT_EXPORT_METHOD(addListener: + (NSString *) eventName) { + // Keep: Required for RN built in Event Emitter Calls. + } + + RCT_EXPORT_METHOD(removeListeners: + (NSInteger) count) { + // Keep: Required for RN built in Event Emitter Calls. + } + +#pragma mark - +#pragma mark Firebase App Methods + + RCT_EXPORT_METHOD(initializeApp: + (FIROptions *) firOptions + appConfig: + (NSDictionary *) appConfig + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + RCTUnsafeExecuteOnMainQueueSync(^{ + FIRApp *firApp; + NSString *appName = [appConfig valueForKey:@"name"]; + + @try { + if (!appName || [appName isEqualToString:DEFAULT_APP_DISPLAY_NAME]) { + [FIRApp configureWithOptions:firOptions]; + firApp = [FIRApp defaultApp]; + } else { + [FIRApp configureWithName:appName options:firOptions]; + firApp = [FIRApp appNamed:appName]; + } + } @catch (NSException *exception) { + // TODO js error builder + // reject(@"code",@"message",[exception ]); + } + + firApp.dataCollectionDefaultEnabled = (BOOL) [appConfig valueForKey:@"automaticDataCollectionEnabled"]; + + resolve([RNFBSharedUtils firAppToDictionary:firApp]); + }); + } + + RCT_EXPORT_METHOD(deleteApp: + (FIRApp *) firApp + resolver: + (RCTPromiseResolveBlock) resolve + rejecter: + (RCTPromiseRejectBlock) reject) { + if (!firApp) { + return resolve([NSNull null]); + } + + [firApp deleteApp:^(BOOL success) { + if (success) { + resolve([NSNull null]); + } else { + // try again once more + [firApp deleteApp:^(BOOL success2) { + if (success2) { + resolve([NSNull null]); + } else { + // TODO js error builder + reject(@"app/delete-app-failed", @"Failed to delete the specified app.", nil); + } + }]; + } + }]; + } + + - (NSDictionary *)constantsToExport { + NSDictionary *firApps = [FIRApp allApps]; + NSMutableArray *appsArray = [NSMutableArray new]; + NSMutableDictionary *constants = [NSMutableDictionary new]; + for (id key in firApps) { + [appsArray addObject:[RNFBSharedUtils firAppToDictionary:firApps[key]]]; + } + constants[@"apps"] = appsArray; + return constants; + } + + + (BOOL)requiresMainQueueSetup { + return YES; + } +@end diff --git a/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.h b/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.h new file mode 100644 index 00000000..0743d0bc --- /dev/null +++ b/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + + +/** + * Listeners for Firebase events and emits them to the JS layer + */ +@interface RNFBRCTEventEmitter : NSObject + +/** + * The RCTBridge. Assigned by `RNFBAppModule` + */ +@property(nonatomic, weak) RCTBridge *bridge; + +/** + * Returns the shared instance + * + * @returns RNFBRCTEventEmitter. + */ ++ (RNFBRCTEventEmitter *)shared; + +/** + * Add an event listener + * + * @param eventName NSString event name. + */ +- (void)addListener:(NSString *)eventName; + +/** + * Removes event listeners + */ +- (void)removeListeners:(NSString *)eventName all:(BOOL *)all; + +/** + * Send an event to JS with the specified name and body + * + */ +- (void)sendEventWithName:(NSString *)eventName body:(id)body; + +/** + * Notify the event emitter that JS has loaded and is ready to receive events. + * + */ +- (void)notifyJsReady:(bool)ready; + +/** + * Returns a dictionary of all registered events & counts. Mainly for testing. + * + * @return NSDictionary + */ +- (NSDictionary *)getListenersDictionary; +@end diff --git a/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.m b/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.m new file mode 100644 index 00000000..a62ed0eb --- /dev/null +++ b/packages/app/ios/RNFBApp/common/RNFBRCTEventEmitter.m @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "RNFBRCTEventEmitter.h" + +@interface RNFBRCTEventEmitter () +@property(atomic, assign) bool jsReady; +@property(atomic, assign) NSInteger jsListenerCount; +@property(nonatomic, strong) NSMutableDictionary *jsListeners; +@property(nonatomic, strong) NSMutableArray *queuedEvents; +@property(readonly) BOOL isObserving; +@end + +NSString *const RNFBRCTEventNameKey = @"name"; +NSString *const RNFBRCTEventBodyKey = @"body"; + +@implementation RNFBRCTEventEmitter + + static RNFBRCTEventEmitter *sharedEventEmitter_; + + + (void)load { + sharedEventEmitter_ = [[RNFBRCTEventEmitter alloc] init]; + } + + + (RNFBRCTEventEmitter *)shared { + return sharedEventEmitter_; + } + + - (instancetype)init { + self = [super init]; + + if (self) { + self.jsReady = FALSE; + self.queuedEvents = [NSMutableArray array]; + self.jsListeners = [NSMutableDictionary dictionary]; + } + + return self; + } + + - (void)notifyJsReady:(bool)jsReady { + @synchronized (self.jsListeners) { + self.jsReady = jsReady; + if (jsReady) { + for (id event in [self.queuedEvents copy]) { + [self sendEventWithName:event[RNFBRCTEventNameKey] body:event[RNFBRCTEventBodyKey]]; + @synchronized (self.queuedEvents) { + [self.queuedEvents removeObject:event]; + } + } + } + } + } + + - (void)sendEventWithName:(NSString *)eventName body:(id)body { + @synchronized (self.jsListeners) { + if (self.bridge && self.isObserving && self.jsListeners[eventName] != nil) { + NSString *prefixedEventName = [@"rnfb_" stringByAppendingString:eventName]; + [self.bridge enqueueJSCall:@"RCTDeviceEventEmitter" + method:@"emit" + args:body ? @[prefixedEventName, body] : @[prefixedEventName] + completion:NULL]; + } else { + @synchronized (self.queuedEvents) { + [self.queuedEvents addObject:@{RNFBRCTEventNameKey: eventName, RNFBRCTEventBodyKey: body}]; + } + } + } + } + + - (void)addListener:(NSString *)eventName { + @synchronized (self.jsListeners) { + self.jsListenerCount++; + + if (self.jsListeners[eventName] == nil) { + self.jsListeners[eventName] = @([@1 integerValue]); + } else { + self.jsListeners[eventName] = @([self.jsListeners[eventName] integerValue] + [@1 integerValue]); + } + + for (id event in [self.queuedEvents copy]) { + if ([event[RNFBRCTEventNameKey] isEqualToString:eventName]) { + [self sendEventWithName:event[RNFBRCTEventNameKey] body:event[RNFBRCTEventBodyKey]]; + @synchronized (self.queuedEvents) { + [self.queuedEvents removeObject:event]; + } + } + } + } + } + + - (void)removeListeners:(NSString *)eventName all:(BOOL *)all { + @synchronized (self.jsListeners) { + if (self.jsListeners[eventName] != nil) { + NSInteger listenersForEvent = [self.jsListeners[eventName] integerValue]; + + if (listenersForEvent <= 1 || all) { + @synchronized (self.jsListeners) { + [self.jsListeners removeObjectForKey:eventName]; + } + } else { + @synchronized (self.jsListeners) { + self.jsListeners[eventName] = @([self.jsListeners[eventName] integerValue] - [@1 integerValue]); + } + } + + if (all) { + self.jsListenerCount = self.jsListenerCount - listenersForEvent; + } else { + self.jsListenerCount = self.jsListenerCount - [@1 integerValue]; + } + } + } + } + + - (NSDictionary *)getListenersDictionary { + NSMutableDictionary *listenersDictionary = [NSMutableDictionary new]; + listenersDictionary[@"listeners"] = @(self.jsListenerCount); + listenersDictionary[@"queued"] = @([self.queuedEvents count]); + listenersDictionary[@"events"] = [self.jsListeners copy]; + return listenersDictionary; + } + + + - (BOOL)isObserving { + return self.jsReady && self.jsListenerCount > 0; + } + +@end diff --git a/packages/app/ios/RNFBApp/common/RNFBSharedUtils.h b/packages/app/ios/RNFBApp/common/RNFBSharedUtils.h new file mode 100644 index 00000000..06a99877 --- /dev/null +++ b/packages/app/ios/RNFBApp/common/RNFBSharedUtils.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef RNFBSharedUtils_h +#define RNFBSharedUtils_h + +#import +#import "RCTBridgeModule.h" + +#ifdef DEBUG +#define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); +#else +#define DLog(...) +#endif + +#define ELog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); + +#pragma mark - +#pragma mark Constants + +extern NSString *const DEFAULT_APP_DISPLAY_NAME; +extern NSString *const DEFAULT_APP_NAME; + +@interface RNFBSharedUtils : NSObject + + +#pragma mark - +#pragma mark Methods + ++ (NSDictionary *)firAppToDictionary:(FIRApp *)firApp; + ++ (void)rejectPromiseWithExceptionDict:(RCTPromiseRejectBlock)reject exception:(NSException *)exception; + +@end + +#endif \ No newline at end of file diff --git a/packages/app/ios/RNFBApp/common/RNFBSharedUtils.m b/packages/app/ios/RNFBApp/common/RNFBSharedUtils.m new file mode 100644 index 00000000..e7664463 --- /dev/null +++ b/packages/app/ios/RNFBApp/common/RNFBSharedUtils.m @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "RNFBSharedUtils.h" + +#pragma mark - +#pragma mark Constants + +NSString *const DEFAULT_APP_DISPLAY_NAME = @"[DEFAULT]"; +NSString *const DEFAULT_APP_NAME = @"__FIRAPP_DEFAULT"; + +@implementation RNFBSharedUtils + static NSString *const RNFBErrorDomain = @"RNFBErrorDomain"; + +#pragma mark - +#pragma mark Methods + + + (NSDictionary *)firAppToDictionary:(FIRApp *)firApp { + FIROptions *firOptions = [firApp options]; + NSMutableDictionary *firAppDictionary = [NSMutableDictionary new]; + NSMutableDictionary *firAppOptions = [NSMutableDictionary new]; + NSMutableDictionary *firAppConfig = [NSMutableDictionary new]; + + NSString *name = [firApp name]; + if ([name isEqualToString:DEFAULT_APP_NAME]) { + name = DEFAULT_APP_DISPLAY_NAME; + } + + firAppConfig[@"name"] = name; + firAppConfig[@"automaticDataCollectionEnabled"] = @([firApp isDataCollectionDefaultEnabled]); + + firAppOptions[@"apiKey"] = firOptions.APIKey; + firAppOptions[@"appId"] = firOptions.googleAppID; + firAppOptions[@"projectId"] = firOptions.projectID; + firAppOptions[@"databaseURL"] = firOptions.databaseURL; + firAppOptions[@"gaTrackingId"] = firOptions.trackingID; + firAppOptions[@"storageBucket"] = firOptions.storageBucket; + firAppOptions[@"messagingSenderId"] = firOptions.GCMSenderID; + // missing from android sdk - ios only: + firAppOptions[@"clientId"] = firOptions.clientID; + firAppOptions[@"androidClientID"] = firOptions.androidClientID; + firAppOptions[@"deepLinkUrlScheme"] = firOptions.deepLinkURLScheme; + + firAppDictionary[@"options"] = firAppOptions; + firAppDictionary[@"appConfig"] = firAppConfig; + + return firAppDictionary; + } + + + (void)rejectPromiseWithExceptionDict:(RCTPromiseRejectBlock)reject exception:(NSException *)exception;{ + NSMutableDictionary * userInfo = [NSMutableDictionary dictionary]; + + [userInfo setValue:@(YES) forKey:@"fatal"]; + [userInfo setValue:@"unknown" forKey:@"code"]; + [userInfo setValue:exception.reason forKey:@"message"]; + [userInfo setValue:exception.name forKey:@"nativeErrorCode"]; + [userInfo setValue:exception.reason forKey:@"nativeErrorMessage"]; + + NSError *error = [[NSError alloc] initWithDomain:RNFBErrorDomain code:666 userInfo:userInfo]; + + // TODO hook into crashlytics - report as handled exception? + + reject(exception.name, exception.reason, error); + } +@end \ No newline at end of file diff --git a/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.h b/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.h new file mode 100644 index 00000000..76c1fdf8 --- /dev/null +++ b/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + +@interface RCTConvert (FIRApp) ++ (FIRApp *)firAppFromString:(NSString *)appName; +@end diff --git a/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.m b/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.m new file mode 100644 index 00000000..6f73725f --- /dev/null +++ b/packages/app/ios/RNFBApp/converters/RCTConvert+FIRApp.m @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "RCTConvert+FIRApp.h" +#import "RNFBSharedUtils.h" + +@implementation RCTConvert (FIRApp) + + (FIRApp *)firAppFromString:(NSString *)appName { + if ([appName isEqualToString:DEFAULT_APP_DISPLAY_NAME]) { + return [FIRApp defaultApp]; + } + + return [FIRApp appNamed:appName]; + } + + RCT_CUSTOM_CONVERTER(FIRApp *, FIRApp, [self firAppFromString:[self NSString:json]]); +@end diff --git a/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.h b/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.h new file mode 100644 index 00000000..5f072649 --- /dev/null +++ b/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + +@interface RCTConvert (FIROptions) ++ (FIROptions *)convertRawOptions:(NSDictionary *)rawOptions; +@end diff --git a/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.m b/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.m new file mode 100644 index 00000000..b9d750f2 --- /dev/null +++ b/packages/app/ios/RNFBApp/converters/RCTConvert+FIROptions.m @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "RCTConvert+FIROptions.h" + +@implementation RCTConvert (FIROptions) + + + (FIROptions *)convertRawOptions:(NSDictionary *)rawOptions { + FIROptions *firOptions = [[FIROptions alloc] initWithGoogleAppID:[rawOptions valueForKey:@"appId"] GCMSenderID:[rawOptions valueForKey:@"messagingSenderId"]]; + firOptions.APIKey = [rawOptions valueForKey:@"apiKey"]; + firOptions.projectID = [rawOptions valueForKey:@"projectId"]; + firOptions.clientID = [rawOptions valueForKey:@"clientId"]; + firOptions.trackingID = [rawOptions valueForKey:@"gaTrackingId"]; + firOptions.databaseURL = [rawOptions valueForKey:@"databaseURL"]; + firOptions.storageBucket = [rawOptions valueForKey:@"storageBucket"]; + firOptions.androidClientID = [rawOptions valueForKey:@"androidClientId"]; + firOptions.deepLinkURLScheme = [rawOptions valueForKey:@"deepLinkURLScheme"]; + firOptions.bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; + return firOptions; + } + + RCT_CUSTOM_CONVERTER(FIROptions *, FIROptions, [self convertRawOptions:[self NSDictionary:json]]); +@end diff --git a/packages/app/lib/FirebaseApp.js b/packages/app/lib/FirebaseApp.js new file mode 100644 index 00000000..5ff6c047 --- /dev/null +++ b/packages/app/lib/FirebaseApp.js @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { getAppModule } from './internal/registry/nativeModule'; + +export default class FirebaseApp { + constructor(options, appConfig, fromNative, deleteApp) { + const { name, automaticDataCollectionEnabled } = appConfig; + + this._name = name; + this._deleted = false; + this._deleteApp = deleteApp; + this._options = Object.assign({}, options); + this._automaticDataCollectionEnabled = !!automaticDataCollectionEnabled; + + if (fromNative) { + this._initialized = true; + this._nativeInitialized = true; + } else { + this._initialized = false; + this._nativeInitialized = false; + } + } + + get name() { + return this._name; + } + + get options() { + return Object.assign({}, this._options); + } + + get automaticDataCollectionEnabled() { + this._checkDestroyed_(); + return this._automaticDataCollectionEnabled; + } + + // TODO assert ow.boolean + set automaticDataCollectionEnabled(enabled) { + this._checkDestroyed(); + getAppModule().setAutomaticDataCollectionEnabled(this.name, enabled); + this._automaticDataCollectionEnabled = enabled; + } + + _checkDestroyed() { + if (this._deleted) { + throw new Error(`Firebase App named '${this._name}' already deleted`); + } + } + + // TODO assert ow.object + extendApp(extendedProps) { + this._checkDestroyed(); + Object.assign(this, extendedProps || {}); + } + + delete() { + this._checkDestroyed(); + return this._deleteApp(); + } + + toString() { + return this.name; + } +} diff --git a/packages/app/lib/index.d.ts b/packages/app/lib/index.d.ts new file mode 100644 index 00000000..f59b66da --- /dev/null +++ b/packages/app/lib/index.d.ts @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import {ReactNativeFirebaseNamespace} from "@react-native-firebase/app-types"; + +/** + * @firebase firebase + */ +declare module 'react-native-firebase' { + import { ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types'; + const ReactNativeFirebase: {} & ReactNativeFirebaseNamespace; + export default ReactNativeFirebase; +} + +declare module '@react-native-firebase/app-types' { + interface ReactNativeFirebaseNamespace { + utils?: { + (app?: FirebaseApp): FirebaseUtilsModule; + }; + } + + interface FirebaseApp { + utils?(app?: FirebaseApp): FirebaseUtilsModule; + } +} diff --git a/packages/app/lib/index.js b/packages/app/lib/index.js new file mode 100644 index 00000000..651427aa --- /dev/null +++ b/packages/app/lib/index.js @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { getFirebaseRoot } from './internal/registry/namespace'; + +export const firebase = getFirebaseRoot(); + +export default firebase; diff --git a/packages/app/lib/index.js.flow b/packages/app/lib/index.js.flow new file mode 100644 index 00000000..6e7869db --- /dev/null +++ b/packages/app/lib/index.js.flow @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * @firebase firebase + */ +declare module 'react-native-firebase' { + import type { ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types/index.js.flow'; + + declare export default {} & ReactNativeFirebaseNamespace; +} + +declare module '@react-native-firebase/app-types' { + declare interface ReactNativeFirebaseNamespace {} + + declare interface FirebaseApp {} +} diff --git a/packages/app/lib/internal/FirebaseModule.js b/packages/app/lib/internal/FirebaseModule.js new file mode 100644 index 00000000..8ba823c0 --- /dev/null +++ b/packages/app/lib/internal/FirebaseModule.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { getNativeModule } from './registry/nativeModule'; +import SharedEventEmitter from './SharedEventEmitter'; + +export default class FirebaseModule { + constructor(app, config, customUrlOrRegion) { + this._app = app; + this._nativeModule = null; + this._customUrlOrRegion = customUrlOrRegion; + this._config = Object.assign({}, config); + } + + get app() { + return this._app; + } + + get emitter() { + return SharedEventEmitter + } + + get native() { + if (this._nativeModule) return this._nativeModule; + this._nativeModule = getNativeModule(this); + return this._nativeModule; + } +} + +// Instance of checks don't work once compiled +FirebaseModule.__extended__ = {}; diff --git a/packages/app/lib/internal/NativeFirebaseError.js b/packages/app/lib/internal/NativeFirebaseError.js new file mode 100644 index 00000000..0e66e6c8 --- /dev/null +++ b/packages/app/lib/internal/NativeFirebaseError.js @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export default class NativeFirebaseError extends Error { + constructor(nativeError, jsStack, namespace) { + super(); + const { userInfo } = nativeError; + + Object.defineProperty(this, 'namespace', { + enumerable: false, + value: namespace, + }); + + Object.defineProperty(this, 'code', { + enumerable: false, + value: `${this.namespace}/${userInfo.code || 'unknown'}`, + }); + + Object.defineProperty(this, 'message', { + enumerable: false, + value: `[${this.code}] ${userInfo.message || nativeError.message}`, + }); + + Object.defineProperty(this, 'jsStack', { + enumerable: false, + value: jsStack, + }); + + Object.defineProperty(this, 'userInfo', { + enumerable: false, + value: userInfo, + }); + + Object.defineProperty(this, 'nativeErrorCode', { + enumerable: false, + value: userInfo.nativeErrorCode || null, + }); + + Object.defineProperty(this, 'nativeErrorMessage', { + enumerable: false, + value: userInfo.nativeErrorMessage || null, + }); + + this.stack = this.getStackWithMessage(`NativeFirebaseError: ${this.message}`); + + // Unused + // this.nativeStackIOS = nativeError.nativeStackIOS; + // this.nativeStackAndroid = nativeError.nativeStackAndroid; + } + + /** + * Build a stack trace that includes JS stack prior to calling the native method. + * + * @returns {string} + */ + getStackWithMessage(message) { + return [message, ...this.jsStack.split('\n').slice(2, 13)].join('\n'); + } +} diff --git a/packages/app/lib/internal/RNFBNativeEventEmitter.js b/packages/app/lib/internal/RNFBNativeEventEmitter.js new file mode 100644 index 00000000..8cd5ce27 --- /dev/null +++ b/packages/app/lib/internal/RNFBNativeEventEmitter.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { NativeModules, NativeEventEmitter } from 'react-native'; + +const { RNFBAppModule } = NativeModules; + +class RNFBNativeEventEmitter extends NativeEventEmitter { + constructor() { + super(RNFBAppModule); + } + + addListener(eventType, listener, context) { + RNFBAppModule.eventsAddListener(eventType); + return super.addListener(`rnfb_${eventType}`, listener, context); + } + + removeAllListeners(eventType) { + RNFBAppModule.eventsRemoveListener(eventType, true); + super.removeAllListeners(`rnfb_${eventType}`); + } + + removeSubscription(subscription) { + RNFBAppModule.eventsRemoveListener(subscription.eventType.replace('rnfb_')); + super.removeSubscription(subscription); + } +} + +export default new RNFBNativeEventEmitter(); diff --git a/packages/app/lib/internal/SharedEventEmitter.js b/packages/app/lib/internal/SharedEventEmitter.js new file mode 100644 index 00000000..58b1ec99 --- /dev/null +++ b/packages/app/lib/internal/SharedEventEmitter.js @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter'; + +export default new EventEmitter(); diff --git a/packages/app/lib/internal/constants.js b/packages/app/lib/internal/constants.js new file mode 100644 index 00000000..07c777a2 --- /dev/null +++ b/packages/app/lib/internal/constants.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export const APP_NATIVE_MODULE = 'RNFBAppModule'; + +export const DEFAULT_APP_NAME = '[DEFAULT]'; + +export const KNOWN_NAMESPACES = [ + // with APIs + 'admob', + 'auth', + 'analytics', + 'config', + 'crashlytics', + 'database', + 'fiam', + 'firestore', + 'functions', + 'iid', + 'invites', + 'indexing', + 'storage', + 'links', + 'messaging', + 'mlkit', + 'notifications', + 'perf', + 'utils', + // documentation only + // 'predictions', + // 'ab-testing' +]; diff --git a/packages/app/lib/internal/index.js b/packages/app/lib/internal/index.js new file mode 100644 index 00000000..26f49350 --- /dev/null +++ b/packages/app/lib/internal/index.js @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export * from './constants'; +export * from './registry/app'; +export * from './registry/namespace'; +export * from './registry/nativeModule'; +export { default as FirebaseModule } from './FirebaseModule'; +export { default as FirebaseApp } from '../FirebaseApp'; +export { default as SharedEventEmitter } from './SharedEventEmitter'; diff --git a/packages/app/lib/internal/registry/app.js b/packages/app/lib/internal/registry/app.js new file mode 100644 index 00000000..648c3fda --- /dev/null +++ b/packages/app/lib/internal/registry/app.js @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { isObject, isNull, isString, isUndefined } from '@react-native-firebase/common'; + +import FirebaseApp from '../../FirebaseApp'; +import { getAppModule } from './nativeModule'; +import { DEFAULT_APP_NAME } from '../constants'; + +const APP_REGISTRY = {}; +let onAppCreateFn = null; +let onAppDestroyFn = null; +let initializedNativeApps = false; + +/** + * This was needed to avoid metro require cycles... + * @param fn + */ +export function setOnAppCreate(fn) { + onAppCreateFn = fn; +} + +/** + * This was needed to avoid metro require cycles... + * @param fn + */ +export function setOnAppDestroy(fn) { + onAppDestroyFn = fn; +} + +/** + * Initializes all apps that were created natively (android/ios), + * e.g. the Default firebase app from plist/json google services file. + */ +export function initializeNativeApps() { + const nativeModule = getAppModule(); + const { apps } = nativeModule; + + if (apps && apps.length) { + for (let i = 0; i < apps.length; i++) { + const { appConfig, options } = apps[i]; + const { name } = appConfig; + APP_REGISTRY[name] = new FirebaseApp( + options, + appConfig, + true, + deleteApp.bind(null, name, true), + ); + onAppCreateFn(APP_REGISTRY[name]); + } + } + + initializedNativeApps = true; +} + +/** + * Get an app by name; or the default app. + * + * On first call of this method it will initialize any + * natively created apps in JS. This makes this 'lazy load'. + * + * @param name + */ +export function getApp(name = DEFAULT_APP_NAME) { + if (!initializedNativeApps) initializeNativeApps(); + const app = APP_REGISTRY[name]; + + if (!app) { + throw new Error(`No Firebase App '${name}' has been created - call firebase.initializeApp()`); + } + + return app; +} + +/** + * Gets all app instances, used for `firebase.apps` + */ +export function getApps() { + return Object.values(APP_REGISTRY); +} + +/** + * + * @param options + * @param configOrName + */ +export function initializeApp(options = {}, configOrName) { + let appConfig = configOrName; + + if (!isObject(configOrName) || isNull(configOrName)) { + appConfig = { + name: configOrName, + automaticResourceManagement: false, + automaticDataCollectionEnabled: true, + }; + } + + if (isUndefined(appConfig.name)) { + appConfig.name = DEFAULT_APP_NAME; + } + + const { name } = appConfig; + + if (!name || !isString(name)) { + return Promise.reject(new Error(`Illegal App name: '${name}'`)); + } + + if (APP_REGISTRY[name]) { + return Promise.reject(new Error(`Firebase App named '${name}' already exists`)); + } + + // VALIDATE OPTIONS + if (!isObject(options)) { + return Promise.reject( + new Error(`firebase.initializeApp(options, <- expects an Object but got '${typeof options}'`), + ); + } + + if (!isString(options.apiKey)) { + return Promise.reject(new Error(`Missing or invalid FirebaseOptions property 'apiKey'.`)); + } + + if (!isString(options.appId)) { + return Promise.reject(new Error(`Missing or invalid FirebaseOptions property 'appId'.`)); + } + + // TODO - make required only if database module exists - init app on native ios&android needs changing also + if (!isString(options.databaseURL)) { + return Promise.reject(new Error(`Missing or invalid FirebaseOptions property 'databaseURL'.`)); + } + + // TODO - make required only if messaging/notifications module exists - init app on native ios&android needs changing also + if (!isString(options.messagingSenderId)) { + return Promise.reject( + new Error(`Missing or invalid FirebaseOptions property 'messagingSenderId'.`), + ); + } + + if (!isString(options.projectId)) { + return Promise.reject(new Error(`Missing or invalid FirebaseOptions property 'projectId'.`)); + } + + // TODO - make required only if database module exists - init app on native ios&android needs changing also + if (!isString(options.storageBucket)) { + return Promise.reject( + new Error(`Missing or invalid FirebaseOptions property 'storageBucket'.`), + ); + } + + const app = new FirebaseApp(options, { name }, false, deleteApp.bind(null, name, true)); + + APP_REGISTRY[name] = app; + onAppCreateFn(APP_REGISTRY[name]); + + return getAppModule() + .initializeApp(options, { name }) + .then(() => { + app._intialized = true; + return app; + }); +} + +/** + * + */ +export function deleteApp(name, nativeInitialized) { + if (name === DEFAULT_APP_NAME && nativeInitialized) { + return Promise.reject(new Error('Unable to delete the default native firebase app instance.')); + } + + const app = APP_REGISTRY[name]; + + const nativeModule = getAppModule(); + + return nativeModule.deleteApp(name).then(() => { + app._deleted = true; + onAppDestroyFn(app); + delete APP_REGISTRY[name]; + }); +} diff --git a/packages/app/lib/internal/registry/namespace.js b/packages/app/lib/internal/registry/namespace.js new file mode 100644 index 00000000..ba6abaeb --- /dev/null +++ b/packages/app/lib/internal/registry/namespace.js @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { isString } from '@react-native-firebase/common'; + +import SDK_VERSION from '../../version'; +import FirebaseApp from '../../FirebaseApp'; +import FirebaseModule from '../FirebaseModule'; +import { getApp, getApps, initializeApp, setOnAppCreate, setOnAppDestroy } from './app'; +import { KNOWN_NAMESPACES, DEFAULT_APP_NAME } from '../constants'; + +// firebase.X +let FIREBASE_ROOT = null; + +const NAMESPACE_REGISTRY = {}; +const APP_MODULE_INSTANCE = {}; +const ROOT_MODULE_INSTANCE = {}; +const MODULE_GETTER_FOR_APP = {}; +const MODULE_GETTER_FOR_ROOT = {}; + +/** + * Attaches module namespace getters on every newly created app. + * + * Structured like this to avoid metro require cycles. + */ +setOnAppCreate(app => { + for (let i = 0; i < KNOWN_NAMESPACES.length; i++) { + const moduleNamespace = KNOWN_NAMESPACES[i]; + Object.defineProperty(app, moduleNamespace, { + enumerable: false, + get: firebaseAppModuleProxy.bind(null, app, moduleNamespace), + }); + } +}); + +/** + * Destroys all APP_MODULE_INSTANCE & MODULE_GETTER_FOR_APP objects relating to the + * recently destroyed app. + * + * Structured like this to avoid metro require cycles. + */ +setOnAppDestroy(app => { + delete APP_MODULE_INSTANCE[app.name]; + delete MODULE_GETTER_FOR_APP[app.name]; +}); + +/** + * + * @param app + * @param moduleNamespace + * @returns {*} + */ +function getOrCreateModuleForApp(app, moduleNamespace) { + if (MODULE_GETTER_FOR_APP[app.name] && MODULE_GETTER_FOR_APP[app.name][moduleNamespace]) { + return MODULE_GETTER_FOR_APP[app.name][moduleNamespace]; + } + + if (!MODULE_GETTER_FOR_APP[app.name]) MODULE_GETTER_FOR_APP[app.name] = {}; + + const { hasCustomUrlOrRegionSupport, hasMultiAppSupport, ModuleClass } = NAMESPACE_REGISTRY[ + moduleNamespace + ]; + + // modules such as analytics only run on the default app + if (!hasMultiAppSupport && app.name !== DEFAULT_APP_NAME) { + throw new Error( + [ + `You attempted to call "firebase.app('${ + app.name + }').${moduleNamespace}" but; ${moduleNamespace} does not support multiple Firebase Apps.`, + '', + `Ensure you access ${moduleNamespace} from the default application only.`, + ].join('\r\n'), + ); + } + + // e.g. firebase.storage(customUrlOrRegion) + function firebaseModuleWithArgs(customUrlOrRegion) { + if (customUrlOrRegion !== undefined) { + if (!hasCustomUrlOrRegionSupport) { + // TODO throw Module does not support arguments error + } + + if (!isString(customUrlOrRegion)) { + // TODO throw Module first argument must be a string error + } + } + + const key = customUrlOrRegion ? `${customUrlOrRegion}:${moduleNamespace}` : moduleNamespace; + + if (!APP_MODULE_INSTANCE[app.name]) { + APP_MODULE_INSTANCE[app.name] = {}; + } + + if (!APP_MODULE_INSTANCE[app.name][key]) { + APP_MODULE_INSTANCE[app.name][key] = new ModuleClass( + app, + NAMESPACE_REGISTRY[moduleNamespace], + customUrlOrRegion, + ); + } + + return APP_MODULE_INSTANCE[app.name][key]; + } + + MODULE_GETTER_FOR_APP[moduleNamespace] = firebaseModuleWithArgs; + return MODULE_GETTER_FOR_APP[moduleNamespace]; +} + +/** + * + * @param moduleNamespace + * @returns {*} + */ +function getOrCreateModuleForRoot(moduleNamespace) { + if (MODULE_GETTER_FOR_ROOT[moduleNamespace]) return MODULE_GETTER_FOR_ROOT[moduleNamespace]; + + const { statics, hasMultiAppSupport, ModuleClass } = NAMESPACE_REGISTRY[moduleNamespace]; + + // e.g. firebase.storage(app) + function firebaseModuleWithApp(app) { + const _app = app || getApp(); + + if (!(_app instanceof FirebaseApp)) { + throw new Error( + [ + `"firebase.${moduleNamespace}(app)" arg expects a FirebaseApp instance or undefined.`, + '', + `Ensure the arg provided is a Firebase app instance; or no args to use the default Firebase app.`, + ].join('\r\n'), + ); + } + + // modules such as analytics only run on the default app + if (!hasMultiAppSupport && _app.name !== DEFAULT_APP_NAME) { + throw new Error( + [ + `You attempted to call "firebase.${moduleNamespace}(app)" but; ${moduleNamespace} does not support multiple Firebase Apps.`, + '', + `Ensure the app provided is the default Firebase app only and not the "${ + _app.name + }" app.`, + ].join('\r\n'), + ); + } + + if (!ROOT_MODULE_INSTANCE[_app.name]) { + ROOT_MODULE_INSTANCE[_app.name] = {}; + } + + if (!ROOT_MODULE_INSTANCE[_app.name][moduleNamespace]) { + ROOT_MODULE_INSTANCE[_app.name][moduleNamespace] = new ModuleClass( + _app, + NAMESPACE_REGISTRY[moduleNamespace], + ); + } + + return ROOT_MODULE_INSTANCE[_app.name][moduleNamespace]; + } + + Object.assign(firebaseModuleWithApp, statics || {}); + Object.freeze(firebaseModuleWithApp); + MODULE_GETTER_FOR_ROOT[moduleNamespace] = firebaseModuleWithApp; + + return MODULE_GETTER_FOR_ROOT[moduleNamespace]; +} + +/** + * + * @param firebaseNamespace + * @param moduleNamespace + * @returns {*} + */ +function firebaseRootModuleProxy(firebaseNamespace, moduleNamespace) { + if (NAMESPACE_REGISTRY[moduleNamespace]) { + return getOrCreateModuleForRoot(moduleNamespace); + } + + throw new Error( + [ + `You attempted to use 'firebase.${moduleNamespace}' but this module could not be found.`, + '', + `Ensure you have installed and imported the '@react-native-firebase/${moduleNamespace}' package.`, + ].join('\r\n'), + ); +} + +/** + * + * @param app + * @param moduleNamespace + * @returns {*} + */ +export function firebaseAppModuleProxy(app, moduleNamespace) { + if (NAMESPACE_REGISTRY[moduleNamespace]) { + app._checkDestroyed(); + return getOrCreateModuleForApp(app, moduleNamespace); + } + + throw new Error( + [ + `You attempted to use "firebase.app('${ + app.name + }').${moduleNamespace}" but this module could not be found.`, + '', + `Ensure you have installed and imported the '@react-native-firebase/${moduleNamespace}' package.`, + ].join('\r\n'), + ); +} + +/** + * + * @returns {*} + */ +export function createFirebaseRoot() { + FIREBASE_ROOT = { + initializeApp, + get app() { + return getApp; + }, + get apps() { + return getApps(); + }, + SDK_VERSION, + }; + + for (let i = 0; i < KNOWN_NAMESPACES.length; i++) { + const namespace = KNOWN_NAMESPACES[i]; + Object.defineProperty(FIREBASE_ROOT, namespace, { + enumerable: false, + get: firebaseRootModuleProxy.bind(null, FIREBASE_ROOT, namespace), + }); + } + + return Object.freeze(FIREBASE_ROOT); +} + +/** + * + * @returns {*} + */ +export function getFirebaseRoot() { + if (FIREBASE_ROOT) return FIREBASE_ROOT; + return createFirebaseRoot(); +} + +/** + * + * @param options + * @returns {*} + */ +export function createModuleNamespace(options = {}) { + const { namespace, ModuleClass, version } = options; + + if (!NAMESPACE_REGISTRY[namespace]) { + // validation only for internal / module dev usage + // instanceof does not work in build + if (FirebaseModule.__extended__ !== ModuleClass.__extended__) { + throw new Error('INTERNAL ERROR: ModuleClass must be an instance of FirebaseModule.'); + } + + if (version !== SDK_VERSION) { + throw new Error( + [ + `You've attempted to require '@react-native-firebase/${namespace}' version '${version}', ` + + `however, the '@react-native-firebase/app' module is of a different version (${SDK_VERSION}).`, + '', + `All React Native Firebase modules must be of the same version. Please ensure they match up ` + + `in your package.json file and re-run yarn/npm install.`, + ].join('\n'), + ); + } + + NAMESPACE_REGISTRY[namespace] = Object.assign({}, options); + } + + return getFirebaseRoot()[namespace]; +} diff --git a/packages/app/lib/internal/registry/nativeModule.js b/packages/app/lib/internal/registry/nativeModule.js new file mode 100644 index 00000000..dcad7ca5 --- /dev/null +++ b/packages/app/lib/internal/registry/nativeModule.js @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { NativeModules, Platform } from 'react-native'; + +import { APP_NATIVE_MODULE } from '../constants'; +import SharedEventEmitter from '../SharedEventEmitter'; +import NativeFirebaseError from '../NativeFirebaseError'; +import RNFBNativeEventEmitter from '../RNFBNativeEventEmitter'; + +const NATIVE_MODULE_REGISTRY = {}; +const NATIVE_MODULE_EVENT_SUBSCRIPTIONS = {}; + +function nativeModuleKey(module) { + return `${module._customUrlOrRegion || ''}:${module.app.name}:${module.namespace}`; +} + +/** + * Wraps a native module method to provide + * auto prepended args and custom Error classes. + * + * @param namespace + * @param method + * @param argToPrepend + * @returns {Function} + */ +function nativeModuleMethodWrapped(namespace, method, argToPrepend) { + return (...args) => { + const possiblePromise = method(...[...argToPrepend, ...args]); + + if (possiblePromise && possiblePromise.then) { + const jsStack = new Error().stack; + return possiblePromise.catch(nativeError => + Promise.reject(new NativeFirebaseError(nativeError, jsStack, namespace)), + ); + } + + return possiblePromise; + }; +} + +/** + * Prepends all arguments in prependArgs to all native method calls + * + * @param namespace + * @param NativeModule + * @param argToPrepend + */ +function nativeModuleWrapped(namespace, NativeModule, argToPrepend) { + const native = {}; + const properties = Object.keys(NativeModule); + + for (let i = 0, len = properties.length; i < len; i++) { + const property = properties[i]; + if (typeof NativeModule[property] === 'function') { + native[property] = nativeModuleMethodWrapped(namespace, NativeModule[property], argToPrepend); + } else { + native[property] = NativeModule[property]; + } + } + + return native; +} + +/** + * Initialises and wraps all the native module methods. + * + * @param module + * @returns {*} + */ +function initialiseNativeModule(module) { + const config = module._config; + const key = nativeModuleKey(module); + const { + namespace, + nativeEvents, + nativeModuleName, + hasMultiAppSupport, + hasCustomUrlOrRegionSupport, + } = config; + const nativeModule = NativeModules[nativeModuleName]; + + if (!nativeModule) { + throw new Error(getMissingModuleHelpText(namespace)); + } + + const argToPrepend = []; + + if (hasMultiAppSupport) { + argToPrepend.push(module.app.name); + } + + if (hasCustomUrlOrRegionSupport) { + argToPrepend.push(module._customUrlOrRegion); + } + + NATIVE_MODULE_REGISTRY[key] = nativeModuleWrapped(namespace, nativeModule, argToPrepend); + + if (nativeEvents && nativeEvents.length) { + for (let i = 0, len = nativeEvents.length; i < len; i++) { + subscribeToNativeModuleEvent(nativeEvents[i]); + } + } + + return NATIVE_MODULE_REGISTRY[key]; +} + +/** + * Subscribe to a native event for js side distribution by appName + * React Native events are hard set at compile - cant do dynamic event names + * so we use a single event send it to js and js then internally can prefix it + * and distribute dynamically. + * + * @param eventName + * @private + */ +function subscribeToNativeModuleEvent(eventName) { + if (!NATIVE_MODULE_EVENT_SUBSCRIPTIONS[eventName]) { + RNFBNativeEventEmitter.addListener(eventName, event => { + if (event.appName) { + // native event has an appName property - auto prefix and internally emit + SharedEventEmitter.emit(`${event.appName}-${eventName}`, event); + } else { + // standard event - no need to prefix + SharedEventEmitter.emit(eventName, event); + } + }); + + NATIVE_MODULE_EVENT_SUBSCRIPTIONS[eventName] = true; + } +} + +/** + * Help text for integrating the native counter parts for each firebase module. + * + * @param namespace + * @returns {string} + */ +function getMissingModuleHelpText(namespace) { + const snippet = `firebase.${namespace}()`; + const nativeModule = namespace.charAt(0).toUpperCase() + namespace.slice(1); + + if (Platform.OS === 'ios') { + return ( + `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` + + '\r\n\r\nEnsure you have either linked the module or added it to your projects Podfile.' + + '\r\n\r\nSee http://invertase.link/ios for full setup instructions.' + ); + } + + const rnFirebasePackage = `'io.invertase.firebase.${namespace}.ReactNativeFirebase${nativeModule}Package'`; + const newInstance = `'new ReactNativeFirebase${nativeModule}Package()'`; + + return ( + `You attempted to use a firebase module that's not installed on your Android project by calling ${snippet}.` + + `\r\n\r\nEnsure you have:\r\n\r\n1) imported the ${rnFirebasePackage} module in your 'MainApplication.java' file.\r\n\r\n2) Added the ` + + `${newInstance} line inside of the RN 'getPackages()' method list.` + + '\r\n\r\nSee http://invertase.link/android for full setup instructions.' + ); +} + +/** + * Gets a wrapped native module instance for the provided firebase module. + * Will attempt to create a new instance if non previously created. + * + * @param module + * @returns {*} + */ +export function getNativeModule(module) { + const key = nativeModuleKey(module); + + if (NATIVE_MODULE_REGISTRY[key]) { + return NATIVE_MODULE_REGISTRY[key]; + } + + return initialiseNativeModule(module); +} + +/** + * Custom wrapped app module as it does not have it's own FirebaseModule based class. + * + * @returns {*} + */ +export function getAppModule() { + if (NATIVE_MODULE_REGISTRY[APP_NATIVE_MODULE]) { + return NATIVE_MODULE_REGISTRY[APP_NATIVE_MODULE]; + } + + const namespace = 'app'; + const nativeModule = NativeModules[APP_NATIVE_MODULE]; + + if (!nativeModule) { + throw new Error(getMissingModuleHelpText(namespace)); + } + + NATIVE_MODULE_REGISTRY[APP_NATIVE_MODULE] = nativeModuleWrapped(namespace, nativeModule, []); + + return NATIVE_MODULE_REGISTRY[APP_NATIVE_MODULE]; +} diff --git a/packages/app/package.json b/packages/app/package.json new file mode 100644 index 00000000..0905e77c --- /dev/null +++ b/packages/app/package.json @@ -0,0 +1,75 @@ +{ + "name": "@react-native-firebase/app", + "version": "6.0.0-alpha.1", + "author": "Invertase (http://invertase.io)", + "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Functions, Messaging (FCM), Remote Config, Storage and more.", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "build": "genversion --semi lib/version.js", + "build:clean": "rimraf android/build && rimraf ios/build", + "prepare": "npm run build" + }, + "repository": { + "type": "git", + "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/app" + }, + "license": "Apache-2.0", + "keywords": [ + "react", + "admob", + "auth", + "config", + "digits", + "fabric", + "functions", + "phone-auth", + "sms", + "firestore", + "cloud-firestore", + "datastore", + "remote-config", + "transactions", + "react-native", + "react-native-firebase", + "firebase", + "fcm", + "apn", + "gcm", + "analytics", + "messaging", + "database", + "android", + "ios", + "crash", + "firestack", + "performance", + "firestore", + "dynamic-links", + "crashlytics" + ], + "peerDependencies": { + "react": ">= 16.6.3", + "react-native": ">= 0.58.1" + }, + "dependencies": { + "@react-native-firebase/app-types": "^6.0.0-alpha.1", + "@react-native-firebase/common": "^6.0.0-alpha.1", + "opencollective-postinstall": "^2.0.1" + }, + "rnpm": { + "android": { + "buildPatch": " implementation project(':react-native-firebase')", + "packageImportPath": "import io.invertase.firebase.modules.app.ReactNativeFirebaseAppPackage;", + "packageInstance": "new ReactNativeFirebaseAppPackage()" + } + }, + "collective": { + "type": "opencollective", + "url": "https://opencollective.com/react-native-firebase" + }, + "gitHead": "5024081214e6cebd3a918274d502d56522f6b3e7", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/common/.npmignore b/packages/common/.npmignore new file mode 100644 index 00000000..d9fa30e5 --- /dev/null +++ b/packages/common/.npmignore @@ -0,0 +1,65 @@ +# Built application files +android/*/build/ + +# Crashlytics configuations +android/com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +android/local.properties + +# Gradle generated files +android/.gradle/ + +# Signing files +android/.signing/ + +# User-specific configurations +android/.idea/gradle.xml +android/.idea/libraries/ +android/.idea/workspace.xml +android/.idea/tasks.xml +android/.idea/.name +android/.idea/compiler.xml +android/.idea/copyright/profiles_settings.xml +android/.idea/encodings.xml +android/.idea/misc.xml +android/.idea/modules.xml +android/.idea/scopes/scope_settings.xml +android/.idea/vcs.xml +android/*.iml + +# Xcode +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.xcuserstate +ios/Pods +ios/build +*project.xcworkspace* +*xcuserdata* + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.dbandroid/gradle +android/gradlew +android/build +android/gradlew.bat +android/gradle/ + +.idea +coverage +yarn.lock +e2e/ +.github +.vscode +.nyc_output +android/.settings +*.coverage.json +.circleci +.eslintignore diff --git a/packages/common/LICENSE b/packages/common/LICENSE new file mode 100644 index 00000000..ef3ed44f --- /dev/null +++ b/packages/common/LICENSE @@ -0,0 +1,32 @@ +Apache-2.0 License +------------------ + +Copyright (c) 2016-present Invertase Limited & Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this library except in compliance with the License. + +You may obtain a copy of the Apache-2.0 License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Creative Commons Attribution 3.0 License +---------------------------------------- + +Copyright (c) 2016-present Invertase Limited & Contributors + +Documentation and other instructional materials provided for this project +(including on a separate documentation repository or it's documentation website) are +licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks +contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above. + +You may obtain a copy of the Creative Commons Attribution 3.0 License at + + https://creativecommons.org/licenses/by/3.0/ diff --git a/packages/common/README.md b/packages/common/README.md new file mode 100644 index 00000000..6c5513e3 --- /dev/null +++ b/packages/common/README.md @@ -0,0 +1,32 @@ +

+ +
+
+

React Native Firebase - Common

+

+ +

+ NPM downloads + NPM version + License + Backers on Open Collective + Sponsors on Open Collective + Chat + Follow on Twitter +

+ +---- + +This is not the package you're looking for. + +## License + +- See [LICENSE](/LICENSE) + +---- + +Built and maintained with 💛 by [Invertase](https://invertase.io). + +- [💼 Hire Us](https://invertase.io/hire-us) +- [☕️ Sponsor Us](https://opencollective.com/react-native-firebase) +- [👩‍💻 Work With Us](https://invertase.io/jobs) diff --git a/packages/common/lib/index.js b/packages/common/lib/index.js new file mode 100644 index 00000000..6d542568 --- /dev/null +++ b/packages/common/lib/index.js @@ -0,0 +1,15 @@ +export * from './validate'; + +export function promiseDefer() { + const deferred = { + resolve: null, + reject: null, + }; + + deferred.promise = new Promise((resolve, reject) => { + deferred.resolve = resolve; + deferred.reject = reject; + }); + + return deferred; +} diff --git a/packages/common/lib/validate.js b/packages/common/lib/validate.js new file mode 100644 index 00000000..f6e99249 --- /dev/null +++ b/packages/common/lib/validate.js @@ -0,0 +1,94 @@ +const AlphaNumericUnderscore = /^[a-zA-Z0-9_]+$/; + +/** + * Simple is null check. + * + * @param value + * @returns {boolean} + */ +export function isNull(value) { + return value === null; +} + +/** + * Simple is object check. + * + * @param value + * @returns {boolean} + */ +export function isObject(value) { + return value ? typeof value === 'object' && !Array.isArray(value) && !isNull(value) : false; +} + +/** + * Simple is function check + * + * @param value + * @returns {*|boolean} + */ +export function isFunction(value) { + return value ? typeof value === 'function' : false; +} + +/** + * Simple is string check + * @param value + * @return {boolean} + */ +export function isString(value) { + return typeof value === 'string'; +} + +/** + * Simple is boolean check + * + * @param value + * @return {boolean} + */ +export function isBoolean(value) { + return typeof value === 'boolean'; +} + +/** + * + * @param value + * @returns {arg is Array} + */ +export function isArray(value) { + return Array.isArray(value); +} + +/** + * + * @param value + * @returns {boolean} + */ +export function isUndefined(value) { + return typeof value === 'undefined'; +} + +/** + * /^[a-zA-Z0-9_]+$/ + * + * @param value + * @returns {boolean} + */ +export function isAlphaNumericUnderscore(value) { + return AlphaNumericUnderscore.test(value); +} + +/** + * Array includes + * + * @param value + * @param oneOf + * @returns {boolean} + */ +export function isOneOf(value, oneOf = []) { + if (!isArray(oneOf)) return false; + return oneOf.includes(value); +} + +export function noop() { + // noop-🐈 +} diff --git a/packages/common/package.json b/packages/common/package.json new file mode 100644 index 00000000..bd2ee523 --- /dev/null +++ b/packages/common/package.json @@ -0,0 +1,22 @@ +{ + "name": "@react-native-firebase/common", + "version": "6.0.0-alpha.1", + "author": "Invertase (http://invertase.io)", + "description": "React Native Firebase internal common utilities & helpers.", + "main": "lib/index.js", + "scripts": {}, + "repository": { + "type": "git", + "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/common" + }, + "license": "Apache-2.0", + "keywords": [ + "react", + "react-native", + "firebase" + ], + "gitHead": "5024081214e6cebd3a918274d502d56522f6b3e7", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/functions/.npmignore b/packages/functions/.npmignore new file mode 100644 index 00000000..d9fa30e5 --- /dev/null +++ b/packages/functions/.npmignore @@ -0,0 +1,65 @@ +# Built application files +android/*/build/ + +# Crashlytics configuations +android/com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +android/local.properties + +# Gradle generated files +android/.gradle/ + +# Signing files +android/.signing/ + +# User-specific configurations +android/.idea/gradle.xml +android/.idea/libraries/ +android/.idea/workspace.xml +android/.idea/tasks.xml +android/.idea/.name +android/.idea/compiler.xml +android/.idea/copyright/profiles_settings.xml +android/.idea/encodings.xml +android/.idea/misc.xml +android/.idea/modules.xml +android/.idea/scopes/scope_settings.xml +android/.idea/vcs.xml +android/*.iml + +# Xcode +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +*.xcuserstate +ios/Pods +ios/build +*project.xcworkspace* +*xcuserdata* + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.dbandroid/gradle +android/gradlew +android/build +android/gradlew.bat +android/gradle/ + +.idea +coverage +yarn.lock +e2e/ +.github +.vscode +.nyc_output +android/.settings +*.coverage.json +.circleci +.eslintignore diff --git a/packages/functions/LICENSE b/packages/functions/LICENSE new file mode 100644 index 00000000..ef3ed44f --- /dev/null +++ b/packages/functions/LICENSE @@ -0,0 +1,32 @@ +Apache-2.0 License +------------------ + +Copyright (c) 2016-present Invertase Limited & Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this library except in compliance with the License. + +You may obtain a copy of the Apache-2.0 License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Creative Commons Attribution 3.0 License +---------------------------------------- + +Copyright (c) 2016-present Invertase Limited & Contributors + +Documentation and other instructional materials provided for this project +(including on a separate documentation repository or it's documentation website) are +licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks +contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above. + +You may obtain a copy of the Creative Commons Attribution 3.0 License at + + https://creativecommons.org/licenses/by/3.0/ diff --git a/packages/functions/README.md b/packages/functions/README.md new file mode 100644 index 00000000..c8a73e1e --- /dev/null +++ b/packages/functions/README.md @@ -0,0 +1,49 @@ +

+ +
+
+

React Native Firebase - Functions

+

+ +

+ NPM downloads + NPM version + License + Backers on Open Collective + Sponsors on Open Collective + Chat + Follow on Twitter +

+ +---- + +The Cloud Functions for Firebase client SDKs let you call functions directly from a Firebase app. +To call a function from your app in this way, write and deploy an HTTPS Callable function in Cloud Functions, +and then add client logic to call the function from your app. + +[> Learn More](https://firebase.google.com/products/functions/) + +## Installation + +```bash +yarn add @react-native-firebase/functions +react-native link @react-native-firebase/functions +``` + +## Documentation + + - [Guides](#TODO) + - [Installation](#TODO) + - [Reference](#TODO) + +## License + +- See [LICENSE](/LICENSE) + +---- + +Built and maintained with 💛 by [Invertase](https://invertase.io). + +- [💼 Hire Us](https://invertase.io/hire-us) +- [☕️ Sponsor Us](https://opencollective.com/react-native-firebase) +- [👩‍💻 Work With Us](https://invertase.io/jobs) diff --git a/packages/functions/android/build.gradle b/packages/functions/android/build.gradle new file mode 100644 index 00000000..2cdcf664 --- /dev/null +++ b/packages/functions/android/build.gradle @@ -0,0 +1,66 @@ +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +plugins { + id "io.invertase.gradle.build" version "1.3" +} + +project.ext { + set('react-native', [ + versions: [ + android : [ + minSdk : 16, + targetSdk : 28, + compileSdk: 28, + // optional as gradle.buildTools comes with one by default + // overriding here though to match the version RN uses + buildTools: "28.0.3" + ], + + googlePlayServices: [ + base: "16.0.1", + ], + + firebase : [ + functions: "16.1.3" + ], + ], + ]) +} + +android { + defaultConfig { + multiDexEnabled true + } + lintOptions { + disable 'GradleCompatible' + abortOnError false + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +repositories { + google() + jcenter() +} + +dependencies { + api project(':@react-native-firebase/app') + implementation "com.google.firebase:firebase-functions:${ReactNative.ext.getVersion("firebase", "functions")}" + implementation "com.google.android.gms:play-services-base:${ReactNative.ext.getVersion("googlePlayServices", "base")}" +} + +ReactNative.shared.applyPackageVersion() +ReactNative.shared.applyDefaultExcludes() +ReactNative.module.applyAndroidVersions() +ReactNative.module.applyReactNativeDependency("api") diff --git a/packages/functions/android/gradle/wrapper/gradle-wrapper.jar b/packages/functions/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/packages/functions/android/gradle/wrapper/gradle-wrapper.properties b/packages/functions/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..5c8a6d6f --- /dev/null +++ b/packages/functions/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Oct 09 01:55:27 BST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/functions/android/gradlew b/packages/functions/android/gradlew new file mode 100644 index 00000000..9d82f789 --- /dev/null +++ b/packages/functions/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/packages/functions/android/gradlew.bat b/packages/functions/android/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/packages/functions/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/functions/android/lint.xml b/packages/functions/android/lint.xml new file mode 100644 index 00000000..c3dd72ac --- /dev/null +++ b/packages/functions/android/lint.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/functions/android/settings.gradle b/packages/functions/android/settings.gradle new file mode 100644 index 00000000..8babe47c --- /dev/null +++ b/packages/functions/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = '@react-native-firebase/functions' diff --git a/packages/functions/android/src/main/AndroidManifest.xml b/packages/functions/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..5337ced5 --- /dev/null +++ b/packages/functions/android/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctions.java b/packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsModule.java similarity index 54% rename from android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctions.java rename to packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsModule.java index 20aae5fe..06d09792 100644 --- a/android/src/main/java/io/invertase/firebase/functions/RNFirebaseFunctions.java +++ b/packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsModule.java @@ -1,11 +1,27 @@ package io.invertase.firebase.functions; +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + import android.util.Log; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; @@ -19,40 +35,20 @@ import com.google.firebase.functions.HttpsCallableResult; import javax.annotation.Nonnull; -import io.invertase.firebase.Utils; - -public class RNFirebaseFunctions extends ReactContextBaseJavaModule { +import io.invertase.firebase.common.RCTConvertFirebase; +import io.invertase.firebase.common.ReactNativeFirebaseModule; +public class ReactNativeFirebaseFunctionsModule extends ReactNativeFirebaseModule { + private static final String TAG = "Functions"; private static final String DATA_KEY = "data"; private static final String CODE_KEY = "code"; private static final String MSG_KEY = "message"; - private static final String ERROR_KEY = "__error"; private static final String DETAILS_KEY = "details"; - private static final String TAG = "RNFirebaseFunctions"; - RNFirebaseFunctions(ReactApplicationContext reactContext) { - super(reactContext); - Log.d(TAG, "New instance"); + ReactNativeFirebaseFunctionsModule(ReactApplicationContext reactContext) { + super(reactContext, TAG); } - @Override - public String getName() { - return TAG; - } - - /** - * Changes this instance to point to a Cloud Functions emulator running - * locally. - *

- * See https://firebase.google.com/docs/functions/local-emulator - * - * @param origin the origin string of the local emulator started via firebase tools - * "http://10.0.0.8:1337". - * @param appName - * @param region - * @param origin - * @param promise - */ @ReactMethod public void useFunctionsEmulator( String appName, @@ -66,26 +62,15 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule { promise.resolve(null); } - /** - * @param appName - * @param region - * @param name - * @param wrapper - * @param promise - */ @ReactMethod public void httpsCallable( String appName, String region, - final String name, + String name, ReadableMap wrapper, - final Promise promise + Promise promise ) { - Object input = wrapper - .toHashMap() - .get(DATA_KEY); - - Log.d(TAG, "function:call:input:" + name + ":" + (input != null ? input.toString() : "null")); + Object input = wrapper.toHashMap().get(DATA_KEY); FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); FirebaseFunctions functionsInstance = FirebaseFunctions.getInstance(firebaseApp, region); @@ -98,25 +83,7 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule { public void onSuccess(HttpsCallableResult httpsCallableResult) { WritableMap map = Arguments.createMap(); Object result = httpsCallableResult.getData(); - - Log.d( - TAG, - "function:call:onSuccess:" + name - ); - - Log.d( - TAG, - "function:call:onSuccess:result:type:" + name + ":" + (result != null ? result - .getClass() - .getName() : "null") - ); - - Log.d( - TAG, - "function:call:onSuccess:result:data:" + name + ":" + (result != null ? result.toString() : "null") - ); - - Utils.mapPutValue(DATA_KEY, result, map); + RCTConvertFirebase.mapPutValue(DATA_KEY, result, map); promise.resolve(map); } }) @@ -128,24 +95,23 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule { String message; Object details = null; String code = "UNKNOWN"; - WritableMap map = Arguments.createMap(); + WritableMap userInfo = Arguments.createMap(); if (exception instanceof FirebaseFunctionsException) { - FirebaseFunctionsException ffe = (FirebaseFunctionsException) exception; - details = ffe.getDetails(); - code = ffe + FirebaseFunctionsException functionsException = (FirebaseFunctionsException) exception; + details = functionsException.getDetails(); + code = functionsException .getCode() .name(); - message = ffe.getMessage(); + message = functionsException.getMessage(); } else { message = exception.getMessage(); } - Utils.mapPutValue(CODE_KEY, code, map); - Utils.mapPutValue(MSG_KEY, message, map); - Utils.mapPutValue(ERROR_KEY, true, map); - Utils.mapPutValue(DETAILS_KEY, details, map); - promise.resolve(map); + RCTConvertFirebase.mapPutValue(CODE_KEY, code, userInfo); + RCTConvertFirebase.mapPutValue(MSG_KEY, message, userInfo); + RCTConvertFirebase.mapPutValue(DETAILS_KEY, details, userInfo); + promise.reject(code, message, exception, userInfo); } }); } diff --git a/packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsPackage.java b/packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsPackage.java new file mode 100644 index 00000000..d87fba27 --- /dev/null +++ b/packages/functions/android/src/main/java/io/invertase/firebase/functions/ReactNativeFirebaseFunctionsPackage.java @@ -0,0 +1,42 @@ +package io.invertase.firebase.functions; + +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("unused") +public class ReactNativeFirebaseFunctionsPackage implements ReactPackage { + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new ReactNativeFirebaseFunctionsModule(reactContext)); + return modules; + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/packages/functions/e2e/functions.e2e.js b/packages/functions/e2e/functions.e2e.js new file mode 100644 index 00000000..b412276d --- /dev/null +++ b/packages/functions/e2e/functions.e2e.js @@ -0,0 +1,255 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const { SAMPLE_DATA } = require('@react-native-firebase/tests-firebase-functions'); + +android.describe('functions()', () => { + describe('namespace', () => { + it('accessible from firebase.app()', () => { + const app = firebase.app(); + should.exist(app.functions); + app.functions().httpsCallable.should.be.a.Function(); + }); + + xit('throws if app arg provided to firebase.functions(APP)', { + // TODO + }); + + it('accepts passing in an FirebaseApp instance as first arg', async () => { + const appName = `functionsApp${global.testRunId}1`; + const platformAppConfig = TestHelpers.core.config(); + const app = await firebase.initializeApp(platformAppConfig, appName); + + const functionsForApp = firebase.functions(app); + + functionsForApp.app.should.equal(app); + functionsForApp.app.name.should.equal(app.name); + + // check from an app + app.functions().app.should.equal(app); + app.functions().app.name.should.equal(app.name); + }); + + it('accepts passing in a region string as first arg to an app', async () => { + const region = 'europe-west1'; + const functionsForRegion = firebase.app().functions(region); + + functionsForRegion._customUrlOrRegion.should.equal(region); + functionsForRegion.app.should.equal(firebase.app()); + functionsForRegion.app.name.should.equal(firebase.app().name); + + firebase + .app() + .functions(region) + .app.should.equal(firebase.app()); + + firebase + .app() + .functions(region) + ._customUrlOrRegion.should.equal(region); + + const functionRunner = functionsForRegion.httpsCallable('testFunctionCustomRegion'); + + const response = await functionRunner(); + response.data.should.equal(region); + }); + }); + + describe('httpsCallable(fnName)(args)', () => { + it('accepts primitive args: undefined', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner(); + response.data.should.equal('null'); + }); + + it('accepts primitive args: string', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner('hello'); + response.data.should.equal('string'); + }); + + it('accepts primitive args: number', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner(123); + response.data.should.equal('number'); + }); + + it('accepts primitive args: boolean', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner(true); + response.data.should.equal('boolean'); + }); + + it('accepts primitive args: null', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner(null); + response.data.should.equal('null'); + }); + + it('accepts array args', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const response = await functionRunner([1, 2, 3, 4]); + response.data.should.equal('array'); + }); + + it('accepts object args', async () => { + const type = 'object'; + const inputData = SAMPLE_DATA[type]; + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const { data: outputData } = await functionRunner({ + type, + inputData, + }); + should.deepEqual(outputData, inputData); + }); + + it('accepts complex nested objects', async () => { + const type = 'deepObject'; + const inputData = SAMPLE_DATA[type]; + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const { data: outputData } = await functionRunner({ + type, + inputData, + }); + should.deepEqual(outputData, inputData); + }); + + it('accepts complex nested arrays', async () => { + const type = 'deepArray'; + const inputData = SAMPLE_DATA[type]; + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + const { data: outputData } = await functionRunner({ + type, + inputData, + }); + should.deepEqual(outputData, inputData); + }); + }); + + describe('HttpsError', () => { + it('errors return instance of HttpsError', async () => { + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + + try { + await functionRunner({}); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.equal(e.details, null); + e.code.should.equal('invalid-argument'); + e.message.should.equal('Invalid test requested.'); + } + + return Promise.resolve(); + }); + + it('HttpsError.details -> allows returning complex data', async () => { + let type = 'deepObject'; + let inputData = SAMPLE_DATA[type]; + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.deepEqual(e.details, inputData); + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + } + + type = 'deepArray'; + inputData = SAMPLE_DATA[type]; + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.deepEqual(e.details, inputData); + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + } + + return Promise.resolve(); + }); + + it('HttpsError.details -> allows returning primitives', async () => { + let type = 'number'; + let inputData = SAMPLE_DATA[type]; + const functionRunner = firebase.functions().httpsCallable('testFunctionDefaultRegion'); + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + should.deepEqual(e.details, inputData); + } + + type = 'string'; + inputData = SAMPLE_DATA[type]; + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.deepEqual(e.details, inputData); + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + } + + type = 'boolean'; + inputData = SAMPLE_DATA[type]; + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.deepEqual(e.details, inputData); + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + } + + type = 'null'; + inputData = SAMPLE_DATA[type]; + try { + await functionRunner({ + type, + inputData, + asError: true, + }); + return Promise.reject(new Error('Function did not reject with error.')); + } catch (e) { + should.deepEqual(e.details, inputData); + e.code.should.equal('cancelled'); + e.message.should.equal( + 'Response data was requested to be sent as part of an Error payload, so here we are!', + ); + } + + return Promise.resolve(); + }); + }); +}); diff --git a/packages/functions/ios/RNFBFunctions.podspec b/packages/functions/ios/RNFBFunctions.podspec new file mode 100644 index 00000000..fd638a07 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.podspec @@ -0,0 +1,20 @@ +require 'json' +package = JSON.parse(File.read('../package.json')) + +Pod::Spec.new do |s| + s.name = "RNFBFunctions" + s.version = package["version"] + s.description = package["description"] + s.summary = <<-DESC + A well tested feature rich Firebase implementation for React Native, supporting iOS & Android. + DESC + s.homepage = "http://invertase.io/oss/react-native-firebase" + s.license = package['license'] + s.authors = "Invertase Limited" + s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" } + s.social_media_url = 'http://twitter.com/invertaseio' + s.platform = :ios, "10.0" + s.source_files = 'RNFBFunctions/**/*.{h,m}' + s.dependency 'React' + s.dependency 'Firebase/Functions', '~> 5.15.0' +end diff --git a/packages/functions/ios/RNFBFunctions.xcodeproj/project.pbxproj b/packages/functions/ios/RNFBFunctions.xcodeproj/project.pbxproj new file mode 100644 index 00000000..c80c7e41 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 2744B98621F45429004F8E3F /* RNFBFunctionsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBFunctionsModule.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 2744B98021F45429004F8E3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 2744B98221F45429004F8E3F /* libRNFBFunctions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBFunctions.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2744B98421F45429004F8E3F /* RNFBFunctionsModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBFunctionsModule.h; path = RNFBFunctions/RNFBFunctionsModule.h; sourceTree = SOURCE_ROOT; }; + 2744B98521F45429004F8E3F /* RNFBFunctionsModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBFunctionsModule.m; path = RNFBFunctions/RNFBFunctionsModule.m; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2744B97F21F45429004F8E3F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2744B97521F452B8004F8E3F /* Products */ = { + isa = PBXGroup; + children = ( + 2744B98221F45429004F8E3F /* libRNFBFunctions.a */, + ); + name = Products; + sourceTree = ""; + }; + 2744B98321F45429004F8E3F /* RNFBFunctions */ = { + isa = PBXGroup; + children = ( + 2744B9A121F48736004F8E3F /* converters */, + 2744B98C21F45C64004F8E3F /* common */, + 2744B98421F45429004F8E3F /* RNFBFunctionsModule.h */, + 2744B98521F45429004F8E3F /* RNFBFunctionsModule.m */, + ); + path = RNFBFunctions; + sourceTree = ""; + }; + 3323F52AAFE26B7384BE4DE3 = { + isa = PBXGroup; + children = ( + 2744B98321F45429004F8E3F /* RNFBFunctions */, + 2744B97521F452B8004F8E3F /* Products */, + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2744B98121F45429004F8E3F /* RNFBFunctions */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBFunctions" */; + buildPhases = ( + 2744B97E21F45429004F8E3F /* Sources */, + 2744B97F21F45429004F8E3F /* Frameworks */, + 2744B98021F45429004F8E3F /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RNFBFunctions; + productName = RNFBFunctions; + productReference = 2744B98221F45429004F8E3F /* libRNFBFunctions.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3323F95273A95DB34F55C6D7 /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = RNFBFunctions; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Invertase; + TargetAttributes = { + 2744B98121F45429004F8E3F = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBFunctions" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 3323F52AAFE26B7384BE4DE3; + productRefGroup = 2744B97521F452B8004F8E3F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2744B98121F45429004F8E3F /* RNFBFunctions */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2744B97E21F45429004F8E3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2744B98621F45429004F8E3F /* RNFBFunctionsModule.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 2744B98921F45429004F8E3F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2744B98A21F45429004F8E3F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3323F77D701E1896E6D239CF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseFunctions/Frameworks", + "$(SRCROOT)/../../../tests/ios/Pods/FirebaseFunctions/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-firebase/ios/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**", + "$(SRCROOT)/../../../packages/app/ios/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 3323F7E33E1559A2B9826720 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "${BUILT_PRODUCTS_DIR}/**", + "${SRCROOT}/../../../ios/Firebase/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "$(SRCROOT)/../../../ios/Pods/FirebaseFunctions/Frameworks", + ); + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(REACT_SEARCH_PATH)/React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-firebase/ios/**", + "$(FIREBASE_SEARCH_PATH)/Firebase/**", + "${SRCROOT}/../../../ios/Firebase/**", + "${SRCROOT}/../../../ios/Pods/Headers/Public/**", + "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**", + "$(SRCROOT)/../../../node_modules/react-native/React/**", + "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**", + "$(SRCROOT)/../../../packages/app/ios/**", + ); + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MACH_O_TYPE = staticlib; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBFunctions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2744B98921F45429004F8E3F /* Debug */, + 2744B98A21F45429004F8E3F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBFunctions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3323F7E33E1559A2B9826720 /* Debug */, + 3323F77D701E1896E6D239CF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3323F95273A95DB34F55C6D7 /* Project object */; +} diff --git a/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/functions/ios/RNFBFunctions.xcodeproj/xcshareddata/IDETemplateMacros.plist b/packages/functions/ios/RNFBFunctions.xcodeproj/xcshareddata/IDETemplateMacros.plist new file mode 100644 index 00000000..63f0a6e5 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1,24 @@ + + + + + FILEHEADER + +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + diff --git a/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.h b/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.h new file mode 100644 index 00000000..b608e558 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#import + +@interface RNFBFunctionsModule : NSObject + +@end diff --git a/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m b/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m new file mode 100644 index 00000000..4afef9a6 --- /dev/null +++ b/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import + +#import "RNFBFunctionsModule.h" +#import "RNFBApp/RNFBSharedUtils.h" + + +@implementation RNFBFunctionsModule +#pragma mark - +#pragma mark Module Setup + + RCT_EXPORT_MODULE(); + + - (dispatch_queue_t)methodQueue { + return dispatch_get_main_queue(); + } + +#pragma mark - +#pragma mark Firebase Functions Methods + + + +@end diff --git a/packages/functions/lib/HttpsError.js b/packages/functions/lib/HttpsError.js new file mode 100644 index 00000000..306502f6 --- /dev/null +++ b/packages/functions/lib/HttpsError.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export default class HttpsError extends Error { + constructor(code, message, details, nativeErrorInstance) { + super(message); + + Object.defineProperty(this, 'code', { + enumerable: false, + value: code, + }); + + Object.defineProperty(this, 'details', { + enumerable: false, + value: details, + }); + + Object.defineProperty(this, 'message', { + enumerable: false, + value: message, + }); + + this.stack = nativeErrorInstance.getStackWithMessage(`Error: ${this.message}`); + } +} diff --git a/packages/functions/lib/index.d.ts b/packages/functions/lib/index.d.ts new file mode 100644 index 00000000..78737297 --- /dev/null +++ b/packages/functions/lib/index.d.ts @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + ReactNativeFirebaseModule, + ReactNativeFirebaseNamespace, +} from '@react-native-firebase/app-types'; + +/** + * The Cloud Functions for Firebase client SDKs let you call functions + * directly from a Firebase app. To call a function from your app in this way, + * write and deploy an HTTPS Callable function in Cloud Functions, + * and then add client logic to call the function from your app. + * + * @firebase functions + */ +export namespace Functions { + /** + * The set of Firebase Functions status codes. The codes are the same at the + * ones exposed by gRPC here: + * https://github.com/grpc/grpc/blob/master/doc/statuscodes.md + * + * Possible values: + * - 'cancelled': The operation was cancelled (typically by the caller). + * - 'unknown': Unknown error or an error from a different error domain. + * - 'invalid-argument': Client specified an invalid argument. Note that this + * differs from 'failed-precondition'. 'invalid-argument' indicates + * arguments that are problematic regardless of the state of the system + * (e.g. an invalid field name). + * - 'deadline-exceeded': Deadline expired before operation could complete. + * For operations that change the state of the system, this error may be + * returned even if the operation has completed successfully. For example, + * a successful response from a server could have been delayed long enough + * for the deadline to expire. + * - 'not-found': Some requested document was not found. + * - 'already-exists': Some document that we attempted to create already + * exists. + * - 'permission-denied': The caller does not have permission to execute the + * specified operation. + * - 'resource-exhausted': Some resource has been exhausted, perhaps a + * per-user quota, or perhaps the entire file system is out of space. + * - 'failed-precondition': Operation was rejected because the system is not + * in a state required for the operation's execution. + * - 'aborted': The operation was aborted, typically due to a concurrency + * issue like transaction aborts, etc. + * - 'out-of-range': Operation was attempted past the valid range. + * - 'unimplemented': Operation is not implemented or not supported/enabled. + * - 'internal': Internal errors. Means some invariants expected by + * underlying system has been broken. If you see one of these errors, + * something is very broken. + * - 'unavailable': The service is currently unavailable. This is most likely + * a transient condition and may be corrected by retrying with a backoff. + * - 'data-loss': Unrecoverable data loss or corruption. + * - 'unauthenticated': The request does not have valid authentication + * credentials for the operation. + */ + export type FunctionsErrorCode = + | 'ok' + | 'cancelled' + | 'unknown' + | 'invalid-argument' + | 'deadline-exceeded' + | 'not-found' + | 'already-exists' + | 'permission-denied' + | 'resource-exhausted' + | 'failed-precondition' + | 'aborted' + | 'out-of-range' + | 'unimplemented' + | 'internal' + | 'unavailable' + | 'data-loss' + | 'unauthenticated'; + + /** + * An HttpsCallableResult wraps a single result from a function call. + */ + export interface HttpsCallableResult { + readonly data: any; + } + + /** + * An HttpsCallable is a reference to a "callable" http trigger in + * Google Cloud Functions. + */ + export interface HttpsCallable { + (data?: any): Promise; + } + + export interface HttpsError extends Error { + /** + * A standard error code that will be returned to the client. This also + * determines the HTTP status code of the response, as defined in code.proto. + */ + readonly code: FunctionsErrorCode; + /** + * Extra data to be converted to JSON and included in the error response. + */ + readonly details?: any; + } + + export interface HttpsErrorCode { + OK: 'ok'; + CANCELLED: 'cancelled'; + UNKNOWN: 'unknown'; + INVALID_ARGUMENT: 'invalid-argument'; + DEADLINE_EXCEEDED: 'deadline-exceeded'; + NOT_FOUND: 'not-found'; + ALREADY_EXISTS: 'already-exists'; + PERMISSION_DENIED: 'permission-denied'; + UNAUTHENTICATED: 'unauthenticated'; + RESOURCE_EXHAUSTED: 'resource-exhausted'; + FAILED_PRECONDITION: 'failed-precondition'; + ABORTED: 'aborted'; + OUT_OF_RANGE: 'out-of-range'; + UNIMPLEMENTED: 'unimplemented'; + INTERNAL: 'internal'; + UNAVAILABLE: 'unavailable'; + DATA_LOSS: 'data-loss'; + } + + /** + * firebase.functions.X + */ + export interface Statics { + /** + * Uppercase + underscored variables of @Functions.FunctionsErrorCode + */ + HttpsErrorCode: {} & HttpsErrorCode, + } + + /** + * firebase.functions().X + */ + export interface Module extends ReactNativeFirebaseModule { + /** + * Gets an `HttpsCallable` instance that refers to the function with the given + * name. + * + * @param name The name of the https callable function. + * @return The `HttpsCallable` instance. + */ + httpsCallable(name: string): HttpsCallable; + + /** + * Changes this instance to point to a Cloud Functions emulator running + * locally. + * + * See https://firebase.google.com/docs/functions/local-emulator + * + * @param origin the origin string of the local emulator started via firebase tools + * "http://10.0.0.8:1337". + */ + useFunctionsEmulator(origin: string): Promise; + } +} + +declare module '@react-native-firebase/functions' { + import { FirebaseApp, ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types'; + + // export statics + export const HttpsErrorCode: {} & Functions.HttpsErrorCode; + + /** + * @example + * ```js + * import { firebase } from '@react-native-firebase/functions'; + * firebase.functions().httpsCallable(...); + * ``` + */ + export const firebase: {} & ReactNativeFirebaseNamespace; + + const FunctionsDefaultExport: { + (app?: FirebaseApp): Functions.Module; + /** + * This React Native Firebase Functions module version. + */ + readonly SDK_VERSION: string; + } & Functions.Statics; + /** + * @example + * ```js + * import functions from '@react-native-firebase/functions'; + * functions().httpsCallable(...); + * ``` + */ + export default FunctionsDefaultExport; +} + +/** + * Attach namespace to `firebase.` and `FirebaseApp.`. + */ +declare module '@react-native-firebase/app-types' { + interface ReactNativeFirebaseNamespace { + /** + * The Cloud Functions for Firebase client SDKs let you call functions + * directly from a Firebase app. To call a function from your app in this way, + * write and deploy an HTTPS Callable function in Cloud Functions, + * and then add client logic to call the function from your app. + */ + functions: { + (app?: FirebaseApp): Functions.Module; + /** + * This React Native Firebase Functions module version. + */ + readonly SDK_VERSION: string; + } & Functions.Statics; + } + + interface FirebaseApp { + /** + * The Cloud Functions for Firebase client SDKs let you call functions + * directly from a Firebase app. To call a function from your app in this way, + * write and deploy an HTTPS Callable function in Cloud Functions, + * and then add client logic to call the function from your app. + */ + functions?(region?: string): Functions.Module; + } +} diff --git a/packages/functions/lib/index.js b/packages/functions/lib/index.js new file mode 100644 index 00000000..8387629c --- /dev/null +++ b/packages/functions/lib/index.js @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + createModuleNamespace, + FirebaseModule, + getFirebaseRoot, +} from '@react-native-firebase/app/lib/internal'; + +// import { +// isNull, +// isObject, +// isUndefined, +// isString, +// isOneOf, +// isAlphaNumericUnderscore, +// } from '@react-native-firebase/common'; + +import version from './version'; +import HttpsError from './HttpsError'; + +const namespace = 'functions'; +const nativeModuleName = 'RNFBFunctionsModule'; + +// import { HttpsErrorCode } from '@react-native-firebase/functions'; +export const HttpsErrorCode = { + OK: 'ok', + CANCELLED: 'cancelled', + UNKNOWN: 'unknown', + INVALID_ARGUMENT: 'invalid-argument', + DEADLINE_EXCEEDED: 'deadline-exceeded', + NOT_FOUND: 'not-found', + ALREADY_EXISTS: 'already-exists', + PERMISSION_DENIED: 'permission-denied', + UNAUTHENTICATED: 'unauthenticated', + RESOURCE_EXHAUSTED: 'resource-exhausted', + FAILED_PRECONDITION: 'failed-precondition', + ABORTED: 'aborted', + OUT_OF_RANGE: 'out-of-range', + UNIMPLEMENTED: 'unimplemented', + INTERNAL: 'internal', + UNAVAILABLE: 'unavailable', + DATA_LOSS: 'data-loss', +}; + +const statics = { + HttpsErrorCode, +}; + +class FirebaseFunctionsModule extends FirebaseModule { + constructor(...args) { + super(...args); + this._customUrlOrRegion = this._customUrlOrRegion || 'us-central1'; + } + + httpsCallable(name) { + return data => { + const nativePromise = this.native.httpsCallable(name, { data }); + return nativePromise.catch(nativeError => { + const { code, message, details } = nativeError.userInfo || {}; + return Promise.reject( + new HttpsError( + HttpsErrorCode[code] || HttpsErrorCode.UNKNOWN, + message || nativeError.message, + details || null, + nativeError, + ), + ); + }); + }; + } + + useFunctionsEmulator(origin) { + return this.native.useFunctionsEmulator(origin); + } +} + +// import { SDK_VERSION } from '@react-native-firebase/functions'; +export const SDK_VERSION = version; + +// import functions from '@react-native-firebase/functions'; +// functions().logEvent(...); +export default createModuleNamespace({ + statics, + version, + namespace, + nativeModuleName, + nativeEvents: false, + hasMultiAppSupport: true, + hasCustomUrlOrRegionSupport: true, + ModuleClass: FirebaseFunctionsModule, +}); + +// import functions, { firebase } from '@react-native-firebase/functions'; +// functions().logEvent(...); +// firebase.functions().logEvent(...); +export const firebase = getFirebaseRoot(); diff --git a/packages/functions/lib/index.js.flow b/packages/functions/lib/index.js.flow new file mode 100644 index 00000000..81281070 --- /dev/null +++ b/packages/functions/lib/index.js.flow @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + ReactNativeFirebaseModule, +} from '@react-native-firebase/app-types/index.js.flow'; + +/** + * The set of Firebase Functions status codes. The codes are the same at the + * ones exposed by gRPC here: + * https://github.com/grpc/grpc/blob/master/doc/statuscodes.md + * + * Possible values: + * - 'cancelled': The operation was cancelled (typically by the caller). + * - 'unknown': Unknown error or an error from a different error domain. + * - 'invalid-argument': Client specified an invalid argument. Note that this + * differs from 'failed-precondition'. 'invalid-argument' indicates + * arguments that are problematic regardless of the state of the system + * (e.g. an invalid field name). + * - 'deadline-exceeded': Deadline expired before operation could complete. + * For operations that change the state of the system, this error may be + * returned even if the operation has completed successfully. For example, + * a successful response from a server could have been delayed long enough + * for the deadline to expire. + * - 'not-found': Some requested document was not found. + * - 'already-exists': Some document that we attempted to create already + * exists. + * - 'permission-denied': The caller does not have permission to execute the + * specified operation. + * - 'resource-exhausted': Some resource has been exhausted, perhaps a + * per-user quota, or perhaps the entire file system is out of space. + * - 'failed-precondition': Operation was rejected because the system is not + * in a state required for the operation's execution. + * - 'aborted': The operation was aborted, typically due to a concurrency + * issue like transaction aborts, etc. + * - 'out-of-range': Operation was attempted past the valid range. + * - 'unimplemented': Operation is not implemented or not supported/enabled. + * - 'internal': Internal errors. Means some invariants expected by + * underlying system has been broken. If you see one of these errors, + * something is very broken. + * - 'unavailable': The service is currently unavailable. This is most likely + * a transient condition and may be corrected by retrying with a backoff. + * - 'data-loss': Unrecoverable data loss or corruption. + * - 'unauthenticated': The request does not have valid authentication + * credentials for the operation. + */ +export type FunctionsErrorCode = + | 'ok' + | 'cancelled' + | 'unknown' + | 'invalid-argument' + | 'deadline-exceeded' + | 'not-found' + | 'already-exists' + | 'permission-denied' + | 'resource-exhausted' + | 'failed-precondition' + | 'aborted' + | 'out-of-range' + | 'unimplemented' + | 'internal' + | 'unavailable' + | 'data-loss' + | 'unauthenticated'; + +/** + * An HttpsCallableResult wraps a single result from a function call. + */ +export interface HttpsCallableResult { + data: any; +} + +/** + * An HttpsCallable is a reference to a "callable" http trigger in + * Google Cloud Functions. + */ +export interface HttpsCallable { + (data?: any): Promise; +} + +export interface HttpsError extends Error { + /** + * A standard error code that will be returned to the client. This also + * determines the HTTP status code of the response, as defined in code.proto. + */ + code: FunctionsErrorCode; + /** + * Extra data to be converted to JSON and included in the error response. + */ + details?: any; +} + +interface HttpsErrorCode { + OK: 'ok'; + CANCELLED: 'cancelled'; + UNKNOWN: 'unknown'; + INVALID_ARGUMENT: 'invalid-argument'; + DEADLINE_EXCEEDED: 'deadline-exceeded'; + NOT_FOUND: 'not-found'; + ALREADY_EXISTS: 'already-exists'; + PERMISSION_DENIED: 'permission-denied'; + UNAUTHENTICATED: 'unauthenticated'; + RESOURCE_EXHAUSTED: 'resource-exhausted'; + FAILED_PRECONDITION: 'failed-precondition'; + ABORTED: 'aborted'; + OUT_OF_RANGE: 'out-of-range'; + UNIMPLEMENTED: 'unimplemented'; + INTERNAL: 'internal'; + UNAVAILABLE: 'unavailable'; + DATA_LOSS: 'data-loss'; +} + +/** + * firebase.functions.X + */ +export interface Statics { + /** + * Uppercase + underscored variables of @Functions.FunctionsErrorCode + */ + HttpsErrorCode: {} & HttpsErrorCode; +} + +/** + * firebase.functions().X + */ +interface Module extends ReactNativeFirebaseModule { + /** + * Gets an `HttpsCallable` instance that refers to the function with the given + * name. + * + * @param name The name of the https callable function. + * @return The `HttpsCallable` instance. + */ + httpsCallable(name: string): HttpsCallable; + + /** + * Changes this instance to point to a Cloud Functions emulator running + * locally. + * + * See https://firebase.google.com/docs/functions/local-emulator + * + * @param origin the origin string of the local emulator started via firebase tools + * "http://10.0.0.8:1337". + */ + useFunctionsEmulator(origin: string): Promise; +} + +declare module '@react-native-firebase/functions' { + import type { FirebaseApp, ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types'; + + declare export var HttpsErrorCode: {} & HttpsErrorCode; + + /** + * @example + * ```js + * import { firebase } from '@react-native-firebase/functions'; + * firebase.functions().httpsCallable(...); + * ``` + */ + declare export var firebase: {} & ReactNativeFirebaseNamespace; + + declare var FunctionsDefaultExport: { + (app?: FirebaseApp): Module, + /** + * This React Native Firebase Functions module version. + */ + SDK_VERSION: string, + } & Statics; + /** + * @example + * ```js + * import functions from '@react-native-firebase/functions'; + * functions().httpsCallable(...); + * ``` + */ + declare export default FunctionsDefaultExport; +} + +/** + * Attach namespace to `firebase.` and `FirebaseApp.`. + */ +declare module '@react-native-firebase/app-types' { + declare interface ReactNativeFirebaseNamespace { + /** + * The Cloud Functions for Firebase client SDKs let you call functions + * directly from a Firebase app. To call a function from your app in this way, + * write and deploy an HTTPS Callable function in Cloud Functions, + * and then add client logic to call the function from your app. + */ + functions: { + (app?: FirebaseApp): Module, + /** + * This React Native Firebase Functions module version. + */ + SDK_VERSION: string, + } & Statics; + } + + declare interface FirebaseApp { + /** + * The Cloud Functions for Firebase client SDKs let you call functions + * directly from a Firebase app. To call a function from your app in this way, + * write and deploy an HTTPS Callable function in Cloud Functions, + * and then add client logic to call the function from your app. + */ + functions(region?: string): Module; + } +} diff --git a/packages/functions/package.json b/packages/functions/package.json new file mode 100644 index 00000000..6ecb3eea --- /dev/null +++ b/packages/functions/package.json @@ -0,0 +1,45 @@ +{ + "name": "@react-native-firebase/functions", + "version": "6.0.0-alpha.1", + "author": "Invertase (http://invertase.io)", + "description": "React Native Firebase - Functions", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "build": "genversion --semi lib/version.js", + "build:clean": "rimraf android/build && rimraf ios/build", + "prepare": "yarn run build" + }, + "repository": { + "type": "git", + "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/functions" + }, + "license": "Apache-2.0", + "keywords": [ + "react", + "react-native", + "firebase", + "functions" + ], + "peerDependencies": { + "@react-native-firebase/app": "0.0.5-alpha.0" + }, + "dependencies": { + "@react-native-firebase/app-types": "^6.0.0-alpha.1", + "@react-native-firebase/common": "^6.0.0-alpha.1" + }, + "devDependencies": { + "@react-native-firebase/tests-firebase-functions": "^0.0.5" + }, + "rnpm": { + "android": { + "buildPatch": "implementation project(':@react-native-firebase_functions')", + "packageImportPath": "import io.invertase.firebase.functions.ReactNativeFirebaseFunctionsPackage;", + "packageInstance": "new ReactNativeFirebaseFunctionsPackage()" + } + }, + "gitHead": "5024081214e6cebd3a918274d502d56522f6b3e7", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/hooks/.gitkeep b/packages/hooks/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/scripts/docs-parse-typedoc.js b/scripts/docs-parse-typedoc.js new file mode 100644 index 00000000..7996fcb0 --- /dev/null +++ b/scripts/docs-parse-typedoc.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const typedocRawFile = process.argv[2]; + +console.log('------------------- EDIT ME ------------------------'); +console.log('path to raw typedoc json ->', typedocRawFile); +console.log('version ->', /(v[0-9]{1,2}\.x\.x)/.exec(typedocRawFile)[0]); +console.log('---------- scripts/docs-parse-typedoc.js ------------'); diff --git a/scripts/docs-version-name.js b/scripts/docs-version-name.js new file mode 100644 index 00000000..175e3750 --- /dev/null +++ b/scripts/docs-version-name.js @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const { version } = require('./../lerna.json'); + +// eslint-disable-next-line no-console +console.log(`v${version.substr(0, version.indexOf('.'))}.x.x`); diff --git a/src/common/NativeError.js b/src/common/NativeError.js deleted file mode 100644 index f973543c..00000000 --- a/src/common/NativeError.js +++ /dev/null @@ -1,14 +0,0 @@ -import type { - NativeErrorObject, - NativeErrorInterface, -} from './commonTypes.flow'; - -export default class NativeError extends Error implements NativeErrorInterface { - constructor(nativeError: NativeErrorObject) { - super(nativeError.message); - this.code = nativeError.code; - this.message = nativeError.message; - this.nativeErrorCode = nativeError.nativeErrorCode; - this.nativeErrorMessage = nativeError.nativeErrorMessage; - } -} diff --git a/src/common/commonTypes.flow.js b/src/common/commonTypes.flow.js deleted file mode 100644 index 228a72db..00000000 --- a/src/common/commonTypes.flow.js +++ /dev/null @@ -1,19 +0,0 @@ -export type NativeErrorObject = { - code: string, - message: string, - nativeErrorCode: string | number, - nativeErrorMessage: string, -}; - -export type NativeErrorResponse = { - error: NativeErrorObject, - // everything else - [key: string]: ?any, -}; - -export interface NativeErrorInterface extends Error { - +code: string; - +message: string; - +nativeErrorCode: string | number; - +nativeErrorMessage: string; -} diff --git a/src/index.d.ts b/src/index.d.ts deleted file mode 100644 index f2088b2e..00000000 --- a/src/index.d.ts +++ /dev/null @@ -1,2938 +0,0 @@ -// Type definitions for React Native Firebase v5.0.0 -// Project: https://github.com/invertase/react-native-firebase -// Definitions by: React Native Firebase Contributors -// TypeScript Version: 2.1 - -declare module 'react-native-firebase' { - /** 3rd party provider Credentials */ - export type AuthCredential = { - providerId: string; - token: string; - secret: string; - }; - - type FirebaseModuleAndStatics = { - (): M; - nativeModuleExists: boolean; - } & S; - - // type AdmobModule = FirebaseModuleAndStatics; - type AnalyticsModule = FirebaseModuleAndStatics; - type AuthModule = FirebaseModuleAndStatics< - RNFirebase.auth.Auth, - RNFirebase.auth.AuthStatics - >; - type ConfigModule = FirebaseModuleAndStatics; - type CrashlyticsModule = FirebaseModuleAndStatics< - RNFirebase.crashlytics.Crashlytics - >; - type DatabaseModule = FirebaseModuleAndStatics< - RNFirebase.database.Database, - RNFirebase.database.DatabaseStatics - >; - type FirestoreModule = FirebaseModuleAndStatics< - RNFirebase.firestore.Firestore, - RNFirebase.firestore.FirestoreStatics - >; - type FunctionsModule = FirebaseModuleAndStatics< - RNFirebase.functions.Functions, - RNFirebase.functions.FunctionsStatics - >; - type IidModule = FirebaseModuleAndStatics; - // type InvitesModule = FirebaseModuleAndStatics; - type LinksModule = FirebaseModuleAndStatics< - RNFirebase.links.Links, - RNFirebase.links.LinksStatics - >; - type MessagingModule = FirebaseModuleAndStatics< - RNFirebase.messaging.Messaging, - RNFirebase.messaging.MessagingStatics - >; - type NotificationsModule = FirebaseModuleAndStatics< - RNFirebase.notifications.Notifications, - RNFirebase.notifications.NotificationsStatics - >; - type PerfModule = FirebaseModuleAndStatics; - type StorageModule = FirebaseModuleAndStatics< - RNFirebase.storage.Storage, - RNFirebase.storage.StorageStatics - >; - // type UtilsModule: FirebaseModuleAndStatics; - - // Modules commented-out do not currently have type definitions - export class Firebase { - private constructor(); - - // admob: AdmobModule; - analytics: AnalyticsModule; - auth: AuthModule; - config: ConfigModule; - crashlytics: CrashlyticsModule; - database: DatabaseModule; - firestore: FirestoreModule; - functions: FunctionsModule; - iid: IidModule; - // invites: InvitesModule; - links: LinksModule; - messaging: MessagingModule; - notifications: NotificationsModule; - perf: PerfModule; - storage: StorageModule; - - // utils: UtilsModule; - initializeApp(options: Firebase.Options, name: string): App; - - app(name?: string): App; - - readonly apps: App[]; - readonly SDK_VERSION: string; - } - - namespace Firebase { - interface Options { - apiKey: string; - appId: string; - databaseURL: string; - messagingSenderId: string; - projectId: string; - storageBucket: string; - } - } - const firebase: Firebase; - export default firebase; - // export const admob: AdmobModule; - export const analytics: AnalyticsModule; - export const auth: AuthModule; - export const config: ConfigModule; - export const crashlytics: CrashlyticsModule; - export const database: DatabaseModule; - export const firestore: FirestoreModule; - export const functions: FunctionsModule; - export const iid: IidModule; - // export const invites: InvitesModule; - export const links: LinksModule; - export const messaging: MessagingModule; - export const notifications: NotificationsModule; - export const storage: StorageModule; - - // Modules commented-out do not currently have type definitions - export class App { - private constructor(); - - // admob(): RNFirebase.admob.AdMob; - analytics(): RNFirebase.Analytics; - - auth(): RNFirebase.auth.Auth; - - config(): RNFirebase.config.Config; - - crashlytics(): RNFirebase.crashlytics.Crashlytics; - - database(): RNFirebase.database.Database; - - firestore(): RNFirebase.firestore.Firestore; - - functions(): RNFirebase.functions.Functions; - - iid(): RNFirebase.iid.InstanceId; - - // invites(): RNFirebase.invites.Invites; - links(): RNFirebase.links.Links; - - messaging(): RNFirebase.messaging.Messaging; - - notifications(): RNFirebase.notifications.Notifications; - - perf(): RNFirebase.perf.Perf; - - storage(): RNFirebase.storage.Storage; - - // utils(): RNFirebase.utils.Utils; - readonly name: string; - readonly options: Firebase.Options; - - onReady: () => Promise; - } - - export namespace RNFirebase { - type Handler = (value: T) => void; - type ErrorHandler = Handler; - - export interface RnError extends Error { - code?: string; - } - - type GoogleApiAvailabilityType = { - status: number; - isAvailable: boolean; - isUserResolvableError?: boolean; - error?: string; - }; - - /** - * pass custom options by passing an object with configuration options. - * The configuration object will be generated first by the native configuration object, if set and then will be overridden if passed in JS. - * That is, all of the following key/value pairs are optional if the native configuration is set. - */ - interface configurationOptions { - /** - * default false - * When set to true, RNFirebase will log messages to the console and fire debug events we can listen to in js - * @usage - * firebase.on('debug', msg => console.log('Received debug message', msg)) - */ - debug?: boolean; - /** - * default false - * When set to true, database persistence will be enabled. - */ - persistence?: boolean; - /** - * Default from app [NSBundle mainBundle] The bundle ID for the app to be bundled with - */ - bundleID?: string; - /** - * default "" - * The Google App ID that is used to uniquely identify an instance of an app. - */ - googleAppID?: string; - /** - * default "" - * The database root (i.e. https://my-app.firebaseio.com) - */ - databaseURL?: string; - /** - * default "" - * URL scheme to set up durable deep link service - */ - deepLinkURLScheme?: string; - /** - * default "" - * The Google Cloud storage bucket name - */ - storageBucket?: string; - /** - * default "" - * The Android client ID used in Google AppInvite when an iOS app has it's android version - */ - androidClientID?: string; - /** - * default "" - * The Project number from the Google Developer's console used to configure Google Cloud Messaging - */ - GCMSenderID?: string; - /** - * default "" - * The tracking ID for Google Analytics - */ - trackingID?: string; - /** - * default "" - * The OAuth2 client ID for iOS application used to authenticate Google Users for signing in with Google - */ - clientID?: string; - /** - * default "" - * The secret iOS API key used for authenticating requests from our app - */ - APIKey?: string; - } - - namespace storage { - interface StorageStatics { - TaskState: TaskState; - TaskEvent: TaskState; - Native?: { - MAIN_BUNDLE_PATH: string; - CACHES_DIRECTORY_PATH: string; - DOCUMENT_DIRECTORY_PATH: string; - EXTERNAL_DIRECTORY_PATH: string; - EXTERNAL_STORAGE_DIRECTORY_PATH: string; - TEMP_DIRECTORY_PATH: string; - LIBRARY_DIRECTORY_PATH: string; - FILETYPE_REGULAR: string; - FILETYPE_DIRECTORY: string; - }; - } - - /** - * The Firebase Storage service interface. - * - * An instance can be accessed using `firebase.storage()`. - */ - class Storage { - /** - * The app associated with the Storage service instance. - */ - app: App; - - /** - * Returns a reference for the given path in the default bucket. - * - * @param path A relative path to initialize the reference with, for - * example path/to/image.jpg. If not passed, the returned - * reference points to the bucket root. - */ - ref(path?: string): Reference; - - /** - * Returns a reference for the given absolute URL. - * - * @param url URL must be in the form of either - * - a Cloud Storage URL, for example gs://bucket/files/image.png; or - * - download URL taken from object metadata. - */ - refFromURL(url: string): Reference; - - /** - * @param time The new maximum operation retry time in milliseconds. - */ - setMaxOperationRetryTime(time: number): void; - - /** - * @param time The new maximum upload retry time in milliseconds. - */ - setMaxUploadRetryTime(time: number): void; - - /** - * @param time The new maximum download retry time in milliseconds. - */ - setMaxDownloadRetryTime(time: number): void; - } - - /** - * A reference represents a reference to a Google Cloud Storage object. - * - * You can upload, download, and delete objects, as well as get/set object - * metadata for a file via this reference. - */ - interface Reference { - fullPath: string; - - toString(): string; - - /** - * Returns a reference to a relative path from this reference. - * - * @param path The relative path - */ - child(path: string): Reference; - - /** - * Deletes the object at this reference's location. - */ - delete(): Promise; - - /** - * Fetches a long lived download URL for this object. - */ - getDownloadURL(): Promise; - - /** - * Fetches metadata for the object at this location, if one exists. - * - * @returns A promise that is resolved with the metadata; or rejected on - * failure, including if the object does not exist. - */ - getMetadata(): Promise; - - /** - * Updates the metadata for the object at this location, if one exists. - * - * @param metadata - */ - updateMetadata(metadata: SettableMetadata): Promise; - - /** - * Downloads the storage object for this reference to the device file - * path specified. - * - * @param filePath The destination path of the downloaded file. - */ - downloadFile(filePath: string): StorageTask; - - /** - * Uploads the file path specified from the device into a storage object - * for this reference. - * - * @param filePath The path to the file on the device. It must be a full - * file path. - * @param metadata The metadata to associate with this file. - */ - putFile( - filePath: string, - metadata?: SettableMetadata - ): StorageTask; - } - - interface FullMetadata extends SettableMetadata { - bucket: string; - fullPath: string; - generation: string; - metageneration: string; - name: string; - size: number; - timeCreated: string; - updated: string; - md5Hash?: string | null; - } - - interface SettableMetadata { - cacheControl?: string | null; - contentDisposition?: string | null; - contentEncoding?: string | null; - contentLanguage?: string | null; - contentType?: string | null; - customMetadata?: Partial>; - } - - interface StorageTask extends Promise { - on( - event: TaskEvent, - next: Handler, - error?: ErrorHandler, - complete?: Handler - ): () => void; - - on( - event: TaskEvent, - observer: { - next?: Handler; - error?: ErrorHandler; - complete?: Handler; - } - ): () => void; - - /** - * Not supported by react-native-firebase - */ - pause(): void; - - /** - * Not supported by react-native-firebase - */ - resume(): void; - - /** - * Not supported by react-native-firebase - */ - cancel(): void; - } - - interface UploadTaskSnapshot { - bytesTransferred: number; - downloadURL: string | null; - metadata: FullMetadata; - ref: Reference; - state: TaskState; - task: StorageTask; - totalBytes: number; - } - - interface DownloadTaskSnapshot { - bytesTransferred: number; - ref: Reference; - state: TaskState; - totalBytes: number; - } - - enum TaskEvent { - STATE_CHANGED = 'state_changed', - } - - enum TaskState { - CANCELLED = 'cancelled', - ERROR = 'error', - PAUSED = 'paused', - RUNNING = 'running', - SUCCESS = 'success', - } - } - - namespace database { - interface Database { - /** - * Returns a new firebase reference instance - * */ - ref(path?: string): RnReference; - - /** - * register listener - */ - on( - path: string, - modifiersString: string, - modifiers: Array, - eventName: string, - cb: () => void, - errorCb: () => void - ): any; - - /** - * unregister listener - */ - off( - path: string, - modifiersString: string, - eventName?: string, - origCB?: () => void - ): any; - - /** - * Removes all event handlers and their native subscriptions - */ - cleanup(): Promise; - - /** - * connect to firebase backend - */ - goOnline(): void; - - /** - * disconnect to firebase backend - */ - goOffline(): void; - - [key: string]: any; - } - - interface RnReference extends Reference { - keepSynced(bool: boolean): any; - - filter(name: string, value: any, key?: string): any; - - [key: string]: any; - } - - type QueryEventType = - | 'value' - | 'child_added' - | 'child_removed' - | 'child_changed' - | 'child_moved'; - type QuerySuccessCallback = ( - snapshot: DataSnapshot, - previousChildId?: string | null - ) => void; - type QueryErrorCallback = (e: Error) => void; - - interface Query { - endAt( - value: number | string | boolean | null, - key?: string - ): database.Query; - - equalTo( - value: number | string | boolean | null, - key?: string - ): database.Query; - - isEqual(other: database.Query | null): boolean; - - limitToFirst(limit: number): database.Query; - - limitToLast(limit: number): database.Query; - - off( - eventType?: QueryEventType, - callback?: QuerySuccessCallback, - context?: Object - ): void; - - on( - eventType: QueryEventType, - callback: QuerySuccessCallback, - cancelCallbackOrContext?: QueryErrorCallback, - context?: Object - ): ( - a: database.DataSnapshot | null, - b?: string - ) => QuerySuccessCallback; - - once( - eventType: QueryEventType, - successCallback?: QuerySuccessCallback, - failureCallbackOrContext?: QueryErrorCallback, - context?: Object - ): Promise; - - orderByChild(path: string): database.Query; - - orderByKey(): database.Query; - - orderByPriority(): database.Query; - - orderByValue(): database.Query; - - ref: database.Reference; - - startAt( - value: number | string | boolean | null, - key?: string - ): database.Query; - - toJSON(): Object; - - toString(): string; - } - - interface DataSnapshot { - child(path: string): database.DataSnapshot; - - exists(): boolean; - - exportVal(): { - '.value': any; - '.priority': string | number | null; - }; - - forEach(action: (a: database.DataSnapshot) => boolean): boolean; - - getPriority(): string | number | null; - - hasChild(path: string): boolean; - - hasChildren(): boolean; - - key: string | null; - - numChildren(): number; - - ref: database.Reference; - - toJSON(): Object | null; - - val(): any; - } - - interface ThenableReference extends Promise {} - - interface ThenableReference extends Reference {} - - interface Reference extends database.Query { - child(path: string): database.Reference; - - key: string | null; - - onDisconnect(): any; - - parent: database.Reference | null; - - push( - value?: any, - onComplete?: (a: RnError | null) => any - ): ThenableReference; - - remove(onComplete?: (a: RnError | null) => any): Promise; - - root: database.Reference; - - set(value: any, onComplete?: (a: RnError | null) => any): Promise; - - setPriority( - priority: string | number | null, - onComplete: (a: RnError | null) => any - ): Promise; - - setWithPriority( - newVal: any, - newPriority: string | number | null, - onComplete?: (a: RnError | null) => any - ): Promise; - - transaction( - transactionUpdate: (a: any) => any, - onComplete?: ( - a: RnError | null, - b: boolean, - c: database.DataSnapshot | null - ) => any, - applyLocally?: boolean - ): Promise; - - update( - values: Object, - onComplete?: (a: RnError | null) => any - ): Promise; - } - - interface DatabaseStatics { - /** @see https://www.firebase.com/docs/java-api/javadoc/com/firebase/client/ServerValue.html#TIMESTAMP */ - ServerValue: { - TIMESTAMP: { - [key: string]: string; - }; - }; - } - } - - /** - * firebase Analytics - */ - interface Analytics { - /**Log a custom event with optional params. */ - logEvent(event: string, params?: Object): void; - - /** Sets whether analytics collection is enabled for this app on this device. */ - setAnalyticsCollectionEnabled(enabled: boolean): void; - - /** - * Sets the current screen name, which specifies the current visual context in your app. - * Whilst screenClassOverride is optional, - * it is recommended it is always sent as your current class name, - * for example on Android it will always show as 'MainActivity' if not specified. - */ - setCurrentScreen( - screenName: string | null, - screenClassOverride?: string - ): void; - - /** - * Sets the minimum engagement time required before starting a session. - * The default value is 10000 (10 seconds) - */ - setMinimumSessionDuration(milliseconds: number): void; - - /** - * Sets the duration of inactivity that terminates the current session. - * The default value is 1800000 (30 minutes). - */ - setSessionTimeoutDuration(milliseconds: number): void; - - /** - * Gives a user a unique identification. - * @example - * const id = firebase.auth().currentUser.uid; - * - * firebase.analytics().setUserId(id); - */ - setUserId(id: string | null): void; - - /** - * Sets a key/value pair of data on the current user. - */ - setUserProperty(name: string, value: string | null): void; - - /** - * Sets multiple user properties to the supplied values. - */ - setUserProperties(fieldMapping: { [key: string]: string | null }): void; - - [key: string]: any; - } - - type AdditionalUserInfo = { - isNewUser: boolean; - profile?: Object; - providerId: string; - username?: string; - }; - - type UserCredential = { - additionalUserInfo?: AdditionalUserInfo; - user: User; - }; - - type UserInfo = { - displayName?: string; - email?: string; - phoneNumber?: string; - photoURL?: string; - providerId: string; - uid: string; - }; - - type UpdateProfile = { - displayName?: string; - photoURL?: string; - }; - - type UserMetadata = { - creationTime?: string; - lastSignInTime?: string; - }; - - type IdTokenResult = { - token: string; - authTime: string; - issuedAtTime: string; - expirationTime: string; - signInProvider: null | string; - claims: { - [key: string]: any; - }; - }; - - interface User { - /** - * The user's display name (if available). - */ - displayName: string | null; - /** - * - The user's email address (if available). - */ - email: string | null; - /** - * - True if the user's email address has been verified. - */ - emailVerified: boolean; - /** - * - */ - isAnonymous: boolean; - - metadata: UserMetadata; - - phoneNumber: string | null; - /** - * - The URL of the user's profile picture (if available). - */ - photoURL: string | null; - /** - * - Additional provider-specific information about the user. - */ - providerData: Array; - /** - * - The authentication provider ID for the current user. - * For example, 'facebook.com', or 'google.com'. - */ - providerId: string; - /** - * - The user's unique ID. - */ - uid: string; - - /** - * Delete the current user. - */ - delete(): Promise; - - /** - * Returns the users authentication token. - * - * @param forceRefresh: boolean - default to false - */ - getIdToken(forceRefresh?: boolean): Promise; - - /** - * Returns a firebase.auth.IdTokenResult object which contains the ID token JWT string and - * other helper properties for getting different data associated with the token as well as - * all the decoded payload claims. - * - * @param forceRefresh boolean Force refresh regardless of token expiration. - */ - getIdTokenResult(forceRefresh?: boolean): Promise; - - /** - * @deprecated - * @param credential - */ - linkAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise; - - /** - * Link the user with a 3rd party credential provider. - */ - linkWithCredential(credential: AuthCredential): Promise; - - /** - * @deprecated - * @param credential - */ - reauthenticateAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise; - - /** - * Re-authenticate a user with a third-party authentication provider - */ - reauthenticateWithCredential( - credential: AuthCredential - ): Promise; - - /** - * Refreshes the current user. - */ - reload(): Promise; - - /** - * Sends a verification email to a user. - * This will Promise reject is the user is anonymous. - */ - sendEmailVerification( - actionCodeSettings?: ActionCodeSettings - ): Promise; - - toJSON(): object; - - unlink(providerId: string): Promise; - - /** - * Updates the user's email address. - * See Firebase docs for more information on security & email validation. - * This will Promise reject is the user is anonymous. - */ - updateEmail(email: string): Promise; - - /** - * Important: this is a security sensitive operation that requires the user to have recently signed in. - * If this requirement isn't met, ask the user to authenticate again and then call firebase.User#reauthenticate. - * This will Promise reject is the user is anonymous. - */ - updatePassword(password: string): Promise; - - /** - * Updates the user's phone number. - * See Firebase docs for more information on security & email validation. - * This will Promise reject is the user is anonymous. - */ - updatePhoneNumber(credential: AuthCredential): Promise; - - /** - * Updates a user's profile data. - * Profile data should be an object of fields to update: - */ - updateProfile(updates: UpdateProfile): Promise; - } - - type ActionCodeSettings = { - android: { - installApp?: boolean; - minimumVersion?: string; - packageName: string; - }; - handleCodeInApp?: boolean; - iOS: { - bundleId?: string; - }; - url: string; - }; - - interface ActionCodeInfo { - data: { - email?: string; - fromEmail?: string; - }; - operation: - | 'PASSWORD_RESET' - | 'VERIFY_EMAIL' - | 'RECOVER_EMAIL' - | 'EMAIL_SIGNIN' - | 'ERROR'; - } - - interface ConfirmationResult { - confirm(verificationCode: string): Promise; - - verificationId: string | null; - } - - type PhoneAuthSnapshot = { - state: 'sent' | 'timeout' | 'verified' | 'error'; - verificationId: string; - code: string | null; - error: Error | null; - }; - - type PhoneAuthError = { - code: string | null; - verificationId: string; - message: string | null; - stack: string | null; - }; - - interface PhoneAuthListener { - on( - event: string, - observer: (snapshot: PhoneAuthSnapshot) => void, - errorCb?: (error: PhoneAuthError) => void, - successCb?: (snapshot: PhoneAuthSnapshot) => void - ): PhoneAuthListener; - - then(fn: (snapshot: PhoneAuthSnapshot) => void): Promise; - - catch(fn: (error: Error) => void): Promise; - } - - namespace auth { - type AuthResult = { - authenticated: boolean; - user: object | null; - } | null; - - type AuthProvider = { - PROVIDER_ID: string; - credential: (token: string | null, secret?: string) => AuthCredential; - }; - - type EmailAuthProvider = { - PROVIDER_ID: string; - EMAIL_LINK_SIGN_IN_METHOD: string; - EMAIL_PASSWORD_SIGN_IN_METHOD: string; - credential: (email: string, password: string) => AuthCredential; - credentialWithLink: ( - email: string, - emailLink: string - ) => AuthCredential; - }; - - interface AuthSettings { - /** - * Flag to determine whether app verification should be disabled for testing or not. - * - * @platform iOS - * @param disabled - */ - appVerificationDisabledForTesting: boolean; - - /** - * The phone number and SMS code here must have been configured in the - * Firebase Console (Authentication > Sign In Method > Phone). - * - * Calling this method a second time will overwrite the previously passed parameters. - * Only one number can be configured at a given time. - * - * @platform Android - * @param phoneNumber - * @param smsCode - * @return {*} - */ - setAutoRetrievedSmsCodeForPhoneNumber( - phoneNumber: string, - smsCode: string - ): Promise; - } - type OrNull = T | null; - type AuthListenerCallback = (user: OrNull) => void; - interface Auth { - readonly app: App; - /** - * Returns the current Firebase authentication state. - */ - authResult: OrNull; - /** - * Returns the currently signed-in user (or null). See the User class documentation for further usage. - */ - currentUser: OrNull; - - /** - * Gets/Sets the language for the app instance - */ - languageCode: OrNull; - - settings: AuthSettings; - - /** - * Listen for changes in the users auth state (logging in and out). - * This method returns a unsubscribe function to stop listening to events. - * Always ensure you unsubscribe from the listener when no longer needed to prevent updates to components no longer in use. - */ - onAuthStateChanged(listener: AuthListenerCallback): () => void; - - /** - * Listen for changes in id token. - * This method returns a unsubscribe function to stop listening to events. - * Always ensure you unsubscribe from the listener when no longer needed to prevent updates to components no longer in use. - */ - onIdTokenChanged(listener: AuthListenerCallback): () => void; - - /** - * Listen for changes in the user. - * This method returns a unsubscribe function to stop listening to events. - * Always ensure you unsubscribe from the listener when no longer needed to prevent updates to components no longer in use. - */ - onUserChanged(listener: AuthListenerCallback): () => void; - - signOut(): Promise; - - /** - * @deprecated - */ - signInAnonymouslyAndRetrieveData(): Promise; - - /** - * Sign an anonymous user. - * If the user has already signed in, that user will be returned - */ - signInAnonymously(): Promise; - - /** - * @deprecated - * @param email - * @param password - */ - createUserAndRetrieveDataWithEmailAndPassword( - email: string, - password: string - ): Promise; - - signInWithEmailLink( - email: string, - emailLink: string - ): Promise; - - isSignInWithEmailLink(emailLink: string): boolean; - - /** - * We can create a user by calling the createUserWithEmailAndPassword() function. - * The method accepts two parameters, an email and a password. - */ - createUserWithEmailAndPassword( - email: string, - password: string - ): Promise; - - /** - * @deprecated - * @param email - * @param password - */ - signInAndRetrieveDataWithEmailAndPassword( - email: string, - password: string - ): Promise; - - /** - * To sign a user in with their email and password, use the signInWithEmailAndPassword() function. - * It accepts two parameters, the user's email and password: - */ - signInWithEmailAndPassword( - email: string, - password: string - ): Promise; - - /** - * @deprecated - * @param token - */ - signInAndRetrieveDataWithCustomToken( - token: string - ): Promise; - - /** - * Sign a user in with a self-signed JWT token. - * To sign a user using a self-signed custom token, - * use the signInWithCustomToken() function. - * It accepts one parameter, the custom token: - */ - signInWithCustomToken(token: string): Promise; - - /** - * @deprecated - * @param credential - */ - signInAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise; - - /** - * Sign in the user with a 3rd party credential provider. - * credential requires the following properties: - */ - signInWithCredential( - credential: AuthCredential - ): Promise; - - /** - * Asynchronously signs in using a phone number. - */ - signInWithPhoneNumber( - phoneNumber: string, - forceResend?: boolean - ): Promise; - - /** - * Returns a PhoneAuthListener to listen to phone verification events, - * on the final completion event a PhoneAuthCredential can be generated for - * authentication purposes. - */ - verifyPhoneNumber( - phoneNumber: string, - autoVerifyTimeoutOrForceResend?: number | boolean, - forceResend?: boolean - ): PhoneAuthListener; - - /** - * Sends a password reset email to the given email address. - * Unlike the web SDK, - * the email will contain a password reset link rather than a code. - */ - sendPasswordResetEmail( - email: string, - actionCodeSettings?: ActionCodeSettings - ): Promise; - - sendSignInLinkToEmail( - email: string, - actionCodeSettings?: ActionCodeSettings - ): Promise; - - /** - * Completes the password reset process, given a confirmation code and new password. - */ - confirmPasswordReset(code: string, newPassword: string): Promise; - - /** - * Applies a verification code sent to the user by email or other out-of-band mechanism. - */ - applyActionCode(code: string): Promise; - - /** - * Checks a verification code sent to the user by email or other out-of-band mechanism. - */ - checkActionCode(code: string): Promise; - - /** - * Returns a list of authentication methods that can be used to sign in a given user (identified by its main email address). - */ - fetchSignInMethodsForEmail(email: string): Promise>; - - verifyPasswordResetCode(code: string): Promise; - - [key: string]: any; - } - - interface AuthStatics { - EmailAuthProvider: EmailAuthProvider; - PhoneAuthProvider: AuthProvider; - GoogleAuthProvider: AuthProvider; - GithubAuthProvider: AuthProvider; - OAuthProvider: AuthProvider; - TwitterAuthProvider: AuthProvider; - FacebookAuthProvider: AuthProvider; - PhoneAuthState: { - CODE_SENT: string; - AUTO_VERIFY_TIMEOUT: string; - AUTO_VERIFIED: string; - ERROR: string; - }; - } - } - - namespace messaging { - interface Messaging { - /** - * Returns firebase.messaging.IOSMessaging that gets the - * iOS specific methods and properties of messaging. - */ - ios: IOSMessaging; - - /** - * Returns the devices FCM token. - */ - getToken(): Promise; - - deleteToken(authorizedEntity?: string, scope?: string): Promise; - - /** - * On a new message, - * the payload object is passed to the listener callback. - * This method is only triggered when the app is running. - */ - onMessage(listener: (message: any) => any): () => any; - - /** - * On the event a devices FCM token is refreshed by Google, - * the new token is returned in a callback listener. - */ - onTokenRefresh(listener: (token: string) => any): () => any; - - /** - * Requests app notification permissions in an Alert dialog. - */ - requestPermission(): Promise; - - /** - * Checks if the app has notification permissions. - */ - hasPermission(): Promise; - - /** - * Send an upstream message - */ - sendMessage(remoteMessage: RemoteMessage): Promise; - - /** - * Subscribes the device to a topic. - */ - subscribeToTopic(topic: string): void; - - /** - * Unsubscribe the device from a topic. - */ - unsubscribeFromTopic(topic: string): void; - } - - class RemoteMessage { - collapseKey?: string; - data: Object; - from?: string; - messageId?: string; - messageType: string; - sentTime?: number; - to?: string; - ttl?: number; - - constructor(); - - setCollapseKey(collapseKey: string): RemoteMessage; - - setData(data: Object): RemoteMessage; - - setMessageId(messageId: string): RemoteMessage; - - setMessageType(messageType: string): RemoteMessage; - - setTo(to: string): RemoteMessage; - - setTtl(ttl: number): RemoteMessage; - } - - class IOSMessaging { - /** - * Returns the devices APNS token. - */ - getAPNSToken(): Promise; - - /** - * Register for iOS remote notifications - */ - registerForRemoteNotifications(): Promise; - } - - interface MessagingStatics { - RemoteMessage: typeof RemoteMessage; - } - } - - namespace iid { - interface InstanceId { - delete(): Promise; - - get(): Promise; - - getToken(authorizedEntity?: string, scope?: string): Promise; - - deleteToken(authorizedEntity?: string, scope?: string): Promise; - } - } - - namespace notifications { - interface AndroidNotifications { - createChannel(channel: Android.Channel): Promise; - - createChannelGroup(channelGroup: Android.ChannelGroup): Promise; - - createChannelGroups( - channelGroups: Android.ChannelGroup[] - ): Promise; - - createChannels(channels: Android.Channel[]): Promise; - - deleteChannelGroup(groupId: string): Promise; - - deleteChannel(channelId: string): Promise; - } - - type BackgroundFetchResultValue = string; - type CompletionHandler = ( - backgroundFetchResult: BackgroundFetchResultValue - ) => void; - - interface Notifications { - android: AndroidNotifications; - - /** - * Cancels all notifications - */ - cancelAllNotifications(): void; - - /** - * Cancels a notification by ID - */ - cancelNotification(notificationId: string): void; - - displayNotification(notification: Notification): Promise; - - /** - * Returns the current badge number on the app icon. - */ - getBadge(): Promise; - - getInitialNotification(): Promise; - - getScheduledNotifications(): Promise; - - onNotification( - listener: (notification: Notification) => any - ): () => any; - - onNotificationDisplayed( - listener: (notification: Notification) => any - ): () => any; - - onNotificationOpened( - listener: (notificationOpen: NotificationOpen) => any - ): () => any; - - removeAllDeliveredNotifications(): void; - - removeDeliveredNotification(notificationId: string): void; - - /** - * Schedule a local notification to be shown on the device. - */ - scheduleNotification(notification: Notification, schedule: any): any; - - /** - * Sets the badge number on the iOS app icon. - */ - setBadge(badge: number): void; - } - - class Notification { - android: AndroidNotification; - ios: IOSNotification; - body: string; - data: any; - notificationId: string; - sound?: string; - subtitle?: string; - title: string; - - constructor(); - - setBody(body: string): Notification; - - setData(data: any): Notification; - - setNotificationId(notificationId: string): Notification; - - setSound(sound: string): Notification; - - setSubtitle(subtitle: string): Notification; - - setTitle(title: string): Notification; - } - - class NotificationOpen { - action: string; - notification: Notification; - results?: any; - } - - class AndroidNotification { - actions?: Android.Action[]; - autoCancel?: boolean; - badgeIconType?: Android.BadgeIconType; - bigPicture?: any; - bigText?: any; - category?: Android.Category; - channelId?: string; - clickAction?: string; - color?: string; - colorized?: boolean; - contentInfo?: string; - defaults?: Android.Defaults[]; - group?: string; - groupAlertBehaviour?: Android.GroupAlert; - groupSummary?: boolean; - largeIcon?: string; - lights?: Android.Lights; - localOnly?: boolean; - number?: number; - ongoing?: boolean; - onlyAlertOnce?: boolean; - people?: string[]; - priority?: Android.Priority; - progress?: Android.Progress; - remoteInputHistory?: string[]; - shortcutId?: string; - showWhen?: boolean; - smallIcon?: any; - sortKey?: string; - tag?: string; - ticker?: string; - timeoutAfter?: number; - usesChronometer?: boolean; - vibrate?: number[]; - visibility?: Android.Visibility; - when?: number; - - addAction(action: Android.Action): Notification; - - addPerson(person: string): Notification; - - setAutoCancel(autoCancel: boolean): Notification; - - setBadgeIconType(badgeIconType: Android.BadgeIconType): Notification; - - setBigPicture( - picture: string, - largeIcon?: string, - contentTitle?: string, - summaryText?: string - ): Notification; - - setBigText( - text: string, - contentTitle?: string, - summaryText?: string - ): Notification; - - setCategory(category: Android.Category): Notification; - - setChannelId(channelId: string): Notification; - - setClickAction(clickAction: string): Notification; - - setColor(color: string): Notification; - - setColorized(colorized: boolean): Notification; - - setContentInfo(contentInfo: string): Notification; - - setDefaults(defaults: Android.Defaults[]): Notification; - - setGroup(group: string): Notification; - - setGroupAlertBehaviour( - groupAlertBehaviour: Android.GroupAlert - ): Notification; - - setGroupSummary(groupSummary: boolean): Notification; - - setLargeIcon(largeIcon: string): Notification; - - setLights(argb: number, onMs: number, offMs: number): Notification; - - setLocalOnly(localOnly: boolean): Notification; - - setNumber(number: number): Notification; - - setOngoing(ongoing: boolean): Notification; - - setOnlyAlertOnce(onlyAlertOnce: boolean): Notification; - - setPriority(priority: Android.Priority): Notification; - - setProgress( - max: number, - progress: number, - indeterminate: boolean - ): Notification; - - //setPublicVersion(publicVersion: Notification): Notification - setRemoteInputHistory(remoteInputHistory: string[]): Notification; - - setShortcutId(shortcutId: string): Notification; - - setShowWhen(showWhen: boolean): Notification; - - setSmallIcon(icon: string, level?: number): Notification; - - setSortKey(sortKey: string): Notification; - - setTag(tag: string): Notification; - - setTicker(ticker: string): Notification; - - setTimeoutAfter(timeoutAfter: number): Notification; - - setUsesChronometer(usesChronometer: boolean): Notification; - - setVibrate(vibrate: number[]): Notification; - - setVisibility(visibility: Android.Visibility): Notification; - - setWhen(when: number): Notification; - } - - namespace Android { - class Action { - action: string; - allowGeneratedReplies: boolean; - icon: string; - remoteInputs: RemoteInput[]; - semanticAction?: SemanticAction; - showUserInterface?: boolean; - title: string; - - constructor(action: string, icon: string, title: string); - - addRemoteInput(remoteInput: RemoteInput): Action; - - setAllowGenerateReplies(allowGeneratedReplies: boolean): Action; - - setSemanticAction(semanticAction: SemanticAction): Action; - - setShowUserInterface(showUserInterface: boolean): Action; - } - - class RemoteInput { - allowedDataTypes: any[]; - allowFreeFormInput?: boolean; - choices: string[]; - label?: string; - resultKey: string; - - constructor(resultKey: string); - - setAllowDataType(mimeType: string, allow: boolean): RemoteInput; - - setAllowFreeFormInput(allowFreeFormInput: boolean): RemoteInput; - - setChoices(choices: string[]): RemoteInput; - - setLabel(label: string): RemoteInput; - } - - class Channel { - channelId: string; - name: string; - importance: Importance; - - bypassDnd?: boolean; - description?: string; - group?: string; - lightColor?: string; - lightsEnabled?: boolean; - lockScreenVisibility?: Visibility; - showBadge?: boolean; - sound?: string; - vibrationEnabled?: boolean; - vibrationPattern?: number[]; - - constructor(channelId: string, name: string, importance: Importance); - - enableLights(lightsEnabled: boolean): Channel; - - enableVibration(vibrationEnabled: boolean): Channel; - - setBypassDnd(bypassDnd: boolean): Channel; - - setDescription(description: string): Channel; - - setGroup(groupId: string): Channel; - - setLightColor(lightColor: string): Channel; - - setLockScreenVisibility(lockScreenVisibility: Visibility): Channel; - - setShowBadge(showBadge: boolean): Channel; - - setSound(sound: string): Channel; - - setVibrationPattern(vibrationPattern: number[]): Channel; - } - - class ChannelGroup { - groupId: string; - name: string; - - constructor(groupId: string, name: string); - } - - export enum BadgeIconType { - Large = 2, - None = 0, - Small = 1, - } - - export type Category = - | 'alarm' - | 'call' - | 'email' - | 'err' - | 'event' - | 'msg' - | 'progress' - | 'promo' - | 'recommendation' - | 'reminder' - | 'service' - | 'social' - | 'status' - | 'system' - | 'transport'; - - export enum Defaults { - All = -1, - Lights = 4, - Sound = 1, - Vibrate = 2, - } - - export enum GroupAlert { - All = 0, - Children = 2, - Summary = 1, - } - - export enum Importance { - Default = 3, - High = 4, - Low = 2, - Max = 5, - Min = 1, - None = 3, - Unspecified = -1000, - } - - export enum Priority { - Default = 0, - High = 1, - Low = -1, - Max = 2, - Min = -2, - } - - export enum SemanticAction { - Archive = 5, - Call = 10, - Delete = 4, - MarkAsRead = 2, - MarkAsUnread = 3, - Mute = 6, - None = 0, - Reply = 1, - ThumbsDown = 9, - ThumbsUp = 8, - Unmute = 7, - } - - export enum Visibility { - Private = 0, - Public = 1, - Secret = -1, - } - - class Lights { - argb: number; - offMs: number; - onMs: number; - } - - class Progress { - indeterminate: boolean; - max: number; - progress: number; - } - } - - class IOSNotification { - alertAction?: string; - attachments: IOSAttachment[]; - badge?: number; - category?: string; - hasAction?: boolean; - launchImage?: string; - threadIdentifier?: string; - complete?: CompletionHandler; - - addAttachment( - identifier: string, - url: string, - options: IOSAttachmentOptions - ): Notification; - - setAlertAction(alertAction: string): Notification; - - setBadge(badge: number): Notification; - - setCategory(category: string): Notification; - - setHasAction(hasAction: boolean): Notification; - - setLaunchImage(launchImage: string): Notification; - - setThreadIdentifier(threadIdentifier: string): Notification; - } - - class IOSAttachment { - identifier: string; - options: IOSAttachmentOptions; - url: string; - } - - class IOSAttachmentOptions { - typeHint: string; - thumbnailHidden: boolean; - thumbnailClippingRect: any; - thumbnailTime: string; - } - - interface NotificationsStatics { - Android: { - Action: typeof Android.Action; - BadgeIconType: typeof Android.BadgeIconType; - Category: Android.Category; - Channel: typeof Android.Channel; - ChannelGroup: typeof Android.ChannelGroup; - Defaults: typeof Android.Defaults; - GroupAlert: typeof Android.GroupAlert; - Importance: typeof Android.Importance; - Priority: typeof Android.Priority; - RemoteInput: typeof Android.RemoteInput; - SemanticAction: typeof Android.SemanticAction; - Visibility: typeof Android.Visibility; - }; - Notification: typeof Notification; - } - } - - namespace config { - interface ConfigSnapshot { - source: string; - - val(): any; - } - - interface Object { - [key: string]: ConfigSnapshot; - } - - interface Config { - /** Enable Remote Config developer mode to allow for frequent refreshes of the cache. */ - enableDeveloperMode(): void; - - /** - * Sets default values for the app to use when accessing values. - * Any data fetched and activated will override any default values. - * Any values in the defaults but not on Firebase will be untouched. - */ - setDefaults(defaults: object): void; - - /** - * Fetches the remote config data from Firebase, defined in the dashboard. - * If duration is defined (seconds), data will be locally cached for this duration. - * - * The default duration is 43200 seconds (12 hours). - * To force a cache refresh call the method with a duration of 0. - */ - fetch(duration?: number): Promise; - - /** - * Fetches the remote config data from Firebase, defined in the dashboard. - * The default expiration duration is 43200 seconds (12 hours) - */ - activateFetched(): Promise; - - /** - * Gets a config item by key. - * Returns a snapshot containing source (default, remote or static) and val function. - */ - getValue(key: string): Promise; - - /** - * Gets multiple values by key. - * Returns a snapshot object with snapshot keys e.g. snapshots.foo.val(). - */ - getValues(array: Array): Promise>; - - /** - * Returns all keys as an array by a prefix. If no prefix is defined all keys are returned. - */ - getKeysByPrefix(prefix?: string): Promise>; - - /** - * Sets the default values from a resource: - * - Android: Id for the XML resource, which should be in your application's res/xml folder. - * - iOS: The plist file name, with no file name extension. - */ - setDefaultsFromResource(resource: string | number): void; - } - } - - namespace perf { - type HttpMethod = - | 'CONNECT' - | 'DELETE' - | 'GET' - | 'HEAD' - | 'OPTIONS' - | 'PATCH' - | 'POST' - | 'PUT' - | 'TRACE'; - - interface Perf { - /** - * Globally enable or disable performance monitoring. - */ - setPerformanceCollectionEnabled(enabled: boolean): void; - - /** - * Returns a new Trace instance. - */ - newTrace(trace: string): Trace; - - /** - * Returns a new HTTP Metric instance. - */ - newHttpMetric(url: string, httpMethod: HttpMethod): HttpMetric; - } - - interface Trace { - /** - * Return an attribute by name, or null if it does not exist. - */ - getAttribute(attribute: string): Promise; - - /** - * Return an object of key-value attributes. - */ - getAttributes(): Promise; - - /** - * Get a metric by name. Returns 0 if it does not exist. - */ - getMetric(metricName: string): Promise; - - /** - * Increment a metric by name and value. - */ - incrementMetric(metricName: string, incrementBy: number): Promise; - - /** - * Set an attribute. Returns true if it was set, false if it was not. - */ - putAttribute(attribute: string, value: string): Promise; - - /** - * Set a metric. - */ - putMetric(metricName: string, value: number): Promise; - - /** - * Remove an attribute by name. - */ - removeAttribute(attribute: string): Promise; - - /** - * Start a Trace instance. - */ - start(): Promise; - - /** - * Stop a Trace instance. - */ - stop(): Promise; - } - - interface HttpMetric { - /** - * Return an attribute by name, or null if it does not exist. - */ - getAttribute(attribute: string): Promise; - - /** - * Return an object of key-value attributes. - */ - getAttributes(): Promise; - - /** - * Set an attribute. Returns true if it was set, false if it was not. - */ - putAttribute(attribute: string, value: string): Promise; - - /** - * Remove an attribute by name. - */ - removeAttribute(attribute: string): Promise; - - /** - * Set the request HTTP response code. - */ - setHttpResponseCode(code: number): Promise; - - /** - * Set the request payload size, in bytes. - */ - setRequestPayloadSize(bytes: number): Promise; - - /** - * Set the response content type. - */ - setResponseContentType(type: string): Promise; - - /** - * Set the response payload size, in bytes. - */ - setResponsePayloadSize(bytes: number): Promise; - - /** - * Start a HttpMetric instance. - */ - start(): Promise; - - /** - * Stop a HttpMetric instance. - */ - stop(): Promise; - } - } - - namespace crashlytics { - interface Crashlytics { - /** - * Forces a crash. Useful for testing your application is set up correctly. - */ - crash(): void; - - /** - * Logs a message that will appear in any subsequent crash reports. - */ - log(message: string): void; - - /** - * Logs a non fatal exception. - */ - recordError(code: number, message: string): void; - - /** - * Set a boolean value to show alongside any subsequent crash reports. - */ - setBoolValue(key: string, value: boolean): void; - - /** - * Set a float value to show alongside any subsequent crash reports. - */ - setFloatValue(key: string, value: number): void; - - /** - * Set an integer value to show alongside any subsequent crash reports. - */ - setIntValue(key: string, value: number): void; - - /** - * Set a string value to show alongside any subsequent crash reports. - */ - setStringValue(key: string, value: string): void; - - /** - * Set the user ID to show alongside any subsequent crash reports. - */ - setUserIdentifier(userId: string): void; - - /** - * Enable Crashlytics reporting. Only avaliable when disabled automatic initialization - */ - enableCrashlyticsCollection(): void; - } - } - - namespace links { - interface Links { - /** Creates a standard dynamic link. */ - createDynamicLink(dynamicLink: DynamicLink): Promise; - - /** Creates a short dynamic link. */ - createShortDynamicLink( - dynamicLink: DynamicLink, - type: 'SHORT' | 'UNGUESSABLE' - ): Promise; - - /** - * Returns the URL that the app has been launched from. If the app was - * not launched from a URL the return value will be null. - */ - getInitialLink(): Promise; - - /** - * Subscribe to URL open events while the app is still running. - * The listener is called from URL open events whilst the app is still - * running, use getInitialLink for URLs which cause the app to open - * from a previously closed / not running state. - * Returns an unsubscribe function, call the returned function to - * unsubscribe from all future events. - */ - onLink(listener: (url: string) => void): () => void; - } - - class DynamicLink { - analytics: AnalyticsParameters; - android: AndroidParameters; - ios: IOSParameters; - itunes: ITunesParameters; - navigation: NavigationParameters; - social: SocialParameters; - - constructor(link: string, dynamicLinkDomain: string); - } - - interface AnalyticsParameters { - setCampaign(campaign: string): DynamicLink; - - setContent(content: string): DynamicLink; - - setMedium(medium: string): DynamicLink; - - setSource(source: string): DynamicLink; - - setTerm(term: string): DynamicLink; - } - - interface AndroidParameters { - setFallbackUrl(fallbackUrl: string): DynamicLink; - - setMinimumVersion(minimumVersion: number): DynamicLink; - - setPackageName(packageName: string): DynamicLink; - } - - interface IOSParameters { - setAppStoreId(appStoreId: string): DynamicLink; - - setBundleId(bundleId: string): DynamicLink; - - setCustomScheme(customScheme: string): DynamicLink; - - setFallbackUrl(fallbackUrl: string): DynamicLink; - - setIPadBundleId(iPadBundleId: string): DynamicLink; - - setIPadFallbackUrl(iPadFallbackUrl: string): DynamicLink; - - setMinimumVersion(minimumVersion: string): DynamicLink; - } - - interface ITunesParameters { - setAffiliateToken(affiliateToken: string): DynamicLink; - - setCampaignToken(campaignToken: string): DynamicLink; - - setProviderToken(providerToken: string): DynamicLink; - } - - interface NavigationParameters { - setForcedRedirectEnabled(forcedRedirectEnabled: boolean): DynamicLink; - } - - interface SocialParameters { - setDescriptionText(descriptionText: string): DynamicLink; - - setImageUrl(imageUrl: string): DynamicLink; - - setTitle(title: string): DynamicLink; - } - - interface LinksStatics { - DynamicLink: typeof DynamicLink; - } - } - - // Source: https://github.com/firebase/firebase-js-sdk/blob/master/packages/functions-types/index.d.ts - namespace functions { - type HttpsErrorCode = { [name: string]: FunctionsErrorCode }; - - /** - * The set of Firebase Functions status codes. The codes are the same at the - * ones exposed by gRPC here: - * https://github.com/grpc/grpc/blob/master/doc/statuscodes.md - * - * Possible values: - * - 'cancelled': The operation was cancelled (typically by the caller). - * - 'unknown': Unknown error or an error from a different error domain. - * - 'invalid-argument': Client specified an invalid argument. Note that this - * differs from 'failed-precondition'. 'invalid-argument' indicates - * arguments that are problematic regardless of the state of the system - * (e.g. an invalid field name). - * - 'deadline-exceeded': Deadline expired before operation could complete. - * For operations that change the state of the system, this error may be - * returned even if the operation has completed successfully. For example, - * a successful response from a server could have been delayed long enough - * for the deadline to expire. - * - 'not-found': Some requested document was not found. - * - 'already-exists': Some document that we attempted to create already - * exists. - * - 'permission-denied': The caller does not have permission to execute the - * specified operation. - * - 'resource-exhausted': Some resource has been exhausted, perhaps a - * per-user quota, or perhaps the entire file system is out of space. - * - 'failed-precondition': Operation was rejected because the system is not - * in a state required for the operation's execution. - * - 'aborted': The operation was aborted, typically due to a concurrency - * issue like transaction aborts, etc. - * - 'out-of-range': Operation was attempted past the valid range. - * - 'unimplemented': Operation is not implemented or not supported/enabled. - * - 'internal': Internal errors. Means some invariants expected by - * underlying system has been broken. If you see one of these errors, - * something is very broken. - * - 'unavailable': The service is currently unavailable. This is most likely - * a transient condition and may be corrected by retrying with a backoff. - * - 'data-loss': Unrecoverable data loss or corruption. - * - 'unauthenticated': The request does not have valid authentication - * credentials for the operation. - */ - type FunctionsErrorCode = - | 'ok' - | 'cancelled' - | 'unknown' - | 'invalid-argument' - | 'deadline-exceeded' - | 'not-found' - | 'already-exists' - | 'permission-denied' - | 'resource-exhausted' - | 'failed-precondition' - | 'aborted' - | 'out-of-range' - | 'unimplemented' - | 'internal' - | 'unavailable' - | 'data-loss' - | 'unauthenticated'; - - /** - * An HttpsCallableResult wraps a single result from a function call. - */ - interface HttpsCallableResult { - readonly data: R; - } - - /** - * An HttpsCallable is a reference to a "callable" http trigger in - * Google Cloud Functions. - */ - type HttpsCallable = - Params extends void ? - () => Promise> : - (data: Params) => Promise> - - /** - * `FirebaseFunctions` represents a Functions app, and is the entry point for - * all Functions operations. - */ - interface Functions { - /** - * Gets an `HttpsCallable` instance that refers to the function with the given - * name. - * - * @param name The name of the https callable function. - * @return The `HttpsCallable` instance. - */ - httpsCallable(name: string): HttpsCallable; - - /** - * Changes this instance to point to a Cloud Functions emulator running - * locally. - * - * See https://firebase.google.com/docs/functions/local-emulator - * - * @param origin the origin string of the local emulator started via firebase tools - * "http://10.0.0.8:1337". - */ - useFunctionsEmulator(origin: string): Promise; - - [key: string]: any; - } - - /** - * firebase.functions.X - */ - interface FunctionsStatics { - /** - * Uppercased + underscored variables of @FunctionsErrorCode - */ - HttpsErrorCode: HttpsErrorCode; - } - - interface HttpsError extends Error { - /** - * A standard error code that will be returned to the client. This also - * determines the HTTP status code of the response, as defined in code.proto. - */ - readonly code: FunctionsErrorCode; - /** - * Extra data to be converted to JSON and included in the error response. - */ - readonly details?: any; - } - } - - namespace firestore { - interface Firestore { - readonly app: App; - - batch(): WriteBatch; - - collection(collectionPath: string): CollectionReference; - - disableNetwork(): Promise; - - doc(documentPath: string): DocumentReference; - - enableNetwork(): Promise; - - enablePersistence(enabled: boolean): Promise; - - runTransaction( - updateFunction: (transaction: Transaction) => Promise - ): Promise; - - settings(settings: Settings): Promise; - } - - interface FirestoreStatics { - Blob: typeof Blob; - FieldPath: typeof FieldPath; - FieldValue: typeof FieldValue; - GeoPoint: typeof GeoPoint; - - enableLogging(enabled: boolean): void; - - setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void; - } - - interface CollectionReference { - readonly firestore: Firestore; - readonly id: string; - readonly parent: DocumentReference; - - add(data: object): Promise; - - doc(documentPath?: string): DocumentReference; - - endAt(snapshot: DocumentSnapshot): Query; - - endAt(...varargs: any[]): Query; - - endBefore(snapshot: DocumentSnapshot): Query; - - endBefore(...varargs: any[]): Query; - - get(options?: Types.GetOptions): Promise; - - limit(limit: number): Query; - - onSnapshot( - onNext: Query.ObserverOnNext, - onError?: Query.ObserverOnError - ): () => void; - - onSnapshot(observer: Query.Observer): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - onNext: Query.ObserverOnNext, - onError?: Query.ObserverOnError - ): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - observer: Query.Observer - ): () => void; - - orderBy( - fieldPath: string | FieldPath, - directionStr?: Types.QueryDirection - ): Query; - - startAfter(snapshot: DocumentSnapshot): Query; - - startAfter(...varargs: any[]): Query; - - startAt(snapshot: DocumentSnapshot): Query; - - startAt(...varargs: any[]): Query; - - where( - fieldPath: string | FieldPath, - op: Types.QueryOperator, - value: any - ): Query; - } - - interface DocumentChange { - readonly doc: DocumentSnapshot; - readonly newIndex: number; - readonly oldIndex: number; - readonly type: 'added' | 'modified' | 'removed'; - } - - interface DocumentReference { - readonly firestore: Firestore; - readonly id: string | null; - readonly parent: CollectionReference; - readonly path: string; - - collection(collectionPath: string): CollectionReference; - - delete(): Promise; - - get(options?: Types.GetOptions): Promise; - - onSnapshot( - onNext: DocumentReference.ObserverOnNext, - onError?: DocumentReference.ObserverOnError - ): () => void; - - onSnapshot(observer: DocumentReference.Observer): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - onNext: DocumentReference.ObserverOnNext, - onError?: DocumentReference.ObserverOnError - ): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - observer: DocumentReference.Observer - ): () => void; - - set(data: object, writeOptions?: Types.SetOptions): Promise; - - update(obj: object): Promise; - - update(key1: Types.UpdateKey, val1: any): Promise; - - update( - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any - ): Promise; - - update( - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any - ): Promise; - - update( - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any - ): Promise; - - update( - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any, - key5: Types.UpdateKey, - val5: any - ): Promise; - } - - namespace DocumentReference { - type ObserverOnNext = (documentSnapshot: DocumentSnapshot) => void; - type ObserverOnError = (err: Query.SnapshotError) => void; - - interface Observer { - next: ObserverOnNext; - error?: ObserverOnError; - } - } - - interface DocumentSnapshot { - readonly exists: boolean; - readonly id: string | null; - readonly metadata: Types.SnapshotMetadata; - readonly ref: DocumentReference; - - data(): object | void; - - get(fieldPath: string | FieldPath): any | undefined; - } - - class Blob { - static fromBase64String(base64: string): Blob; - - static fromUint8Array(array: Uint8Array): Blob; - - isEqual(other: Blob): boolean; - - toBase64(): string; - - toUint8Array(): Uint8Array; - } - - class FieldPath { - static documentId(): FieldPath; - - constructor(...segments: string[]); - } - - type AnyJs = null | undefined | boolean | number | string | object; - - class FieldValue { - static delete(): FieldValue; - - static serverTimestamp(): FieldValue; - - static arrayUnion(...elements: AnyJs[]): FieldValue; - - static arrayRemove(...elements: AnyJs[]): FieldValue; - } - - class GeoPoint { - constructor(latitude: number, longitude: number); - - readonly latitude: number; - readonly longitude: number; - } - - class Path { - static fromName(name: string): Path; - - constructor(pathComponents: string[]); - - readonly id: string | null; - readonly isDocument: boolean; - readonly isCollection: boolean; - readonly relativeName: string; - - child(relativePath: string): Path; - - parent(): Path | null; - } - - type MetadataChanges = { - includeMetadataChanges: boolean; - }; - - interface Query { - readonly firestore: Firestore; - - endAt(snapshot: DocumentSnapshot): Query; - - endAt(...varargs: any[]): Query; - - endBefore(snapshot: DocumentSnapshot): Query; - - endBefore(...varargs: any[]): Query; - - get(options?: Types.GetOptions): Promise; - - limit(limit: number): Query; - - onSnapshot( - onNext: Query.ObserverOnNext, - onError?: Query.ObserverOnError - ): () => void; - - onSnapshot(observer: Query.Observer): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - onNext: Query.ObserverOnNext, - onError?: Query.ObserverOnError - ): () => void; - - onSnapshot( - metadataChanges: MetadataChanges, - observer: Query.Observer - ): () => void; - - orderBy( - fieldPath: string | FieldPath, - directionStr?: Types.QueryDirection - ): Query; - - startAfter(snapshot: DocumentSnapshot): Query; - - startAfter(...varargs: any[]): Query; - - startAt(snapshot: DocumentSnapshot): Query; - - startAt(...varargs: any[]): Query; - - where( - fieldPath: string | FieldPath, - op: Types.QueryOperator, - value: any - ): Query; - } - - namespace Query { - interface NativeFieldPath { - elements?: string[]; - string?: string; - type: 'fieldpath' | 'string'; - } - - interface FieldFilter { - fieldPath: NativeFieldPath; - operator: string; - value: any; - } - - interface FieldOrder { - direction: string; - fieldPath: NativeFieldPath; - } - - interface QueryOptions { - endAt?: any[]; - endBefore?: any[]; - limit?: number; - offset?: number; - selectFields?: string[]; - startAfter?: any[]; - startAt?: any[]; - } - - interface NativeError extends Error { - code: string; - message: string; - nativeErrorCode?: string; - nativeErrorMessage?: string; - } - - interface SnapshotError extends NativeError { - path: string; - appName: string; - } - - type ObserverOnNext = (querySnapshot: QuerySnapshot) => void; - type ObserverOnError = (err: SnapshotError) => void; - - interface Observer { - next: ObserverOnNext; - error?: ObserverOnError; - } - } - - interface QuerySnapshot { - readonly docChanges: DocumentChange[]; - readonly docs: DocumentSnapshot[]; - readonly empty: boolean; - readonly metadata: Types.SnapshotMetadata; - readonly query: Query; - readonly size: number; - - forEach(callback: (snapshot: DocumentSnapshot) => any): void; - } - - namespace QuerySnapshot { - interface NativeData { - changes: Types.NativeDocumentChange[]; - documents: Types.NativeDocumentSnapshot[]; - metadata: Types.SnapshotMetadata; - } - } - - interface Settings { - host?: string; - persistence?: boolean; - ssl?: boolean; - timestampsInSnapshots?: boolean; - } - - interface Transaction { - delete(docRef: DocumentReference): WriteBatch; - - get(documentRef: DocumentReference): Promise; - - set( - documentRef: DocumentReference, - data: Object, - options?: Types.SetOptions - ): Transaction; - - // multiple overrides for update() to allow strong-typed var_args - update(docRef: DocumentReference, obj: object): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any, - key5: Types.UpdateKey, - val5: any - ): WriteBatch; - } - - interface WriteBatch { - commit(): Promise; - - delete(docRef: DocumentReference): WriteBatch; - - set( - docRef: DocumentReference, - data: object, - options?: Types.SetOptions - ): WriteBatch; - - // multiple overrides for update() to allow strong-typed var_args - update(docRef: DocumentReference, obj: object): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any - ): WriteBatch; - - update( - docRef: DocumentReference, - key1: Types.UpdateKey, - val1: any, - key2: Types.UpdateKey, - val2: any, - key3: Types.UpdateKey, - val3: any, - key4: Types.UpdateKey, - val4: any, - key5: Types.UpdateKey, - val5: any - ): WriteBatch; - } - - namespace Types { - interface NativeDocumentChange { - document: NativeDocumentSnapshot; - newIndex: number; - oldIndex: number; - type: string; - } - - interface NativeDocumentSnapshot { - data: { - [key: string]: TypeMap; - }; - metadata: SnapshotMetadata; - path: string; - } - - interface SnapshotMetadata { - fromCache: boolean; - hasPendingWrites: boolean; - } - - type QueryDirection = 'asc' | 'ASC' | 'desc' | 'DESC'; - type QueryOperator = - | '=' - | '==' - | '>' - | '>=' - | '<' - | '<=' - | 'array-contains'; - - interface TypeMap { - type: - | 'array' - | 'boolean' - | 'date' - | 'documentid' - | 'fieldvalue' - | 'geopoint' - | 'null' - | 'number' - | 'object' - | 'reference' - | 'string'; - value: any; - } - - /** The key in update() function for DocumentReference and WriteBatch. */ - type UpdateKey = string | FieldPath; - - interface GetOptions { - source: 'default' | 'server' | 'cache'; - } - - interface SetOptions { - merge?: boolean; - } - } - } - } -} - -declare module 'react-native-firebase/storage' { - import { RNFirebase } from 'react-native-firebase'; - export type Storage = RNFirebase.storage.Storage; - export type Reference = RNFirebase.storage.Reference; - export type FullMetadata = RNFirebase.storage.FullMetadata; - export type SettableMetadata = RNFirebase.storage.SettableMetadata; - export type StorageTask = RNFirebase.storage.StorageTask; - export type UploadTaskSnapshot = RNFirebase.storage.UploadTaskSnapshot; - export type DownloadTaskSnapshot = RNFirebase.storage.DownloadTaskSnapshot; - export type TaskEvent = RNFirebase.storage.TaskEvent; - export type TaskState = RNFirebase.storage.TaskState; -} - -declare module 'react-native-firebase/database' { - import { RNFirebase } from 'react-native-firebase'; - export type Database = RNFirebase.database.Database; - export type RnReference = RNFirebase.database.RnReference; - export type QueryEventType = RNFirebase.database.QueryEventType; - export type QuerySuccessCallback = RNFirebase.database.QuerySuccessCallback; - export type QueryErrorCallback = RNFirebase.database.QueryErrorCallback; - export type Query = RNFirebase.database.Query; - export type DataSnapshot = RNFirebase.database.DataSnapshot; - export type Reference = RNFirebase.database.Reference; - export type DatabaseStatics = RNFirebase.database.DatabaseStatics; - - interface ThenableReference extends Promise {} - - interface ThenableReference extends RNFirebase.database.Reference {} -} - -declare module 'react-native-firebase/auth' { - import { RNFirebase } from 'react-native-firebase'; - export type AuthResult = RNFirebase.auth.AuthResult; - export type AuthProvider = RNFirebase.auth.AuthProvider; - export type Auth = RNFirebase.auth.Auth; - export type AuthStatics = RNFirebase.auth.AuthStatics; -} - -declare module 'react-native-firebase/messaging' { - import { RNFirebase } from 'react-native-firebase'; - export type Messaging = RNFirebase.messaging.Messaging; - export type RemoteMessage = RNFirebase.messaging.RemoteMessage; -} - -declare module 'react-native-firebase/iid' { - import { RNFirebase } from 'react-native-firebase'; - export type InstanceId = RNFirebase.iid.InstanceId; -} - -declare module 'react-native-firebase/notifications' { - import { RNFirebase } from 'react-native-firebase'; - export type AndroidNotifications = RNFirebase.notifications.AndroidNotifications; - export type Notifications = RNFirebase.notifications.Notifications; - export type Notification = RNFirebase.notifications.Notification; - export type NotificationOpen = RNFirebase.notifications.NotificationOpen; - export type AndroidNotification = RNFirebase.notifications.AndroidNotification; - export type IOSNotification = RNFirebase.notifications.IOSNotification; - export type IOSAttachment = RNFirebase.notifications.IOSAttachment; - export type IOSAttachmentOptions = RNFirebase.notifications.IOSAttachmentOptions; -} - -declare module 'react-native-firebase/config' { - import { RNFirebase } from 'react-native-firebase'; - export type ConfigSnapshot = RNFirebase.config.ConfigSnapshot; - export type Config = RNFirebase.config.Config; -} - -declare module 'react-native-firebase/crashlytics' { - import { RNFirebase } from 'react-native-firebase'; - export type Crashlytics = RNFirebase.crashlytics.Crashlytics; -} - -declare module 'react-native-firebase/links' { - import { RNFirebase } from 'react-native-firebase'; - export type Links = RNFirebase.links.Links; - export type DynamicLink = RNFirebase.links.DynamicLink; - export type AnalyticsParameters = RNFirebase.links.AnalyticsParameters; - export type AndroidParameters = RNFirebase.links.AndroidParameters; - export type IOSParameters = RNFirebase.links.IOSParameters; - export type ITunesParameters = RNFirebase.links.ITunesParameters; - export type NavigationParameters = RNFirebase.links.NavigationParameters; - export type SocialParameters = RNFirebase.links.SocialParameters; -} - -declare module 'react-native-firebase/functions' { - import { RNFirebase } from 'react-native-firebase'; - export type HttpsErrorCode = RNFirebase.functions.HttpsErrorCode; - export type FunctionsErrorCode = RNFirebase.functions.FunctionsErrorCode; - export type HttpsCallableResult = RNFirebase.functions.HttpsCallableResult; - export type Functions = RNFirebase.functions.Functions; - export type HttpsError = RNFirebase.functions.HttpsError; -} - -declare module 'react-native-firebase/firestore' { - import { RNFirebase } from 'react-native-firebase'; - export type Firestore = RNFirebase.firestore.Firestore; - export type FirestoreStatics = RNFirebase.firestore.FirestoreStatics; - export type CollectionReference = RNFirebase.firestore.CollectionReference; - export type DocumentChange = RNFirebase.firestore.DocumentChange; - export type DocumentReference = RNFirebase.firestore.DocumentReference; - export type DocumentSnapshot = RNFirebase.firestore.DocumentSnapshot; - export type FieldPath = RNFirebase.firestore.FieldPath; - export type FieldValue = RNFirebase.firestore.FieldValue; - export type GeoPoint = RNFirebase.firestore.GeoPoint; - export type Path = RNFirebase.firestore.Path; - export type Query = RNFirebase.firestore.Query; - export type SnapshotError = RNFirebase.firestore.Query.SnapshotError; - export type QuerySnapshot = RNFirebase.firestore.QuerySnapshot; - export type WriteBatch = RNFirebase.firestore.WriteBatch; -} diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 34353b24..00000000 --- a/src/index.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @flow - */ -import firebase from './modules/core/firebase'; - -export default firebase; -export * from './modules/core/firebase'; - -/* - * Export App types - */ -export type { default as App } from './modules/core/app'; - -/* - * Export Auth types - */ -export type { - ActionCodeInfo, - ActionCodeSettings, - AdditionalUserInfo, - AuthCredential, - UserCredential, - UserInfo, - UserMetadata, -} from './modules/auth/types'; -export type { - default as ConfirmationResult, -} from './modules/auth/phone/ConfirmationResult'; -export type { default as User } from './modules/auth/User'; - -/* - * Export Database types - */ -export type { default as DataSnapshot } from './modules/database/DataSnapshot'; -export type { default as OnDisconnect } from './modules/database/OnDisconnect'; -export type { default as Reference } from './modules/database/Reference'; -export type { default as DataQuery } from './modules/database/Query'; - -/* - * Export Firestore types - */ -export type { - MetadataChanges, - SetOptions, - SnapshotMetadata, -} from './modules/firestore/firestoreTypes.flow'; -export type { - default as CollectionReference, -} from './modules/firestore/CollectionReference'; -export type { - default as DocumentChange, -} from './modules/firestore/DocumentChange'; -export type { - default as DocumentReference, -} from './modules/firestore/DocumentReference'; -export type { - default as DocumentSnapshot, -} from './modules/firestore/DocumentSnapshot'; -export type { default as FieldPath } from './modules/firestore/FieldPath'; -export type { default as FieldValue } from './modules/firestore/FieldValue'; -export type { default as GeoPoint } from './modules/firestore/GeoPoint'; -export type { default as Query } from './modules/firestore/Query'; -export type { - default as QuerySnapshot, -} from './modules/firestore/QuerySnapshot'; -export type { default as WriteBatch } from './modules/firestore/WriteBatch'; - -/* - * Export Messaging types - */ -export type { - default as RemoteMessage, -} from './modules/messaging/RemoteMessage'; - -/* - * Export Notifications types - */ -export type { - default as Notification, - NotificationOpen, -} from './modules/notifications/Notification'; diff --git a/src/modules/admob/AdMobComponent.js b/src/modules/admob/AdMobComponent.js deleted file mode 100644 index b23bc586..00000000 --- a/src/modules/admob/AdMobComponent.js +++ /dev/null @@ -1,102 +0,0 @@ -import React from 'react'; -import { ViewPropTypes, requireNativeComponent } from 'react-native'; -import PropTypes from 'prop-types'; -import EventTypes, { NativeExpressEventTypes } from './EventTypes'; -import { nativeToJSError } from '../../utils'; - -import AdRequest from './AdRequest'; -import VideoOptions from './VideoOptions'; - -const adMobPropTypes = { - ...ViewPropTypes, - size: PropTypes.string.isRequired, - unitId: PropTypes.string.isRequired, - /* eslint-disable react/forbid-prop-types */ - request: PropTypes.object, - video: PropTypes.object, - /* eslint-enable react/forbid-prop-types */ -}; -Object.keys(EventTypes).forEach(eventType => { - adMobPropTypes[eventType] = PropTypes.func; -}); -Object.keys(NativeExpressEventTypes).forEach(eventType => { - adMobPropTypes[eventType] = PropTypes.func; -}); - -const nativeComponents = {}; - -function getNativeComponent(name) { - if (nativeComponents[name]) return nativeComponents[name]; - const component = requireNativeComponent(name, AdMobComponent, { - nativeOnly: { - onBannerEvent: true, - }, - }); - nativeComponents[name] = component; - return component; -} - -class AdMobComponent extends React.Component { - static propTypes = adMobPropTypes; - - static defaultProps = { - request: new AdRequest().addTestDevice().build(), - video: new VideoOptions().build(), - }; - - constructor(props) { - super(props); - this.state = { - width: 0, - height: 0, - }; - - this.nativeView = getNativeComponent(props.class); - } - - /** - * Handle a single banner event and pass to - * any props watching it - * @param nativeEvent - */ - onBannerEvent = ({ nativeEvent }) => { - const { props } = this; - if (props[nativeEvent.type]) { - if (nativeEvent.type === 'onAdFailedToLoad') { - const { code, message } = nativeEvent.payload; - props[nativeEvent.type](nativeToJSError(code, message)); - } else { - props[nativeEvent.type](nativeEvent.payload || {}); - } - } - - if (nativeEvent.type === 'onSizeChange') - this.updateSize(nativeEvent.payload); - }; - - /** - * Set the JS size of the loaded banner - * @param width - * @param height - */ - updateSize = ({ width, height }) => { - this.setState({ width, height }); - }; - - /** - * Render the native component - * @returns {XML} - */ - render() { - const { style } = this.props; - return ( - - ); - } -} - -export default AdMobComponent; diff --git a/src/modules/admob/AdRequest.js b/src/modules/admob/AdRequest.js deleted file mode 100644 index 41d2d5d6..00000000 --- a/src/modules/admob/AdRequest.js +++ /dev/null @@ -1,58 +0,0 @@ -export default class AdRequest { - constructor() { - this._props = { - keywords: [], - testDevices: [], - }; - } - - build() { - return this._props; - } - - addTestDevice(deviceId?: string) { - this._props.testDevices.push(deviceId || 'DEVICE_ID_EMULATOR'); - return this; - } - - addKeyword(keyword: string) { - this._props.keywords.push(keyword); - return this; - } - - setBirthday() { - // TODO - } - - setContentUrl(url: string) { - this._props.contentUrl = url; - return this; - } - - setGender(gender: 'male | female | unknown') { - const genders = ['male', 'female', 'unknown']; - if (genders.includes(gender)) { - this._props.gender = gender; - } - return this; - } - - setLocation() { - // TODO - } - - setRequestAgent(requestAgent: string) { - this._props.requestAgent = requestAgent; - return this; - } - - setIsDesignedForFamilies(isDesignedForFamilies: boolean) { - this._props.isDesignedForFamilies = isDesignedForFamilies; - return this; - } - - tagForChildDirectedTreatment(tagForChildDirectedTreatment: boolean) { - this._props.tagForChildDirectedTreatment = tagForChildDirectedTreatment; - return this; - } -} diff --git a/src/modules/admob/Banner.js b/src/modules/admob/Banner.js deleted file mode 100644 index 82eac4e8..00000000 --- a/src/modules/admob/Banner.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import AdMobComponent from './AdMobComponent'; - -function Banner({ ...props }) { - return ; -} - -Banner.propTypes = AdMobComponent.propTypes; - -Banner.defaultProps = { - size: 'SMART_BANNER', -}; - -export default Banner; diff --git a/src/modules/admob/EventTypes.js b/src/modules/admob/EventTypes.js deleted file mode 100644 index 510f62e3..00000000 --- a/src/modules/admob/EventTypes.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @flow - */ -export default { - onAdLoaded: 'onAdLoaded', - onAdOpened: 'onAdOpened', - onAdLeftApplication: 'onAdLeftApplication', - onAdClosed: 'onAdClosed', - onAdFailedToLoad: 'onAdFailedToLoad', -}; - -export const NativeExpressEventTypes = { - onVideoEnd: 'onVideoEnd', - onVideoMute: 'onVideoMute', - onVideoPause: 'onVideoPause', - onVideoPlay: 'onVideoPlay', - onVideoStart: 'onVideoStart', -}; - -export const RewardedVideoEventTypes = { - onRewarded: 'onRewarded', - onRewardedVideoStarted: 'onRewardedVideoStarted', -}; diff --git a/src/modules/admob/Interstitial.js b/src/modules/admob/Interstitial.js deleted file mode 100644 index a2f4c821..00000000 --- a/src/modules/admob/Interstitial.js +++ /dev/null @@ -1,119 +0,0 @@ -import { Platform } from 'react-native'; -import { statics } from './'; -import AdRequest from './AdRequest'; -import { SharedEventEmitter } from '../../utils/events'; -import { getNativeModule } from '../../utils/native'; -import { nativeToJSError } from '../../utils'; -import type AdMob from './'; - -let subscriptions = []; - -export default class Interstitial { - _admob: AdMob; - - constructor(admob: AdMob, adUnit: string) { - // Interstitials on iOS require a new instance each time - if (Platform.OS === 'ios') { - getNativeModule(admob).clearInterstitial(adUnit); - } - - for (let i = 0, len = subscriptions.length; i < len; i++) { - subscriptions[i].remove(); - } - subscriptions = []; - - this._admob = admob; - this.adUnit = adUnit; - this.loaded = false; - SharedEventEmitter.removeAllListeners(`interstitial_${adUnit}`); - SharedEventEmitter.addListener( - `interstitial_${adUnit}`, - this._onInterstitialEvent - ); - } - - /** - * Handle a JS emit event - * @param event - * @private - */ - _onInterstitialEvent = event => { - const eventType = `interstitial:${this.adUnit}:${event.type}`; - - let emitData = Object.assign({}, event); - - switch (event.type) { - case 'onAdLoaded': - this.loaded = true; - break; - case 'onAdFailedToLoad': - emitData = nativeToJSError(event.payload.code, event.payload.message); - emitData.type = event.type; - break; - default: - } - - SharedEventEmitter.emit(eventType, emitData); - SharedEventEmitter.emit(`interstitial:${this.adUnit}:*`, emitData); - }; - - /** - * Load an ad with an instance of AdRequest - * @param request - * @returns {*} - */ - loadAd(request?: AdRequest) { - let adRequest = request; - - if (!adRequest || !Object.keys(adRequest)) { - adRequest = new AdRequest().addTestDevice().build(); - } - - return getNativeModule(this._admob).interstitialLoadAd( - this.adUnit, - adRequest - ); - } - - /** - * Return a local instance of isLoaded - * @returns {boolean} - */ - isLoaded() { - return this.loaded; - } - - /** - * Show the advert - will only show if loaded - * @returns {*} - */ - show() { - if (this.loaded) { - getNativeModule(this._admob).interstitialShowAd(this.adUnit); - } - } - - /** - * Listen to an Ad event - * @param eventType - * @param listenerCb - * @returns {null} - */ - on(eventType, listenerCb) { - if (!statics.EventTypes[eventType]) { - console.warn( - `Invalid event type provided, must be one of: ${Object.keys( - statics.EventTypes - ).join(', ')}` - ); - return null; - } - - const sub = SharedEventEmitter.addListener( - `interstitial:${this.adUnit}:${eventType}`, - listenerCb - ); - subscriptions.push(sub); - return sub; - } -} diff --git a/src/modules/admob/NativeExpress.js b/src/modules/admob/NativeExpress.js deleted file mode 100644 index 1dd57232..00000000 --- a/src/modules/admob/NativeExpress.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import AdMobComponent from './AdMobComponent'; - -function NativeExpress({ ...props }) { - return ; -} - -NativeExpress.propTypes = AdMobComponent.propTypes; - -NativeExpress.defaultProps = { - size: 'SMART_BANNER', -}; - -export default NativeExpress; diff --git a/src/modules/admob/RewardedVideo.js b/src/modules/admob/RewardedVideo.js deleted file mode 100644 index f5f6e0db..00000000 --- a/src/modules/admob/RewardedVideo.js +++ /dev/null @@ -1,118 +0,0 @@ -import { statics } from './'; -import AdRequest from './AdRequest'; -import { SharedEventEmitter } from '../../utils/events'; -import { getNativeModule } from '../../utils/native'; -import { nativeToJSError } from '../../utils'; -import type AdMob from './'; - -let subscriptions = []; - -export default class RewardedVideo { - _admob: AdMob; - - constructor(admob: AdMob, adUnit: string) { - for (let i = 0, len = subscriptions.length; i < len; i++) { - subscriptions[i].remove(); - } - subscriptions = []; - - this._admob = admob; - this.adUnit = adUnit; - this.loaded = false; - SharedEventEmitter.removeAllListeners(`rewarded_video_${adUnit}`); - SharedEventEmitter.addListener( - `rewarded_video_${adUnit}`, - this._onRewardedVideoEvent - ); - } - - /** - * Handle a JS emit event - * @param event - * @private - */ - _onRewardedVideoEvent = event => { - const eventType = `rewarded_video:${this.adUnit}:${event.type}`; - - let emitData = Object.assign({}, event); - - switch (event.type) { - case 'onAdLoaded': - this.loaded = true; - break; - case 'onAdFailedToLoad': - emitData = nativeToJSError(event.payload.code, event.payload.message); - emitData.type = event.type; - break; - default: - } - - SharedEventEmitter.emit(eventType, emitData); - SharedEventEmitter.emit(`rewarded_video:${this.adUnit}:*`, emitData); - }; - - /** - * Load an ad with an instance of AdRequest - * @param request - * @returns {*} - */ - loadAd(request?: AdRequest) { - let adRequest = request; - - if (!adRequest || !Object.keys(adRequest)) { - adRequest = new AdRequest().addTestDevice().build(); - } - - return getNativeModule(this._admob).rewardedVideoLoadAd( - this.adUnit, - adRequest - ); - } - - /** - * Return a local instance of isLoaded - * @returns {boolean} - */ - isLoaded() { - return this.loaded; - } - - /** - * Show the advert - will only show if loaded - * @returns {*} - */ - show() { - if (this.loaded) { - getNativeModule(this._admob).rewardedVideoShowAd(this.adUnit); - } - } - - /** - * Listen to an Ad event - * @param eventType - * @param listenerCb - * @returns {null} - */ - on(eventType, listenerCb) { - const types = { - ...statics.EventTypes, - ...statics.RewardedVideoEventTypes, - }; - - if (!types[eventType]) { - console.warn( - `Invalid event type provided, must be one of: ${Object.keys(types).join( - ', ' - )}` - ); - return null; - } - - const sub = SharedEventEmitter.addListener( - `rewarded_video:${this.adUnit}:${eventType}`, - listenerCb - ); - subscriptions.push(sub); - return sub; - } -} diff --git a/src/modules/admob/VideoOptions.js b/src/modules/admob/VideoOptions.js deleted file mode 100644 index ab8a4777..00000000 --- a/src/modules/admob/VideoOptions.js +++ /dev/null @@ -1,16 +0,0 @@ -export default class VideoOptions { - constructor() { - this._props = { - startMuted: true, - }; - } - - build() { - return this._props; - } - - setStartMuted(muted: boolean = true) { - this._props.startMuted = muted; - return this; - } -} diff --git a/src/modules/admob/index.js b/src/modules/admob/index.js deleted file mode 100644 index a1ae8c37..00000000 --- a/src/modules/admob/index.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @flow - * AdMob representation wrapper - */ -import { SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import { getNativeModule } from '../../utils/native'; -import ModuleBase from '../../utils/ModuleBase'; - -import Interstitial from './Interstitial'; -import RewardedVideo from './RewardedVideo'; -import AdRequest from './AdRequest'; -import VideoOptions from './VideoOptions'; -import Banner from './Banner'; -import NativeExpress from './NativeExpress'; - -import EventTypes, { - NativeExpressEventTypes, - RewardedVideoEventTypes, -} from './EventTypes'; - -import type App from '../core/app'; - -type NativeEvent = { - adUnit: string, - payload: Object, - type: string, -}; - -const NATIVE_EVENTS = ['interstitial_event', 'rewarded_video_event']; - -export const MODULE_NAME = 'RNFirebaseAdMob'; -export const NAMESPACE = 'admob'; - -export default class AdMob extends ModuleBase { - _appId: ?string; - - _initialized: boolean; - - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - - this._initialized = false; - this._appId = null; - - SharedEventEmitter.addListener( - 'interstitial_event', - this._onInterstitialEvent.bind(this) - ); - SharedEventEmitter.addListener( - 'rewarded_video_event', - this._onRewardedVideoEvent.bind(this) - ); - } - - _onInterstitialEvent(event: NativeEvent): void { - const { adUnit } = event; - const jsEventType = `interstitial_${adUnit}`; - - if (SharedEventEmitter.listeners(jsEventType).length === 0) { - // TODO - } - - SharedEventEmitter.emit(jsEventType, event); - } - - _onRewardedVideoEvent(event: NativeEvent): void { - const { adUnit } = event; - const jsEventType = `rewarded_video_${adUnit}`; - - if (SharedEventEmitter.listeners(jsEventType).length === 0) { - // TODO - } - - SharedEventEmitter.emit(jsEventType, event); - } - - initialize(appId: string): void { - if (this._initialized) { - getLogger(this).warn('AdMob has already been initialized!'); - } else { - this._initialized = true; - this._appId = appId; - getNativeModule(this).initialize(appId); - } - } - - openDebugMenu(): void { - if (!this._initialized) { - getLogger(this).warn( - 'AdMob needs to be initialized before opening the dev menu!' - ); - } else { - getLogger(this).info('Opening debug menu'); - getNativeModule(this).openDebugMenu(this._appId); - } - } - - interstitial(adUnit: string): Interstitial { - return new Interstitial(this, adUnit); - } - - rewarded(adUnit: string): RewardedVideo { - return new RewardedVideo(this, adUnit); - } -} - -export const statics = { - Banner, - NativeExpress, - AdRequest, - VideoOptions, - EventTypes, - RewardedVideoEventTypes, - NativeExpressEventTypes, -}; diff --git a/src/modules/analytics/index.js b/src/modules/analytics/index.js deleted file mode 100644 index 007e1c7c..00000000 --- a/src/modules/analytics/index.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @flow - * Analytics representation wrapper - */ -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; -import { isString, isObject } from '../../utils'; - -import type App from '../core/app'; - -const AlphaNumericUnderscore = /^[a-zA-Z0-9_]+$/; - -const ReservedEventNames = [ - 'app_clear_data', - 'app_uninstall', - 'app_update', - 'error', - 'first_open', - 'in_app_purchase', - 'notification_dismiss', - 'notification_foreground', - 'notification_open', - 'notification_receive', - 'os_update', - 'session_start', - 'user_engagement', -]; - -export const MODULE_NAME = 'RNFirebaseAnalytics'; -export const NAMESPACE = 'analytics'; - -export default class Analytics extends ModuleBase { - constructor(app: App) { - super(app, { - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - } - - /** - * Logs an app event. - * @param {string} name - * @param params - * @return {Promise} - */ - logEvent(name: string, params: Object = {}): void { - if (!isString(name)) { - throw new Error( - `analytics.logEvent(): First argument 'name' is required and must be a string value.` - ); - } - - if (typeof params !== 'undefined' && !isObject(params)) { - throw new Error( - `analytics.logEvent(): Second optional argument 'params' must be an object if provided.` - ); - } - - // check name is not a reserved event name - if (ReservedEventNames.includes(name)) { - throw new Error( - `analytics.logEvent(): event name '${name}' is a reserved event name and can not be used.` - ); - } - - // name format validation - if (!AlphaNumericUnderscore.test(name)) { - throw new Error( - `analytics.logEvent(): Event name '${name}' is invalid. Names should contain 1 to 32 alphanumeric characters or underscores.` - ); - } - - // maximum number of allowed params check - if (params && Object.keys(params).length > 25) - throw new Error( - 'analytics.logEvent(): Maximum number of parameters exceeded (25).' - ); - - // Parameter names can be up to 24 characters long and must start with an alphabetic character - // and contain only alphanumeric characters and underscores. Only String, long and double param - // types are supported. String parameter values can be up to 36 characters long. The "firebase_" - // prefix is reserved and should not be used for parameter names. - - getNativeModule(this).logEvent(name, params); - } - - /** - * Sets whether analytics collection is enabled for this app on this device. - * @param enabled - */ - setAnalyticsCollectionEnabled(enabled: boolean): void { - getNativeModule(this).setAnalyticsCollectionEnabled(enabled); - } - - /** - * Sets the current screen name, which specifies the current visual context in your app. - * @param screenName - * @param screenClassOverride - */ - setCurrentScreen(screenName: string, screenClassOverride: string): void { - getNativeModule(this).setCurrentScreen(screenName, screenClassOverride); - } - - /** - * Sets the minimum engagement time required before starting a session. The default value is 10000 (10 seconds). - * @param milliseconds - */ - setMinimumSessionDuration(milliseconds: number = 10000): void { - getNativeModule(this).setMinimumSessionDuration(milliseconds); - } - - /** - * Sets the duration of inactivity that terminates the current session. The default value is 1800000 (30 minutes). - * @param milliseconds - */ - setSessionTimeoutDuration(milliseconds: number = 1800000): void { - getNativeModule(this).setSessionTimeoutDuration(milliseconds); - } - - /** - * Sets the user ID property. - * @param id - */ - setUserId(id: string | null): void { - if (id !== null && !isString(id)) { - throw new Error( - 'analytics.setUserId(): The supplied userId must be a string value or null.' - ); - } - getNativeModule(this).setUserId(id); - } - - /** - * Sets a user property to a given value. - * @param name - * @param value - */ - setUserProperty(name: string, value: string | null): void { - if (value !== null && !isString(value)) { - throw new Error( - 'analytics.setUserProperty(): The supplied property must be a string value or null.' - ); - } - getNativeModule(this).setUserProperty(name, value); - } - - /** - * Sets multiple user properties to the supplied values. - * @RNFirebaseSpecific - * @param object - */ - setUserProperties(object: Object): void { - Object.keys(object).forEach(property => { - const value = object[property]; - if (value !== null && !isString(value)) { - throw new Error( - `analytics.setUserProperties(): The property with name '${property}' must be a string value or null.` - ); - } - getNativeModule(this).setUserProperty(property, object[property]); - }); - } -} - -export const statics = {}; diff --git a/src/modules/auth/AuthSettings.js b/src/modules/auth/AuthSettings.js deleted file mode 100644 index 997efc79..00000000 --- a/src/modules/auth/AuthSettings.js +++ /dev/null @@ -1,70 +0,0 @@ -import { getNativeModule } from '../../utils/native'; -import { isAndroid, isIOS } from '../../utils'; - -import type Auth from './'; - -/** - * Interface representing an Auth instance's settings, currently used - * for enabling/disabling app verification for phone Auth testing. * - */ -export default class AuthSettings { - _auth: Auth; - - _appVerificationDisabledForTesting: boolean; - - constructor(auth: Auth) { - this._auth = auth; - this._appVerificationDisabledForTesting = false; - } - - /** - * Flag to determine whether app verification should be disabled for testing or not. - * - * @platform iOS - * @return {boolean} - */ - get appVerificationDisabledForTesting(): boolean { - return this._appVerificationDisabledForTesting; - } - - /** - * Flag to determine whether app verification should be disabled for testing or not. - * - * @platform iOS - * @param disabled - */ - set appVerificationDisabledForTesting(disabled: boolean) { - if (isIOS) { - this._appVerificationDisabledForTesting = disabled; - getNativeModule(this._auth).setAppVerificationDisabledForTesting( - disabled - ); - } - } - - /** - * The phone number and SMS code here must have been configured in the - * Firebase Console (Authentication > Sign In Method > Phone). - * - * Calling this method a second time will overwrite the previously passed parameters. - * Only one number can be configured at a given time. - * - * @platform Android - * @param phoneNumber - * @param smsCode - * @return {*} - */ - setAutoRetrievedSmsCodeForPhoneNumber( - phoneNumber: string, - smsCode: string - ): Promise { - if (isAndroid) { - return getNativeModule(this._auth).setAutoRetrievedSmsCodeForPhoneNumber( - phoneNumber, - smsCode - ); - } - - return Promise.resolve(null); - } -} diff --git a/src/modules/auth/User.js b/src/modules/auth/User.js deleted file mode 100644 index 96026b66..00000000 --- a/src/modules/auth/User.js +++ /dev/null @@ -1,347 +0,0 @@ -/** - * @flow - * User representation wrapper - */ -import INTERNALS from '../../utils/internals'; -import { getNativeModule } from '../../utils/native'; - -import type Auth from './'; -import type { - ActionCodeSettings, - AuthCredential, - NativeUser, - UserCredential, - UserInfo, - UserMetadata, - IdTokenResult, -} from './types'; - -type UpdateProfile = { - displayName?: string, - photoURL?: string, -}; - -export default class User { - _auth: Auth; - - _user: NativeUser; - - /** - * - * @param auth Instance of Authentication class - * @param user user result object from native - */ - constructor(auth: Auth, user: NativeUser) { - this._auth = auth; - this._user = user; - } - - /** - * PROPERTIES - */ - - get displayName(): ?string { - return this._user.displayName || null; - } - - get email(): ?string { - return this._user.email || null; - } - - get emailVerified(): boolean { - return this._user.emailVerified || false; - } - - get isAnonymous(): boolean { - return this._user.isAnonymous || false; - } - - get metadata(): UserMetadata { - return this._user.metadata; - } - - get phoneNumber(): ?string { - return this._user.phoneNumber || null; - } - - get photoURL(): ?string { - return this._user.photoURL || null; - } - - get providerData(): Array { - return this._user.providerData; - } - - get providerId(): string { - return this._user.providerId; - } - - get uid(): string { - return this._user.uid; - } - - /** - * METHODS - */ - - /** - * Delete the current user - * @return {Promise} - */ - delete(): Promise { - return getNativeModule(this._auth) - .delete() - .then(() => { - this._auth._setUser(); - }); - } - - /** - * Returns a JWT token used to identify the user to a Firebase service. - * - * @param forceRefresh boolean Force refresh regardless of token expiration. - * @return {Promise} - */ - getIdToken(forceRefresh: boolean = false): Promise { - return getNativeModule(this._auth).getIdToken(forceRefresh); - } - - /** - * Returns a IdTokenResult object which contains the ID token JWT string and other properties for getting - * data associated with the token and all the decoded payload claims. - * - * @param forceRefresh boolean Force refresh regardless of token expiration. - * @return {Promise} - */ - getIdTokenResult(forceRefresh: boolean = false): Promise { - return getNativeModule(this._auth).getIdTokenResult(forceRefresh); - } - - /** - * @param credential - */ - linkWithCredential(credential: AuthCredential): Promise { - return getNativeModule(this._auth) - .linkWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._auth._setUserCredential(userCredential)); - } - - /** - * @deprecated Deprecated linkAndRetrieveDataWithCredential in favor of linkWithCredential. - * @param credential - */ - linkAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise { - console.warn( - 'Deprecated linkAndRetrieveDataWithCredential in favor of linkWithCredential.' - ); - return getNativeModule(this._auth) - .linkWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._auth._setUserCredential(userCredential)); - } - - /** - * Re-authenticate a user with a third-party authentication provider - * @return {Promise} A promise resolved upon completion - */ - reauthenticateWithCredential( - credential: AuthCredential - ): Promise { - return getNativeModule(this._auth) - .reauthenticateWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._auth._setUserCredential(userCredential)); - } - - /** - * Re-authenticate a user with a third-party authentication provider - * - * @deprecated Deprecated reauthenticateAndRetrieveDataWithCredential in favor of reauthenticateWithCredential. - * @return {Promise} A promise resolved upon completion - */ - reauthenticateAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise { - console.warn( - 'Deprecated reauthenticateAndRetrieveDataWithCredential in favor of reauthenticateWithCredential.' - ); - return getNativeModule(this._auth) - .reauthenticateWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._auth._setUserCredential(userCredential)); - } - - /** - * Reload the current user - * @return {Promise} - */ - reload(): Promise { - return getNativeModule(this._auth) - .reload() - .then(user => { - this._auth._setUser(user); - }); - } - - /** - * Send verification email to current user. - */ - sendEmailVerification( - actionCodeSettings?: ActionCodeSettings - ): Promise { - return getNativeModule(this._auth) - .sendEmailVerification(actionCodeSettings) - .then(user => { - this._auth._setUser(user); - }); - } - - toJSON(): Object { - return Object.assign({}, this._user); - } - - /** - * - * @param providerId - * @return {Promise.|*} - */ - unlink(providerId: string): Promise { - return getNativeModule(this._auth) - .unlink(providerId) - .then(user => this._auth._setUser(user)); - } - - /** - * Update the current user's email - * - * @param {string} email The user's _new_ email - * @return {Promise} A promise resolved upon completion - */ - updateEmail(email: string): Promise { - return getNativeModule(this._auth) - .updateEmail(email) - .then(user => { - this._auth._setUser(user); - }); - } - - /** - * Update the current user's password - * @param {string} password the new password - * @return {Promise} - */ - updatePassword(password: string): Promise { - return getNativeModule(this._auth) - .updatePassword(password) - .then(user => { - this._auth._setUser(user); - }); - } - - /** - * Update the current user's phone number - * - * @param {AuthCredential} credential Auth credential with the _new_ phone number - * @return {Promise} - */ - updatePhoneNumber(credential: AuthCredential): Promise { - return getNativeModule(this._auth) - .updatePhoneNumber( - credential.providerId, - credential.token, - credential.secret - ) - .then(user => { - this._auth._setUser(user); - }); - } - - /** - * Update the current user's profile - * @param {Object} updates An object containing the keys listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile) - * @return {Promise} - */ - updateProfile(updates: UpdateProfile = {}): Promise { - return getNativeModule(this._auth) - .updateProfile(updates) - .then(user => { - this._auth._setUser(user); - }); - } - - /** - * KNOWN UNSUPPORTED METHODS - */ - - linkWithPhoneNumber() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( - 'User', - 'linkWithPhoneNumber' - ) - ); - } - - linkWithPopup() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'linkWithPopup') - ); - } - - linkWithRedirect() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( - 'User', - 'linkWithRedirect' - ) - ); - } - - reauthenticateWithPhoneNumber() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( - 'User', - 'reauthenticateWithPhoneNumber' - ) - ); - } - - reauthenticateWithPopup() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( - 'User', - 'reauthenticateWithPopup' - ) - ); - } - - reauthenticateWithRedirect() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD( - 'User', - 'reauthenticateWithRedirect' - ) - ); - } - - get refreshToken(): string { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('User', 'refreshToken') - ); - } -} diff --git a/src/modules/auth/index.js b/src/modules/auth/index.js deleted file mode 100644 index dac7e83e..00000000 --- a/src/modules/auth/index.js +++ /dev/null @@ -1,641 +0,0 @@ -/** - * @flow - * Auth representation wrapper - */ -import User from './User'; -import ModuleBase from '../../utils/ModuleBase'; -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; -import { isAndroid, isBoolean } from '../../utils'; -import { getLogger } from '../../utils/log'; -import { getNativeModule } from '../../utils/native'; -import INTERNALS from '../../utils/internals'; -import ConfirmationResult from './phone/ConfirmationResult'; -import PhoneAuthListener from './phone/PhoneAuthListener'; -import AuthSettings from './AuthSettings'; - -// providers -import EmailAuthProvider from './providers/EmailAuthProvider'; -import PhoneAuthProvider from './providers/PhoneAuthProvider'; -import GoogleAuthProvider from './providers/GoogleAuthProvider'; -import GithubAuthProvider from './providers/GithubAuthProvider'; -import OAuthProvider from './providers/OAuthProvider'; -import TwitterAuthProvider from './providers/TwitterAuthProvider'; -import FacebookAuthProvider from './providers/FacebookAuthProvider'; - -import type { - ActionCodeInfo, - ActionCodeSettings, - AuthCredential, - NativeUser, - NativeUserCredential, - UserCredential, -} from './types'; -import type App from '../core/app'; - -type AuthState = { - user?: NativeUser, -}; - -const NATIVE_EVENTS = [ - 'auth_state_changed', - 'auth_id_token_changed', - 'phone_auth_state_changed', -]; - -export const MODULE_NAME = 'RNFirebaseAuth'; -export const NAMESPACE = 'auth'; - -export default class Auth extends ModuleBase { - _authResult: boolean; - - _languageCode: string; - - _settings: AuthSettings | null; - - _user: User | null; - - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: true, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - const NativeModule = getNativeModule(this); - - this._user = null; - this._settings = null; - this._authResult = false; - this._languageCode = - NativeModule.APP_LANGUAGE[app._name] || - NativeModule.APP_LANGUAGE['[DEFAULT]']; - - if (NativeModule.APP_USER[app._name]) { - this._setUser(NativeModule.APP_USER[app._name]); - } - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onAuthStateChanged - getAppEventName(this, 'auth_state_changed'), - (state: AuthState) => { - this._setUser(state.user); - SharedEventEmitter.emit( - getAppEventName(this, 'onAuthStateChanged'), - this._user - ); - } - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public events based on event.type - getAppEventName(this, 'phone_auth_state_changed'), - (event: Object) => { - const eventKey = `phone:auth:${event.requestKey}:${event.type}`; - SharedEventEmitter.emit(eventKey, event.state); - } - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onIdTokenChanged - getAppEventName(this, 'auth_id_token_changed'), - (auth: AuthState) => { - this._setUser(auth.user); - SharedEventEmitter.emit( - getAppEventName(this, 'onIdTokenChanged'), - this._user - ); - } - ); - - NativeModule.addAuthStateListener(); - NativeModule.addIdTokenListener(); - } - - _setUser(user: ?NativeUser): ?User { - this._user = user ? new User(this, user) : null; - this._authResult = true; - SharedEventEmitter.emit(getAppEventName(this, 'onUserChanged'), this._user); - return this._user; - } - - _setUserCredential(userCredential: NativeUserCredential): UserCredential { - const user = new User(this, userCredential.user); - this._user = user; - this._authResult = true; - SharedEventEmitter.emit(getAppEventName(this, 'onUserChanged'), this._user); - return { - additionalUserInfo: userCredential.additionalUserInfo, - user, - }; - } - - /* - * WEB API - */ - - /** - * Listen for auth changes. - * @param listener - */ - onAuthStateChanged(listener: Function) { - getLogger(this).info('Creating onAuthStateChanged listener'); - SharedEventEmitter.addListener( - getAppEventName(this, 'onAuthStateChanged'), - listener - ); - if (this._authResult) listener(this._user || null); - - return () => { - getLogger(this).info('Removing onAuthStateChanged listener'); - SharedEventEmitter.removeListener( - getAppEventName(this, 'onAuthStateChanged'), - listener - ); - }; - } - - /** - * Listen for id token changes. - * @param listener - */ - onIdTokenChanged(listener: Function) { - getLogger(this).info('Creating onIdTokenChanged listener'); - SharedEventEmitter.addListener( - getAppEventName(this, 'onIdTokenChanged'), - listener - ); - if (this._authResult) listener(this._user || null); - - return () => { - getLogger(this).info('Removing onIdTokenChanged listener'); - SharedEventEmitter.removeListener( - getAppEventName(this, 'onIdTokenChanged'), - listener - ); - }; - } - - /** - * Listen for user changes. - * @param listener - */ - onUserChanged(listener: Function) { - getLogger(this).info('Creating onUserChanged listener'); - SharedEventEmitter.addListener( - getAppEventName(this, 'onUserChanged'), - listener - ); - if (this._authResult) listener(this._user || null); - - return () => { - getLogger(this).info('Removing onUserChanged listener'); - SharedEventEmitter.removeListener( - getAppEventName(this, 'onUserChanged'), - listener - ); - }; - } - - /** - * Sign the current user out - * @return {Promise} - */ - signOut(): Promise { - return getNativeModule(this) - .signOut() - .then(() => { - this._setUser(); - }); - } - - /** - * Sign a user in anonymously - * - * @return {Promise} A promise resolved upon completion - */ - signInAnonymously(): Promise { - return getNativeModule(this) - .signInAnonymously() - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign a user in anonymously - * - * @deprecated Deprecated signInAnonymouslyAndRetrieveData in favor of signInAnonymously. - * @return {Promise} A promise resolved upon completion - */ - signInAnonymouslyAndRetrieveData(): Promise { - console.warn( - 'Deprecated signInAnonymouslyAndRetrieveData in favor of signInAnonymously.' - ); - return getNativeModule(this) - .signInAnonymously() - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Create a user with the email/password functionality - * - * @param {string} email The user's email - * @param {string} password The user's password - * @return {Promise} A promise indicating the completion - */ - createUserWithEmailAndPassword( - email: string, - password: string - ): Promise { - return getNativeModule(this) - .createUserWithEmailAndPassword(email, password) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Create a user with the email/password functionality - * - * @deprecated Deprecated createUserAndRetrieveDataWithEmailAndPassword in favor of createUserWithEmailAndPassword. - * @param {string} email The user's email - * @param {string} password The user's password - * @return {Promise} A promise indicating the completion - */ - createUserAndRetrieveDataWithEmailAndPassword( - email: string, - password: string - ): Promise { - console.warn( - 'Deprecated createUserAndRetrieveDataWithEmailAndPassword in favor of createUserWithEmailAndPassword.' - ); - return getNativeModule(this) - .createUserWithEmailAndPassword(email, password) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign a user in with email/password - * - * @param {string} email The user's email - * @param {string} password The user's password - * @return {Promise} A promise that is resolved upon completion - */ - signInWithEmailAndPassword( - email: string, - password: string - ): Promise { - return getNativeModule(this) - .signInWithEmailAndPassword(email, password) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign a user in with email/password - * - * @deprecated Deprecated signInAndRetrieveDataWithEmailAndPassword in favor of signInWithEmailAndPassword - * @param {string} email The user's email - * @param {string} password The user's password - * @return {Promise} A promise that is resolved upon completion - */ - signInAndRetrieveDataWithEmailAndPassword( - email: string, - password: string - ): Promise { - console.warn( - 'Deprecated signInAndRetrieveDataWithEmailAndPassword in favor of signInWithEmailAndPassword.' - ); - return getNativeModule(this) - .signInWithEmailAndPassword(email, password) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign the user in with a custom auth token - * - * @param {string} customToken A self-signed custom auth token. - * @return {Promise} A promise resolved upon completion - */ - signInWithCustomToken(customToken: string): Promise { - return getNativeModule(this) - .signInWithCustomToken(customToken) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign the user in with a custom auth token - * - * @deprecated Deprecated signInAndRetrieveDataWithCustomToken in favor of signInWithCustomToken - * @param {string} customToken A self-signed custom auth token. - * @return {Promise} A promise resolved upon completion - */ - signInAndRetrieveDataWithCustomToken( - customToken: string - ): Promise { - console.warn( - 'Deprecated signInAndRetrieveDataWithCustomToken in favor of signInWithCustomToken.' - ); - return getNativeModule(this) - .signInWithCustomToken(customToken) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign the user in with a third-party authentication provider - * - * @return {Promise} A promise resolved upon completion - */ - signInWithCredential(credential: AuthCredential): Promise { - return getNativeModule(this) - .signInWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Sign the user in with a third-party authentication provider - * - * @deprecated Deprecated signInAndRetrieveDataWithCredential in favor of signInWithCredential. - * @return {Promise} A promise resolved upon completion - */ - signInAndRetrieveDataWithCredential( - credential: AuthCredential - ): Promise { - console.warn( - 'Deprecated signInAndRetrieveDataWithCredential in favor of signInWithCredential.' - ); - return getNativeModule(this) - .signInWithCredential( - credential.providerId, - credential.token, - credential.secret - ) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Asynchronously signs in using a phone number. - * - */ - signInWithPhoneNumber( - phoneNumber: string, - forceResend?: boolean - ): Promise { - if (isAndroid) { - return getNativeModule(this) - .signInWithPhoneNumber(phoneNumber, forceResend || false) - .then(result => new ConfirmationResult(this, result.verificationId)); - } - - return getNativeModule(this) - .signInWithPhoneNumber(phoneNumber) - .then(result => new ConfirmationResult(this, result.verificationId)); - } - - /** - * Returns a PhoneAuthListener to listen to phone verification events, - * on the final completion event a PhoneAuthCredential can be generated for - * authentication purposes. - * - * @param phoneNumber - * @param autoVerifyTimeoutOrForceResend Android Only - * @param forceResend Android Only - * @returns {PhoneAuthListener} - */ - verifyPhoneNumber( - phoneNumber: string, - autoVerifyTimeoutOrForceResend?: number | boolean, - forceResend?: boolean - ): PhoneAuthListener { - let _forceResend = forceResend; - let _autoVerifyTimeout = 60; - - if (isBoolean(autoVerifyTimeoutOrForceResend)) { - _forceResend = autoVerifyTimeoutOrForceResend; - } else { - _autoVerifyTimeout = autoVerifyTimeoutOrForceResend; - } - - return new PhoneAuthListener( - this, - phoneNumber, - _autoVerifyTimeout, - _forceResend - ); - } - - /** - * Send reset password instructions via email - * @param {string} email The email to send password reset instructions - * @param actionCodeSettings - */ - sendPasswordResetEmail( - email: string, - actionCodeSettings?: ActionCodeSettings - ): Promise { - return getNativeModule(this).sendPasswordResetEmail( - email, - actionCodeSettings - ); - } - - /** - * Sends a sign-in email link to the user with the specified email - * @param {string} email The email account to sign in with. - * @param actionCodeSettings - */ - sendSignInLinkToEmail( - email: string, - actionCodeSettings?: ActionCodeSettings - ): Promise { - return getNativeModule(this).sendSignInLinkToEmail( - email, - actionCodeSettings - ); - } - - /** - * Checks if an incoming link is a sign-in with email link. - * @param {string} emailLink Sign-in email link. - */ - isSignInWithEmailLink(emailLink: string): boolean { - return ( - typeof emailLink === 'string' && - (emailLink.includes('mode=signIn') || - emailLink.includes('mode%3DsignIn')) && - (emailLink.includes('oobCode=') || emailLink.includes('oobCode%3D')) - ); - } - - /** - * Asynchronously signs in using an email and sign-in email link. - * - * @param {string} email The email account to sign in with. - * @param {string} emailLink Sign-in email link. - * @return {Promise} A promise resolved upon completion - */ - signInWithEmailLink( - email: string, - emailLink: string - ): Promise { - return getNativeModule(this) - .signInWithEmailLink(email, emailLink) - .then(userCredential => this._setUserCredential(userCredential)); - } - - /** - * Completes the password reset process, given a confirmation code and new password. - * - * @link https://firebase.google.com/docs/reference/js/firebase.auth.Auth#confirmPasswordReset - * @param code - * @param newPassword - * @return {Promise.} - */ - confirmPasswordReset(code: string, newPassword: string): Promise { - return getNativeModule(this).confirmPasswordReset(code, newPassword); - } - - /** - * Applies a verification code sent to the user by email or other out-of-band mechanism. - * - * @link https://firebase.google.com/docs/reference/js/firebase.auth.Auth#applyActionCode - * @param code - * @return {Promise.} - */ - applyActionCode(code: string): Promise { - return getNativeModule(this).applyActionCode(code); - } - - /** - * Checks a verification code sent to the user by email or other out-of-band mechanism. - * - * @link https://firebase.google.com/docs/reference/js/firebase.auth.Auth#checkActionCode - * @param code - * @return {Promise.|Promise} - */ - checkActionCode(code: string): Promise { - return getNativeModule(this).checkActionCode(code); - } - - /** - * Returns a list of authentication methods that can be used to sign in a given user (identified by its main email address). - * @return {Promise} - */ - fetchSignInMethodsForEmail(email: string): Promise { - return getNativeModule(this).fetchSignInMethodsForEmail(email); - } - - verifyPasswordResetCode(code: string): Promise { - return getNativeModule(this).verifyPasswordResetCode(code); - } - - /** - * Sets the language for the auth module. - * - * @param code - */ - set languageCode(code: string) { - this._languageCode = code; - getNativeModule(this).setLanguageCode(code); - } - - /** - * The language for the auth module. - * - * @return {string} - */ - get languageCode(): string { - return this._languageCode; - } - - /** - * The current Auth instance's settings. This is used to edit/read configuration - * related options like app verification mode for phone authentication. - * - * @return {AuthSettings} - */ - get settings(): AuthSettings { - if (!this._settings) { - // lazy initialize - this._settings = new AuthSettings(this); - } - return this._settings; - } - - /** - * Get the currently signed in user - * @return {Promise} - */ - get currentUser(): User | null { - return this._user; - } - - /** - * KNOWN UNSUPPORTED METHODS - */ - - getRedirectResult() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'auth', - 'getRedirectResult' - ) - ); - } - - setPersistence() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'auth', - 'setPersistence' - ) - ); - } - - signInWithPopup() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'auth', - 'signInWithPopup' - ) - ); - } - - signInWithRedirect() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'auth', - 'signInWithRedirect' - ) - ); - } - - // firebase issue - https://github.com/invertase/react-native-firebase/pull/655#issuecomment-349904680 - useDeviceLanguage() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'auth', - 'useDeviceLanguage' - ) - ); - } -} - -export const statics = { - EmailAuthProvider, - PhoneAuthProvider, - GoogleAuthProvider, - GithubAuthProvider, - TwitterAuthProvider, - FacebookAuthProvider, - OAuthProvider, - PhoneAuthState: { - CODE_SENT: 'sent', - AUTO_VERIFY_TIMEOUT: 'timeout', - AUTO_VERIFIED: 'verified', - ERROR: 'error', - }, -}; diff --git a/src/modules/auth/phone/ConfirmationResult.js b/src/modules/auth/phone/ConfirmationResult.js deleted file mode 100644 index 94ef56a2..00000000 --- a/src/modules/auth/phone/ConfirmationResult.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @flow - * ConfirmationResult representation wrapper - */ -import { getNativeModule } from '../../../utils/native'; -import type Auth from '..'; -import type User from '../User'; - -export default class ConfirmationResult { - _auth: Auth; - - _verificationId: string; - - /** - * - * @param auth - * @param verificationId The phone number authentication operation's verification ID. - */ - constructor(auth: Auth, verificationId: string) { - this._auth = auth; - this._verificationId = verificationId; - } - - /** - * - * @param verificationCode - * @return {*} - */ - confirm(verificationCode: string): Promise { - return getNativeModule(this._auth) - ._confirmVerificationCode(verificationCode) - .then(user => this._auth._setUser(user)); - } - - get verificationId(): string | null { - return this._verificationId; - } -} diff --git a/src/modules/auth/phone/PhoneAuthListener.js b/src/modules/auth/phone/PhoneAuthListener.js deleted file mode 100644 index e1940601..00000000 --- a/src/modules/auth/phone/PhoneAuthListener.js +++ /dev/null @@ -1,365 +0,0 @@ -// @flow -import INTERNALS from '../../../utils/internals'; -import { SharedEventEmitter } from '../../../utils/events'; -import { - generatePushID, - isFunction, - isAndroid, - isIOS, - isString, - nativeToJSError, -} from '../../../utils'; -import { getNativeModule } from '../../../utils/native'; - -import type Auth from '..'; - -type PhoneAuthSnapshot = { - state: 'sent' | 'timeout' | 'verified' | 'error', - verificationId: string, - code: string | null, - error: Error | null, -}; - -type PhoneAuthError = { - code: string | null, - verificationId: string, - message: string | null, - stack: string | null, -}; - -export default class PhoneAuthListener { - _auth: Auth; - - _timeout: number; - - _publicEvents: Object; - - _internalEvents: Object; - - _forceResending: boolean; - - _reject: Function | null; - - _resolve: Function | null; - - _credential: Object | null; - - _promise: Promise<*> | null; - - _phoneAuthRequestKey: string; - - /** - * - * @param auth - * @param phoneNumber - * @param timeout - * @param forceResend - */ - constructor( - auth: Auth, - phoneNumber: string, - timeout?: number, - forceResend?: boolean - ) { - this._auth = auth; - this._reject = null; - this._resolve = null; - this._promise = null; - this._credential = null; - - this._timeout = timeout || 20; // 20 secs - this._forceResending = forceResend || false; - this._phoneAuthRequestKey = generatePushID(); - - // internal events - this._internalEvents = { - codeSent: `phone:auth:${this._phoneAuthRequestKey}:onCodeSent`, - verificationFailed: `phone:auth:${ - this._phoneAuthRequestKey - }:onVerificationFailed`, - verificationComplete: `phone:auth:${ - this._phoneAuthRequestKey - }:onVerificationComplete`, - codeAutoRetrievalTimeout: `phone:auth:${ - this._phoneAuthRequestKey - }:onCodeAutoRetrievalTimeout`, - }; - - // user observer events - this._publicEvents = { - // error cb - error: `phone:auth:${this._phoneAuthRequestKey}:error`, - // observer - event: `phone:auth:${this._phoneAuthRequestKey}:event`, - // success cb - success: `phone:auth:${this._phoneAuthRequestKey}:success`, - }; - - // setup internal event listeners - this._subscribeToEvents(); - - // start verification flow natively - if (isAndroid) { - getNativeModule(this._auth).verifyPhoneNumber( - phoneNumber, - this._phoneAuthRequestKey, - this._timeout, - this._forceResending - ); - } - - if (isIOS) { - getNativeModule(this._auth).verifyPhoneNumber( - phoneNumber, - this._phoneAuthRequestKey - ); - } - } - - /** - * Subscribes to all EE events on this._internalEvents - * @private - */ - _subscribeToEvents() { - const events = Object.keys(this._internalEvents); - - for (let i = 0, len = events.length; i < len; i++) { - const type = events[i]; - SharedEventEmitter.once( - this._internalEvents[type], - // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 - this[`_${type}Handler`].bind(this) - ); - } - } - - /** - * Subscribe a users listener cb to the snapshot events. - * @param observer - * @private - */ - _addUserObserver(observer) { - SharedEventEmitter.addListener(this._publicEvents.event, observer); - } - - /** - * Send a snapshot event to users event observer. - * @param snapshot PhoneAuthSnapshot - * @private - */ - _emitToObservers(snapshot: PhoneAuthSnapshot) { - SharedEventEmitter.emit(this._publicEvents.event, snapshot); - } - - /** - * Send a error snapshot event to any subscribed errorCb's - * @param snapshot - * @private - */ - _emitToErrorCb(snapshot) { - const { error } = snapshot; - if (this._reject) this._reject(error); - SharedEventEmitter.emit(this._publicEvents.error, error); - } - - /** - * Send a success snapshot event to any subscribed completeCb's - * @param snapshot - * @private - */ - _emitToSuccessCb(snapshot) { - if (this._resolve) this._resolve(snapshot); - SharedEventEmitter.emit(this._publicEvents.success, snapshot); - } - - /** - * Removes all listeners for this phone auth instance - * @private - */ - _removeAllListeners() { - setTimeout(() => { - // move to next event loop - not sure if needed - // internal listeners - Object.values(this._internalEvents).forEach(event => { - SharedEventEmitter.removeAllListeners(event); - }); - - // user observer listeners - Object.values(this._publicEvents).forEach(publicEvent => { - SharedEventEmitter.removeAllListeners(publicEvent); - }); - }, 0); - } - - /** - * Create a new internal deferred promise, if not already created - * @private - */ - _promiseDeferred() { - if (!this._promise) { - this._promise = new Promise((resolve, reject) => { - this._resolve = result => { - this._resolve = null; - return resolve(result); - }; - - this._reject = possibleError => { - this._reject = null; - return reject(possibleError); - }; - }); - } - } - - /* -------------------------- - --- INTERNAL EVENT HANDLERS - ---------------------------- */ - - /** - * Internal code sent event handler - * @private - * @param credential - */ - _codeSentHandler(credential) { - const snapshot: PhoneAuthSnapshot = { - verificationId: credential.verificationId, - code: null, - error: null, - state: 'sent', - }; - - this._emitToObservers(snapshot); - - if (isIOS) { - this._emitToSuccessCb(snapshot); - } - - if (isAndroid) { - // android can auto retrieve so we don't emit to successCb immediately, - // if auto retrieve times out then that will emit to successCb - } - } - - /** - * Internal code auto retrieve timeout event handler - * @private - * @param credential - */ - _codeAutoRetrievalTimeoutHandler(credential) { - const snapshot: PhoneAuthSnapshot = { - verificationId: credential.verificationId, - code: null, - error: null, - state: 'timeout', - }; - - this._emitToObservers(snapshot); - this._emitToSuccessCb(snapshot); - } - - /** - * Internal verification complete event handler - * @param credential - * @private - */ - _verificationCompleteHandler(credential) { - const snapshot: PhoneAuthSnapshot = { - verificationId: credential.verificationId, - code: credential.code || null, - error: null, - state: 'verified', - }; - - this._emitToObservers(snapshot); - this._emitToSuccessCb(snapshot); - this._removeAllListeners(); - } - - /** - * Internal verification failed event handler - * @param state - * @private - */ - _verificationFailedHandler(state) { - const snapshot: PhoneAuthSnapshot = { - verificationId: state.verificationId, - code: null, - error: null, - state: 'error', - }; - - const { code, message, nativeErrorMessage } = state.error; - snapshot.error = nativeToJSError(code, message, { nativeErrorMessage }); - - this._emitToObservers(snapshot); - this._emitToErrorCb(snapshot); - this._removeAllListeners(); - } - - /* ------------- - -- PUBLIC API - --------------*/ - - on( - event: string, - observer: PhoneAuthSnapshot => void, - errorCb?: PhoneAuthError => void, - successCb?: PhoneAuthSnapshot => void - ): this { - if (!isString(event)) { - throw new Error( - INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('event', 'string', 'on') - ); - } - - if (event !== 'state_changed') { - throw new Error( - INTERNALS.STRINGS.ERROR_ARG_INVALID_VALUE( - 'event', - 'state_changed', - event - ) - ); - } - - if (!isFunction(observer)) { - throw new Error( - INTERNALS.STRINGS.ERROR_MISSING_ARG_NAMED('observer', 'function', 'on') - ); - } - - this._addUserObserver(observer); - - if (isFunction(errorCb)) { - SharedEventEmitter.once(this._publicEvents.error, errorCb); - } - - if (isFunction(successCb)) { - SharedEventEmitter.once(this._publicEvents.success, successCb); - } - - return this; - } - - /** - * Promise .then proxy - * @param fn - */ - then(fn: PhoneAuthSnapshot => void) { - this._promiseDeferred(); - // $FlowFixMe: Unsure how to annotate `bind` here - if (this._promise) return this._promise.then.bind(this._promise)(fn); - return undefined; // will never get here - just to keep flow happy - } - - /** - * Promise .catch proxy - * @param fn - */ - catch(fn: Error => void) { - this._promiseDeferred(); - // $FlowFixMe: Unsure how to annotate `bind` here - if (this._promise) return this._promise.catch.bind(this._promise)(fn); - return undefined; // will never get here - just to keep flow happy - } -} diff --git a/src/modules/auth/providers/EmailAuthProvider.js b/src/modules/auth/providers/EmailAuthProvider.js deleted file mode 100644 index fc013a47..00000000 --- a/src/modules/auth/providers/EmailAuthProvider.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @flow - * EmailAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const linkProviderId = 'emailLink'; -const passwordProviderId = 'password'; - -export default class EmailAuthProvider { - constructor() { - throw new Error( - '`new EmailAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get EMAIL_LINK_SIGN_IN_METHOD(): string { - return linkProviderId; - } - - static get EMAIL_PASSWORD_SIGN_IN_METHOD(): string { - return passwordProviderId; - } - - static get PROVIDER_ID(): string { - return passwordProviderId; - } - - static credential(email: string, password: string): AuthCredential { - return { - token: email, - secret: password, - providerId: passwordProviderId, - }; - } - - /** - * Initialize an EmailAuthProvider credential using an email and an email link after a sign in with email link operation. - * @param email Email address. - * @param emailLink Sign-in email link. - * @returns {{token: string, secret: string, providerId: string}} - */ - static credentialWithLink(email: string, emailLink: string): AuthCredential { - return { - token: email, - secret: emailLink, - providerId: linkProviderId, - }; - } -} diff --git a/src/modules/auth/providers/FacebookAuthProvider.js b/src/modules/auth/providers/FacebookAuthProvider.js deleted file mode 100644 index 67fa957b..00000000 --- a/src/modules/auth/providers/FacebookAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * FacebookAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'facebook.com'; - -export default class FacebookAuthProvider { - constructor() { - throw new Error( - '`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(token: string): AuthCredential { - return { - token, - secret: '', - providerId, - }; - } -} diff --git a/src/modules/auth/providers/GithubAuthProvider.js b/src/modules/auth/providers/GithubAuthProvider.js deleted file mode 100644 index a6e8c13c..00000000 --- a/src/modules/auth/providers/GithubAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * GithubAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'github.com'; - -export default class GithubAuthProvider { - constructor() { - throw new Error( - '`new GithubAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(token: string): AuthCredential { - return { - token, - secret: '', - providerId, - }; - } -} diff --git a/src/modules/auth/providers/GoogleAuthProvider.js b/src/modules/auth/providers/GoogleAuthProvider.js deleted file mode 100644 index 25c81a21..00000000 --- a/src/modules/auth/providers/GoogleAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * EmailAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'google.com'; - -export default class GoogleAuthProvider { - constructor() { - throw new Error( - '`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(token: string, secret: string): AuthCredential { - return { - token, - secret, - providerId, - }; - } -} diff --git a/src/modules/auth/providers/OAuthProvider.js b/src/modules/auth/providers/OAuthProvider.js deleted file mode 100644 index 2bd28ed2..00000000 --- a/src/modules/auth/providers/OAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * OAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'oauth'; - -export default class OAuthProvider { - constructor() { - throw new Error( - '`new OAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(idToken: string, accessToken: string): AuthCredential { - return { - token: idToken, - secret: accessToken, - providerId, - }; - } -} diff --git a/src/modules/auth/providers/PhoneAuthProvider.js b/src/modules/auth/providers/PhoneAuthProvider.js deleted file mode 100644 index 57ce6558..00000000 --- a/src/modules/auth/providers/PhoneAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * PhoneAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'phone'; - -export default class PhoneAuthProvider { - constructor() { - throw new Error( - '`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(verificationId: string, code: string): AuthCredential { - return { - token: verificationId, - secret: code, - providerId, - }; - } -} diff --git a/src/modules/auth/providers/TwitterAuthProvider.js b/src/modules/auth/providers/TwitterAuthProvider.js deleted file mode 100644 index 150926bb..00000000 --- a/src/modules/auth/providers/TwitterAuthProvider.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @flow - * TwitterAuthProvider representation wrapper - */ -import type { AuthCredential } from '../types'; - -const providerId = 'twitter.com'; - -export default class TwitterAuthProvider { - constructor() { - throw new Error( - '`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.' - ); - } - - static get PROVIDER_ID(): string { - return providerId; - } - - static credential(token: string, secret: string): AuthCredential { - return { - token, - secret, - providerId, - }; - } -} diff --git a/src/modules/auth/types.js b/src/modules/auth/types.js deleted file mode 100644 index ca2976a9..00000000 --- a/src/modules/auth/types.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @flow - */ -import type User from './User'; - -export type IdTokenResult = { - token: string, - authTime: string, - issuedAtTime: string, - expirationTime: string, - signInProvider: null | string, - claims: { - [key: string]: any, - }, -}; - -export type ActionCodeInfo = { - data: { - email?: string, - fromEmail?: string, - }, - operation: - | 'PASSWORD_RESET' - | 'VERIFY_EMAIL' - | 'RECOVER_EMAIL' - | 'EMAIL_SIGNIN' - | 'ERROR', -}; - -export type ActionCodeSettings = { - android: { - installApp?: boolean, - minimumVersion?: string, - packageName: string, - }, - handleCodeInApp?: boolean, - iOS: { - bundleId?: string, - }, - url: string, -}; - -export type AdditionalUserInfo = { - isNewUser: boolean, - profile?: Object, - providerId: string, - username?: string, -}; - -export type AuthCredential = { - providerId: string, - token: string, - secret: string, -}; - -export type UserCredential = {| - additionalUserInfo?: AdditionalUserInfo, - user: User, -|}; - -export type UserInfo = { - displayName?: string, - email?: string, - phoneNumber?: string, - photoURL?: string, - providerId: string, - uid: string, -}; - -export type UserMetadata = { - creationTime?: string, - lastSignInTime?: string, -}; - -export type NativeUser = { - displayName?: string, - email?: string, - emailVerified?: boolean, - isAnonymous?: boolean, - metadata: UserMetadata, - phoneNumber?: string, - photoURL?: string, - providerData: UserInfo[], - providerId: string, - uid: string, -}; - -export type NativeUserCredential = {| - additionalUserInfo?: AdditionalUserInfo, - user: NativeUser, -|}; diff --git a/src/modules/config/index.js b/src/modules/config/index.js deleted file mode 100644 index 97efdb12..00000000 --- a/src/modules/config/index.js +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @flow - * Remote Config representation wrapper - */ -import { getLogger } from '../../utils/log'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -type NativeValue = { - stringValue?: string, - numberValue?: number, - dataValue?: Object, - boolValue?: boolean, - source: - | 'remoteConfigSourceRemote' - | 'remoteConfigSourceDefault' - | ' remoteConfigSourceStatic', -}; - -export const MODULE_NAME = 'RNFirebaseRemoteConfig'; -export const NAMESPACE = 'config'; - -type ConfigSnapshot = { - source: string, - val(): any, -}; - -/** - * @class Config - */ -export default class RemoteConfig extends ModuleBase { - _developerModeEnabled: boolean; - - constructor(app: App) { - super(app, { - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - this._developerModeEnabled = false; - } - - /** - * Converts a native map to single JS value - * @param nativeValue - * @returns {*} - * @private - */ - _nativeValueToJS(nativeValue: NativeValue): ConfigSnapshot { - return { - source: nativeValue.source, - val() { - if ( - nativeValue.boolValue !== null && - (nativeValue.stringValue === 'true' || - nativeValue.stringValue === 'false' || - nativeValue.stringValue === null) - ) - return nativeValue.boolValue; - if ( - nativeValue.numberValue !== null && - nativeValue.numberValue !== undefined && - (nativeValue.stringValue == null || - nativeValue.stringValue === '' || - nativeValue.numberValue.toString() === nativeValue.stringValue) - ) - return nativeValue.numberValue; - if ( - nativeValue.dataValue !== nativeValue.stringValue && - (nativeValue.stringValue == null || nativeValue.stringValue === '') - ) - return nativeValue.dataValue; - return nativeValue.stringValue; - }, - }; - } - - /** - * Enable Remote Config developer mode to allow for frequent refreshes of the cache - */ - enableDeveloperMode() { - if (!this._developerModeEnabled) { - getLogger(this).debug('Enabled developer mode'); - getNativeModule(this).enableDeveloperMode(); - this._developerModeEnabled = true; - } - } - - /** - * Fetches Remote Config data - * Call activateFetched to make fetched data available in app - * @returns {*|Promise.}: - */ - fetch(expiration?: number): Promise { - if (expiration !== undefined) { - getLogger(this).debug( - `Fetching remote config data with expiration ${expiration.toString()}` - ); - return getNativeModule(this).fetchWithExpirationDuration(expiration); - } - getLogger(this).debug('Fetching remote config data'); - return getNativeModule(this).fetch(); - } - - /** - * Applies Fetched Config data to the Active Config - * @returns {*|Promise.} - * resolves if there was a Fetched Config, and it was activated, - * rejects if no Fetched Config was found, or the Fetched Config was already activated. - */ - activateFetched(): Promise { - getLogger(this).debug('Activating remote config'); - return getNativeModule(this).activateFetched(); - } - - /** - * Gets the config value of the default namespace. - * @param key: Config key - * @returns {*|Promise.}, will always resolve - * Object looks like - * { - * "stringValue" : stringValue, - * "numberValue" : numberValue, - * "dataValue" : dataValue, - * "boolValue" : boolValue, - * "source" : OneOf(remoteConfigSourceRemote|remoteConfigSourceDefault|remoteConfigSourceStatic) - * } - */ - getValue(key: string): Promise { - return getNativeModule(this) - .getValue(key || '') - .then(this._nativeValueToJS); - } - - /** - * Gets the config value of the default namespace. - * @param keys: Config key - * @returns {*|Promise.}, will always resolve. - * Result will be a dictionary of key and config objects - * Object looks like - * { - * "stringValue" : stringValue, - * "numberValue" : numberValue, - * "dataValue" : dataValue, - * "boolValue" : boolValue, - * "source" : OneOf(remoteConfigSourceRemote|remoteConfigSourceDefault|remoteConfigSourceStatic) - * } - */ - getValues(keys: Array): Promise<{ [string]: ConfigSnapshot }> { - return getNativeModule(this) - .getValues(keys || []) - .then(nativeValues => { - const values: { [string]: Object } = {}; - for (let i = 0, len = keys.length; i < len; i++) { - values[keys[i]] = this._nativeValueToJS(nativeValues[i]); - } - return values; - }); - } - - /** - * Get the set of parameter keys that start with the given prefix, from the default namespace - * @param prefix: The key prefix to look for. If prefix is nil or empty, returns all the keys. - * @returns {*|Promise.>} - */ - getKeysByPrefix(prefix?: string): Promise { - return getNativeModule(this).getKeysByPrefix(prefix); - } - - /** - * Sets config defaults for parameter keys and values in the default namespace config. - * @param defaults: A dictionary mapping a String key to a Object values. - */ - setDefaults(defaults: Object): void { - getNativeModule(this).setDefaults(defaults); - } - - /** - * Sets default configs from plist for default namespace; - * @param resource: The plist file name or resource ID - */ - setDefaultsFromResource(resource: string | number): void { - getNativeModule(this).setDefaultsFromResource(resource); - } -} - -export const statics = {}; diff --git a/src/modules/core/app.js b/src/modules/core/app.js deleted file mode 100644 index 97deec05..00000000 --- a/src/modules/core/app.js +++ /dev/null @@ -1,208 +0,0 @@ -/* - * @flow - */ -import { NativeModules } from 'react-native'; - -import APPS from '../../utils/apps'; -import { SharedEventEmitter } from '../../utils/events'; -import INTERNALS from '../../utils/internals'; -import { isObject } from '../../utils'; - -import AdMob, { NAMESPACE as AdmobNamespace } from '../admob'; -import Auth, { NAMESPACE as AuthNamespace } from '../auth'; -import Analytics, { NAMESPACE as AnalyticsNamespace } from '../analytics'; -import Config, { NAMESPACE as ConfigNamespace } from '../config'; -import Crashlytics, { NAMESPACE as CrashlyticsNamespace } from '../crashlytics'; -import Database, { NAMESPACE as DatabaseNamespace } from '../database'; -import Firestore, { NAMESPACE as FirestoreNamespace } from '../firestore'; -import Functions, { NAMESPACE as FunctionsNamespace } from '../functions'; -import InstanceId, { NAMESPACE as InstanceIdNamespace } from '../iid'; -import Invites, { NAMESPACE as InvitesNamespace } from '../invites'; -import Links, { NAMESPACE as LinksNamespace } from '../links'; -import Messaging, { NAMESPACE as MessagingNamespace } from '../messaging'; -import Notifications, { - NAMESPACE as NotificationsNamespace, -} from '../notifications'; -import Performance, { NAMESPACE as PerfNamespace } from '../perf'; -import Storage, { NAMESPACE as StorageNamespace } from '../storage'; -import Utils, { NAMESPACE as UtilsNamespace } from '../utils'; - -import type { FirebaseOptions } from '../../types'; - -const FirebaseCoreModule = NativeModules.RNFirebase; - -export default class App { - _extendedProps: { [string]: boolean }; - - _initialized: boolean = false; - - _name: string; - - _nativeInitialized: boolean = false; - - _options: FirebaseOptions; - - admob: () => AdMob; - - analytics: () => Analytics; - - auth: () => Auth; - - config: () => Config; - - crashlytics: () => Crashlytics; - - database: () => Database; - - firestore: () => Firestore; - - functions: () => Functions; - - iid: () => InstanceId; - - invites: () => Invites; - - links: () => Links; - - messaging: () => Messaging; - - notifications: () => Notifications; - - perf: () => Performance; - - storage: () => Storage; - - utils: () => Utils; - - constructor( - name: string, - options: FirebaseOptions, - fromNative: boolean = false - ) { - this._name = name; - this._options = Object.assign({}, options); - - if (fromNative) { - this._initialized = true; - this._nativeInitialized = true; - } else if (options.databaseURL && options.apiKey) { - FirebaseCoreModule.initializeApp( - this._name, - this._options, - (error, result) => { - this._initialized = true; - SharedEventEmitter.emit(`AppReady:${this._name}`, { error, result }); - } - ); - } - - // modules - this.admob = APPS.appModule(this, AdmobNamespace, AdMob); - this.analytics = APPS.appModule(this, AnalyticsNamespace, Analytics); - this.auth = APPS.appModule(this, AuthNamespace, Auth); - this.config = APPS.appModule(this, ConfigNamespace, Config); - this.crashlytics = APPS.appModule(this, CrashlyticsNamespace, Crashlytics); - this.database = APPS.appModule(this, DatabaseNamespace, Database); - this.firestore = APPS.appModule(this, FirestoreNamespace, Firestore); - this.functions = APPS.appModule(this, FunctionsNamespace, Functions); - this.iid = APPS.appModule(this, InstanceIdNamespace, InstanceId); - this.invites = APPS.appModule(this, InvitesNamespace, Invites); - this.links = APPS.appModule(this, LinksNamespace, Links); - this.messaging = APPS.appModule(this, MessagingNamespace, Messaging); - this.notifications = APPS.appModule( - this, - NotificationsNamespace, - Notifications - ); - this.perf = APPS.appModule(this, PerfNamespace, Performance); - this.storage = APPS.appModule(this, StorageNamespace, Storage); - this.utils = APPS.appModule(this, UtilsNamespace, Utils); - this._extendedProps = {}; - } - - /** - * - * @return {*} - */ - get name(): string { - return this._name; - } - - /** - * - * @return {*} - */ - get options(): FirebaseOptions { - return Object.assign({}, this._options); - } - - /** - * Undocumented firebase web sdk method that allows adding additional properties onto - * a firebase app instance. - * - * See: https://github.com/firebase/firebase-js-sdk/blob/master/tests/app/firebase_app.test.ts#L328 - * - * @param props - */ - extendApp(props: Object) { - if (!isObject(props)) { - throw new Error( - INTERNALS.STRINGS.ERROR_MISSING_ARG('Object', 'extendApp') - ); - } - - const keys = Object.keys(props); - - for (let i = 0, len = keys.length; i < len; i++) { - const key = keys[i]; - - if (!this._extendedProps[key] && Object.hasOwnProperty.call(this, key)) { - throw new Error(INTERNALS.STRINGS.ERROR_PROTECTED_PROP(key)); - } - - // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 - this[key] = props[key]; - this._extendedProps[key] = true; - } - } - - /** - * - * @return {Promise} - */ - delete(): Promise { - if (this._name === APPS.DEFAULT_APP_NAME && this._nativeInitialized) { - return Promise.reject( - new Error('Unable to delete the default native firebase app instance.') - ); - } - - return FirebaseCoreModule.deleteApp(this._name).then(() => - APPS.deleteApp(this._name) - ); - } - - /** - * - * @return {*} - */ - onReady(): Promise { - if (this._initialized) return Promise.resolve(this); - - return new Promise((resolve, reject) => { - SharedEventEmitter.once(`AppReady:${this._name}`, ({ error }) => { - if (error) return reject(new Error(error)); // error is a string as it's from native - return resolve(this); // return app - }); - }); - } - - /** - * toString returns the name of the app. - * - * @return {string} - */ - toString() { - return this._name; - } -} diff --git a/src/modules/core/firebase.js b/src/modules/core/firebase.js deleted file mode 100644 index 0b3a2e58..00000000 --- a/src/modules/core/firebase.js +++ /dev/null @@ -1,262 +0,0 @@ -/** - * @flow - */ -import { NativeModules } from 'react-native'; - -import APPS from '../../utils/apps'; -import INTERNALS from '../../utils/internals'; -import App from './app'; -import VERSION from '../../version'; - -// module imports -import { - statics as AdMobStatics, - MODULE_NAME as AdmobModuleName, -} from '../admob'; -import { statics as AuthStatics, MODULE_NAME as AuthModuleName } from '../auth'; -import { - statics as AnalyticsStatics, - MODULE_NAME as AnalyticsModuleName, -} from '../analytics'; -import { - statics as ConfigStatics, - MODULE_NAME as ConfigModuleName, -} from '../config'; -import { - statics as CrashlyticsStatics, - MODULE_NAME as CrashlyticsModuleName, -} from '../crashlytics'; -import { - statics as DatabaseStatics, - MODULE_NAME as DatabaseModuleName, -} from '../database'; -import { - statics as FirestoreStatics, - MODULE_NAME as FirestoreModuleName, -} from '../firestore'; -import { - statics as FunctionsStatics, - MODULE_NAME as FunctionsModuleName, -} from '../functions'; -import { - statics as InstanceIdStatics, - MODULE_NAME as InstanceIdModuleName, -} from '../iid'; -import { - statics as InvitesStatics, - MODULE_NAME as InvitesModuleName, -} from '../invites'; -import { - statics as LinksStatics, - MODULE_NAME as LinksModuleName, -} from '../links'; -import { - statics as MessagingStatics, - MODULE_NAME as MessagingModuleName, -} from '../messaging'; -import { - statics as NotificationsStatics, - MODULE_NAME as NotificationsModuleName, -} from '../notifications'; -import { - statics as PerformanceStatics, - MODULE_NAME as PerfModuleName, -} from '../perf'; -import { - statics as StorageStatics, - MODULE_NAME as StorageModuleName, -} from '../storage'; -import { - statics as UtilsStatics, - MODULE_NAME as UtilsModuleName, -} from '../utils'; - -import type { - AdMobModule, - AnalyticsModule, - AuthModule, - ConfigModule, - CrashlyticsModule, - DatabaseModule, - FirebaseOptions, - FirestoreModule, - FunctionsModule, - InstanceIdModule, - InvitesModule, - LinksModule, - MessagingModule, - NotificationsModule, - PerformanceModule, - StorageModule, - UtilsModule, -} from '../../types'; - -const FirebaseCoreModule = NativeModules.RNFirebase; - -class Firebase { - admob: AdMobModule; - - analytics: AnalyticsModule; - - auth: AuthModule; - - config: ConfigModule; - - crashlytics: CrashlyticsModule; - - database: DatabaseModule; - - firestore: FirestoreModule; - - functions: FunctionsModule; - - iid: InstanceIdModule; - - invites: InvitesModule; - - links: LinksModule; - - messaging: MessagingModule; - - notifications: NotificationsModule; - - perf: PerformanceModule; - - storage: StorageModule; - - utils: UtilsModule; - - constructor() { - if (!FirebaseCoreModule) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_CORE); - } - APPS.initializeNativeApps(); - - // modules - this.admob = APPS.moduleAndStatics('admob', AdMobStatics, AdmobModuleName); - this.analytics = APPS.moduleAndStatics( - 'analytics', - AnalyticsStatics, - AnalyticsModuleName - ); - this.auth = APPS.moduleAndStatics('auth', AuthStatics, AuthModuleName); - this.config = APPS.moduleAndStatics( - 'config', - ConfigStatics, - ConfigModuleName - ); - this.crashlytics = APPS.moduleAndStatics( - 'crashlytics', - CrashlyticsStatics, - CrashlyticsModuleName - ); - this.database = APPS.moduleAndStatics( - 'database', - DatabaseStatics, - DatabaseModuleName - ); - this.firestore = APPS.moduleAndStatics( - 'firestore', - FirestoreStatics, - FirestoreModuleName - ); - this.functions = APPS.moduleAndStatics( - 'functions', - FunctionsStatics, - FunctionsModuleName - ); - this.iid = APPS.moduleAndStatics( - 'iid', - InstanceIdStatics, - InstanceIdModuleName - ); - this.invites = APPS.moduleAndStatics( - 'invites', - InvitesStatics, - InvitesModuleName - ); - this.links = APPS.moduleAndStatics('links', LinksStatics, LinksModuleName); - this.messaging = APPS.moduleAndStatics( - 'messaging', - MessagingStatics, - MessagingModuleName - ); - this.notifications = APPS.moduleAndStatics( - 'notifications', - NotificationsStatics, - NotificationsModuleName - ); - this.perf = APPS.moduleAndStatics( - 'perf', - PerformanceStatics, - PerfModuleName - ); - this.storage = APPS.moduleAndStatics( - 'storage', - StorageStatics, - StorageModuleName - ); - this.utils = APPS.moduleAndStatics('utils', UtilsStatics, UtilsModuleName); - } - - /** - * Web SDK initializeApp - * - * @param options - * @param name - * @return {*} - */ - initializeApp(options: FirebaseOptions, name: string): App { - return APPS.initializeApp(options, name); - } - - /** - * Retrieves a Firebase app instance. - * - * When called with no arguments, the default app is returned. - * When an app name is provided, the app corresponding to that name is returned. - * - * @param name - * @return {*} - */ - app(name?: string): App { - return APPS.app(name); - } - - /** - * A (read-only) array of all initialized apps. - * @return {Array} - */ - get apps(): Array { - return APPS.apps(); - } - - /** - * The current SDK version. - * @return {string} - */ - get SDK_VERSION(): string { - return VERSION; - } -} - -const firebaseApp = new Firebase(); -export default firebaseApp; -export const { - admob, - analytics, - auth, - config, - crashlytics, - database, - firestore, - functions, - iid, - invites, - links, - messaging, - notifications, - perf, - storage, - utils, -} = firebaseApp; diff --git a/src/modules/crashlytics/index.js b/src/modules/crashlytics/index.js deleted file mode 100644 index 8ee91784..00000000 --- a/src/modules/crashlytics/index.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @flow - * Crash Reporting representation wrapper - */ -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -export const MODULE_NAME = 'RNFirebaseCrashlytics'; -export const NAMESPACE = 'crashlytics'; - -export default class Crashlytics extends ModuleBase { - constructor(app: App) { - super(app, { - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - } - - /** - * Forces a crash. Useful for testing your application is set up correctly. - */ - crash(): void { - getNativeModule(this).crash(); - } - - /** - * Logs a message that will appear in any subsequent crash reports. - * @param {string} message - */ - log(message: string): void { - getNativeModule(this).log(message); - } - - /** - * Logs a non fatal exception. - * @param {string} code - * @param {string} message - */ - recordError(code: number, message: string): void { - getNativeModule(this).recordError(code, message); - } - - /** - * Set a boolean value to show alongside any subsequent crash reports. - */ - setBoolValue(key: string, value: boolean): void { - getNativeModule(this).setBoolValue(key, value); - } - - /** - * Set a float value to show alongside any subsequent crash reports. - */ - setFloatValue(key: string, value: number): void { - getNativeModule(this).setFloatValue(key, value); - } - - /** - * Set an integer value to show alongside any subsequent crash reports. - */ - setIntValue(key: string, value: number): void { - getNativeModule(this).setIntValue(key, value); - } - - /** - * Set a string value to show alongside any subsequent crash reports. - */ - setStringValue(key: string, value: string): void { - getNativeModule(this).setStringValue(key, value); - } - - /** - * Set the user ID to show alongside any subsequent crash reports. - */ - setUserIdentifier(userId: string): void { - getNativeModule(this).setUserIdentifier(userId); - } - - /** - * Enable Crashlytics reporting. Only avaliable when disabled automatic initialization - */ - enableCrashlyticsCollection(): void { - getNativeModule(this).enableCrashlyticsCollection(); - } -} - -export const statics = {}; diff --git a/src/modules/database/DataSnapshot.js b/src/modules/database/DataSnapshot.js deleted file mode 100644 index 1d9d2309..00000000 --- a/src/modules/database/DataSnapshot.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @flow - * DataSnapshot representation wrapper - */ -import { isObject, deepGet, deepExists } from '../../utils'; -import type Reference from './Reference'; - -type ExportedValue = { - '.value': any, - '.priority': string | number | null, -}; - -/** - * @class DataSnapshot - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot - */ -export default class DataSnapshot { - ref: Reference; - - key: string; - - _value: any; - - _priority: any; - - _childKeys: Array; - - constructor(ref: Reference, snapshot: Object) { - this.key = snapshot.key; - - if (ref.key !== snapshot.key) { - this.ref = ref.child(snapshot.key); - } else { - this.ref = ref; - } - - // internal use only - this._value = snapshot.value; - this._priority = snapshot.priority === undefined ? null : snapshot.priority; - this._childKeys = snapshot.childKeys || []; - } - - /** - * Extracts a JavaScript value from a DataSnapshot. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#val - * @returns {any} - */ - val(): any { - // clone via JSON stringify/parse - prevent modification of this._value - if (isObject(this._value) || Array.isArray(this._value)) { - return JSON.parse(JSON.stringify(this._value)); - } - - return this._value; - } - - /** - * Exports the entire contents of the DataSnapshot as a JavaScript object. - * - * The exportVal() method is similar to val(), except priority information is - * included (if available), making it suitable for backing up your data. - * - * @return {{'.value': *, '.priority': *}} - */ - exportVal(): ExportedValue { - let value = this._value; - - if (isObject(this._value) || Array.isArray(this._value)) { - value = JSON.parse(JSON.stringify(this._value)); - } - - return { - '.value': value, - '.priority': this._priority, - }; - } - - /** - * Gets another DataSnapshot for the location at the specified relative path. - * @param path - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#forEach - * @returns {Snapshot} - */ - child(path: string): DataSnapshot { - // TODO validate path is a string - let value = deepGet(this._value, path); - if (value === undefined) value = null; - const childRef = this.ref.child(path); - return new DataSnapshot(childRef, { - value, - key: childRef.key, - exists: value !== null, - - // TODO this is wrong - child keys needs to be the ordered keys, from FB - // TODO potential solution is build up a tree/map of a snapshot and its children - // TODO natively and send that back to JS to be use in this class. - - // null check to keep flow happy even though isObject already does this - childKeys: isObject(value) && value !== null ? Object.keys(value) : [], - }); - } - - /** - * Returns true if this DataSnapshot contains any data. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#exists - * @returns {boolean} - */ - exists(): boolean { - return this._value !== null; - } - - /** - * Enumerates the top-level children in the DataSnapshot. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#forEach - * @param action - */ - forEach(action: (key: any) => any): boolean { - if (!this._childKeys.length) return false; - let cancelled = false; - - for (let i = 0, len = this._childKeys.length; i < len; i++) { - const key = this._childKeys[i]; - const childSnapshot = this.child(key); - const returnValue = action(childSnapshot); - - if (returnValue === true) { - cancelled = true; - break; - } - } - - return cancelled; - } - - /** - * Gets the priority value of the data in this DataSnapshot. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#getPriority - * @returns {String|Number|null} - */ - getPriority(): string | number | null { - return this._priority; - } - - /** - * Returns true if the specified child path has (non-null) data. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#hasChild - * @param path - * @returns {Boolean} - */ - hasChild(path: string): boolean { - return deepExists(this._value, path); - } - - /** - * Returns whether or not the DataSnapshot has any non-null child properties. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#hasChildren - * @returns {boolean} - */ - hasChildren(): boolean { - return this.numChildren() > 0; - } - - /** - * Returns the number of child properties of this DataSnapshot. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#numChildren - * @returns {Number} - */ - numChildren(): number { - if (!isObject(this._value)) return 0; - return Object.keys(this._value).length; - } - - /** - * Returns a JSON-serializable representation of this object. - * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#toJSON - * @returns {any} - */ - toJSON(): Object { - return this.val(); - } -} diff --git a/src/modules/database/OnDisconnect.js b/src/modules/database/OnDisconnect.js deleted file mode 100644 index f04286b1..00000000 --- a/src/modules/database/OnDisconnect.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @flow - * OnDisconnect representation wrapper - */ -import { typeOf } from '../../utils'; -import { getNativeModule } from '../../utils/native'; -import type Database from './'; -import type Reference from './Reference'; - -/** - * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect - * @class OmDisconnect - */ -export default class OnDisconnect { - _database: Database; - - ref: Reference; - - path: string; - - /** - * - * @param ref - */ - constructor(ref: Reference) { - this.ref = ref; - this.path = ref.path; - this._database = ref._database; - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect#set - * @param value - * @returns {*} - */ - set(value: string | Object): Promise { - return getNativeModule(this._database).onDisconnectSet(this.path, { - type: typeOf(value), - value, - }); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect#update - * @param values - * @returns {*} - */ - update(values: Object): Promise { - return getNativeModule(this._database).onDisconnectUpdate( - this.path, - values - ); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect#remove - * @returns {*} - */ - remove(): Promise { - return getNativeModule(this._database).onDisconnectRemove(this.path); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect#cancel - * @returns {*} - */ - cancel(): Promise { - return getNativeModule(this._database).onDisconnectCancel(this.path); - } -} diff --git a/src/modules/database/Query.js b/src/modules/database/Query.js deleted file mode 100644 index 5a74066e..00000000 --- a/src/modules/database/Query.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @flow - * Query representation wrapper - */ -import { objectToUniqueId } from '../../utils'; - -import type { DatabaseModifier } from '../../types'; -import type Reference from './Reference'; - -// todo doc methods - -/** - * @class Query - */ -export default class Query { - _reference: Reference; - - modifiers: Array; - - constructor(ref: Reference, existingModifiers?: Array) { - this.modifiers = existingModifiers ? [...existingModifiers] : []; - this._reference = ref; - } - - /** - * - * @param name - * @param key - * @return {Reference|*} - */ - orderBy(name: string, key?: string) { - this.modifiers.push({ - id: `orderBy-${name}:${key || ''}`, - type: 'orderBy', - name, - key, - }); - - return this._reference; - } - - /** - * - * @param name - * @param limit - * @return {Reference|*} - */ - limit(name: string, limit: number) { - this.modifiers.push({ - id: `limit-${name}:${limit}`, - type: 'limit', - name, - limit, - }); - - return this._reference; - } - - /** - * - * @param name - * @param value - * @param key - * @return {Reference|*} - */ - filter(name: string, value: any, key?: string) { - this.modifiers.push({ - id: `filter-${name}:${objectToUniqueId(value)}:${key || ''}`, - type: 'filter', - name, - value, - valueType: typeof value, - key, - }); - - return this._reference; - } - - /** - * - * @return {[*]} - */ - getModifiers(): Array { - return [...this.modifiers]; - } - - /** - * - * @return {*} - */ - queryIdentifier() { - // sort modifiers to enforce ordering - const sortedModifiers = this.getModifiers().sort((a, b) => { - if (a.id < b.id) return -1; - if (a.id > b.id) return 1; - return 0; - }); - - // Convert modifiers to unique key - let key = '{'; - for (let i = 0; i < sortedModifiers.length; i++) { - if (i !== 0) key += ','; - key += sortedModifiers[i].id; - } - key += '}'; - - return key; - } -} diff --git a/src/modules/database/Reference.js b/src/modules/database/Reference.js deleted file mode 100644 index e0142686..00000000 --- a/src/modules/database/Reference.js +++ /dev/null @@ -1,848 +0,0 @@ -/** - * @flow - * Database Reference representation wrapper - */ -import Query from './Query'; -import DataSnapshot from './DataSnapshot'; -import OnDisconnect from './OnDisconnect'; -import { getLogger } from '../../utils/log'; -import { getNativeModule } from '../../utils/native'; -import ReferenceBase from '../../utils/ReferenceBase'; - -import { - promiseOrCallback, - isFunction, - isObject, - isString, - tryJSONParse, - tryJSONStringify, - generatePushID, -} from '../../utils'; - -import SyncTree from '../../utils/SyncTree'; - -import type Database from './'; -import type { DatabaseModifier, FirebaseError } from '../../types'; - -// track all event registrations by path -let listeners = 0; - -/** - * Enum for event types - * @readonly - * @enum {String} - */ -const ReferenceEventTypes = { - value: 'value', - child_added: 'child_added', - child_removed: 'child_removed', - child_changed: 'child_changed', - child_moved: 'child_moved', -}; - -type DatabaseListener = { - listenerId: number, - eventName: string, - successCallback: Function, - failureCallback?: Function, -}; - -/** - * @typedef {String} ReferenceLocation - Path to location in the database, relative - * to the root reference. Consists of a path where segments are separated by a - * forward slash (/) and ends in a ReferenceKey - except the root location, which - * has no ReferenceKey. - * - * @example - * // root reference location: '/' - * // non-root reference: '/path/to/referenceKey' - */ - -/** - * @typedef {String} ReferenceKey - Identifier for each location that is unique to that - * location, within the scope of its parent. The last part of a ReferenceLocation. - */ - -/** - * Represents a specific location in your Database that can be used for - * reading or writing data. - * - * You can reference the root using firebase.database().ref() or a child location - * by calling firebase.database().ref("child/path"). - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference - * @class Reference - * @extends ReferenceBase - */ -export default class Reference extends ReferenceBase { - _database: Database; - - _query: Query; - - _refListeners: { [listenerId: number]: DatabaseListener }; - - then: (a?: any) => Promise; - - catch: (a?: any) => Promise; - - constructor( - database: Database, - path: string, - existingModifiers?: Array - ) { - super(path); - this._refListeners = {}; - this._database = database; - this._query = new Query(this, existingModifiers); - getLogger(database).debug('Created new Reference', this._getRefKey()); - } - - /** - * By calling `keepSynced(true)` on a location, the data for that location will - * automatically be downloaded and kept in sync, even when no listeners are - * attached for that location. Additionally, while a location is kept synced, - * it will not be evicted from the persistent disk cache. - * - * @link https://firebase.google.com/docs/reference/android/com/google/firebase/database/Query.html#keepSynced(boolean) - * @param bool - * @returns {*} - */ - keepSynced(bool: boolean): Promise { - return getNativeModule(this._database).keepSynced( - this._getRefKey(), - this.path, - this._query.getModifiers(), - bool - ); - } - - /** - * Writes data to this Database location. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#set - * @param value - * @param onComplete - * @returns {Promise} - */ - set(value: any, onComplete?: Function): Promise { - return promiseOrCallback( - getNativeModule(this._database).set( - this.path, - this._serializeAnyType(value) - ), - onComplete - ); - } - - /** - * Sets a priority for the data at this Database location. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#setPriority - * @param priority - * @param onComplete - * @returns {Promise} - */ - setPriority( - priority: string | number | null, - onComplete?: Function - ): Promise { - const _priority = this._serializeAnyType(priority); - - return promiseOrCallback( - getNativeModule(this._database).setPriority(this.path, _priority), - onComplete - ); - } - - /** - * Writes data the Database location. Like set() but also specifies the priority for that data. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#setWithPriority - * @param value - * @param priority - * @param onComplete - * @returns {Promise} - */ - setWithPriority( - value: any, - priority: string | number | null, - onComplete?: Function - ): Promise { - const _value = this._serializeAnyType(value); - const _priority = this._serializeAnyType(priority); - - return promiseOrCallback( - getNativeModule(this._database).setWithPriority( - this.path, - _value, - _priority - ), - onComplete - ); - } - - /** - * Writes multiple values to the Database at once. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#update - * @param val - * @param onComplete - * @returns {Promise} - */ - update(val: Object, onComplete?: Function): Promise { - const value = this._serializeObject(val); - - return promiseOrCallback( - getNativeModule(this._database).update(this.path, value), - onComplete - ); - } - - /** - * Removes the data at this Database location. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#remove - * @param onComplete - * @return {Promise} - */ - remove(onComplete?: Function): Promise { - return promiseOrCallback( - getNativeModule(this._database).remove(this.path), - onComplete - ); - } - - /** - * Atomically modifies the data at this location. - * - * @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction - * @param transactionUpdate - * @param onComplete - * @param applyLocally - */ - transaction( - transactionUpdate: Function, - onComplete: ( - error: ?Error, - committed: boolean, - snapshot: ?DataSnapshot - ) => *, - applyLocally: boolean = false - ) { - if (!isFunction(transactionUpdate)) { - return Promise.reject( - new Error('Missing transactionUpdate function argument.') - ); - } - - return new Promise((resolve, reject) => { - const onCompleteWrapper = (error, committed, snapshotData) => { - if (isFunction(onComplete)) { - if (error) { - onComplete(error, committed, null); - } else { - onComplete(null, committed, new DataSnapshot(this, snapshotData)); - } - } - - if (error) return reject(error); - return resolve({ - committed, - snapshot: new DataSnapshot(this, snapshotData), - }); - }; - - // start the transaction natively - this._database._transactionHandler.add( - this, - transactionUpdate, - onCompleteWrapper, - applyLocally - ); - }); - } - - /** - * - * @param eventName - * @param successCallback - * @param cancelOrContext - * @param context - * @returns {Promise.} - */ - once( - eventName: string = 'value', - successCallback: (snapshot: DataSnapshot) => void, - cancelOrContext: (error: FirebaseError) => void, - context?: Object - ) { - return getNativeModule(this._database) - .once(this._getRefKey(), this.path, this._query.getModifiers(), eventName) - .then(({ snapshot }) => { - const _snapshot = new DataSnapshot(this, snapshot); - - if (isFunction(successCallback)) { - if (isObject(cancelOrContext)) - successCallback.bind(cancelOrContext)(_snapshot); - if (context && isObject(context)) - successCallback.bind(context)(_snapshot); - successCallback(_snapshot); - } - - return _snapshot; - }) - .catch(error => { - if (isFunction(cancelOrContext)) return cancelOrContext(error); - throw error; - }); - } - - /** - * - * @param value - * @param onComplete - * @returns {*} - */ - push(value: any, onComplete?: Function): Reference | Promise { - const name = generatePushID(this._database._serverTimeOffset); - - const pushRef = this.child(name); - const thennablePushRef = this.child(name); - - let promise; - if (value != null) { - promise = thennablePushRef.set(value, onComplete).then(() => pushRef); - } else { - promise = Promise.resolve(pushRef); - } - - thennablePushRef.then = promise.then.bind(promise); - thennablePushRef.catch = promise.catch.bind(promise); - - if (isFunction(onComplete)) { - promise.catch(() => {}); - } - - return thennablePushRef; - } - - /** - * MODIFIERS - */ - - /** - * - * @returns {Reference} - */ - orderByKey(): Reference { - return this.orderBy('orderByKey'); - } - - /** - * - * @returns {Reference} - */ - orderByPriority(): Reference { - return this.orderBy('orderByPriority'); - } - - /** - * - * @returns {Reference} - */ - orderByValue(): Reference { - return this.orderBy('orderByValue'); - } - - /** - * - * @param key - * @returns {Reference} - */ - orderByChild(key: string): Reference { - return this.orderBy('orderByChild', key); - } - - /** - * - * @param name - * @param key - * @returns {Reference} - */ - orderBy(name: string, key?: string): Reference { - const newRef = new Reference( - this._database, - this.path, - this._query.getModifiers() - ); - newRef._query.orderBy(name, key); - return newRef; - } - - /** - * LIMITS - */ - - /** - * - * @param limit - * @returns {Reference} - */ - limitToLast(limit: number): Reference { - return this.limit('limitToLast', limit); - } - - /** - * - * @param limit - * @returns {Reference} - */ - limitToFirst(limit: number): Reference { - return this.limit('limitToFirst', limit); - } - - /** - * - * @param name - * @param limit - * @returns {Reference} - */ - limit(name: string, limit: number): Reference { - const newRef = new Reference( - this._database, - this.path, - this._query.getModifiers() - ); - newRef._query.limit(name, limit); - return newRef; - } - - /** - * FILTERS - */ - - /** - * - * @param value - * @param key - * @returns {Reference} - */ - equalTo(value: any, key?: string): Reference { - return this.filter('equalTo', value, key); - } - - /** - * - * @param value - * @param key - * @returns {Reference} - */ - endAt(value: any, key?: string): Reference { - return this.filter('endAt', value, key); - } - - /** - * - * @param value - * @param key - * @returns {Reference} - */ - startAt(value: any, key?: string): Reference { - return this.filter('startAt', value, key); - } - - /** - * - * @param name - * @param value - * @param key - * @returns {Reference} - */ - filter(name: string, value: any, key?: string): Reference { - const newRef = new Reference( - this._database, - this.path, - this._query.getModifiers() - ); - newRef._query.filter(name, value, key); - return newRef; - } - - /** - * - * @returns {OnDisconnect} - */ - onDisconnect(): OnDisconnect { - return new OnDisconnect(this); - } - - /** - * Creates a Reference to a child of the current Reference, using a relative path. - * No validation is performed on the path to ensure it has a valid format. - * @param {String} path relative to current ref's location - * @returns {!Reference} A new Reference to the path provided, relative to the current - * Reference - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#child} - */ - child(path: string): Reference { - return new Reference(this._database, `${this.path}/${path}`); - } - - /** - * Return the ref as a path string - * @returns {string} - */ - toString(): string { - return `${this._database.databaseUrl}${this.path}`; - } - - /** - * Return a JSON-serializable representation of this object. - * @returns {string} - */ - toJSON(): string { - return this.toString(); - } - - /** - * Returns whether another Reference represent the same location and are from the - * same instance of firebase.app.App - multiple firebase apps not currently supported. - * @param {Reference} otherRef - Other reference to compare to this one - * @return {Boolean} Whether otherReference is equal to this one - * - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#isEqual} - */ - isEqual(otherRef: Reference): boolean { - return ( - !!otherRef && - otherRef.constructor === Reference && - otherRef.key === this.key && - this._query.queryIdentifier() === otherRef._query.queryIdentifier() - ); - } - - /** - * GETTERS - */ - - /** - * The parent location of a Reference, or null for the root Reference. - * @type {Reference} - * - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#parent} - */ - get parent(): Reference | null { - if (this.path === '/') return null; - return new Reference( - this._database, - this.path.substring(0, this.path.lastIndexOf('/')) - ); - } - - /** - * A reference to itself - * @type {!Reference} - * - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#ref} - */ - get ref(): Reference { - return this; - } - - /** - * Reference to the root of the database: '/' - * @type {!Reference} - * - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#root} - */ - get root(): Reference { - return new Reference(this._database, '/'); - } - - /** - * INTERNALS - */ - - /** - * Generate a unique registration key. - * - * @return {string} - */ - _getRegistrationKey(eventType: string): string { - return `$${this._database.databaseUrl}$/${ - this.path - }$${this._query.queryIdentifier()}$${listeners}$${eventType}`; - } - - /** - * Generate a string that uniquely identifies this - * combination of path and query modifiers - * - * @return {string} - * @private - */ - _getRefKey() { - return `$${this._database.databaseUrl}$/${ - this.path - }$${this._query.queryIdentifier()}`; - } - - /** - * - * @param obj - * @returns {Object} - * @private - */ - _serializeObject(obj: Object) { - if (!isObject(obj)) return obj; - - // json stringify then parse it calls toString on Objects / Classes - // that support it i.e new Date() becomes a ISO string. - return tryJSONParse(tryJSONStringify(obj)); - } - - /** - * - * @param value - * @returns {*} - * @private - */ - _serializeAnyType(value: any) { - if (isObject(value)) { - return { - type: 'object', - value: this._serializeObject(value), - }; - } - - return { - type: typeof value, - value, - }; - } - - /** - * Register a listener for data changes at the current ref's location. - * The primary method of reading data from a Database. - * - * Listeners can be unbound using {@link off}. - * - * Event Types: - * - * - value: {@link callback}. - * - child_added: {@link callback} - * - child_removed: {@link callback} - * - child_changed: {@link callback} - * - child_moved: {@link callback} - * - * @param {ReferenceEventType} eventType - Type of event to attach a callback for. - * @param {ReferenceEventCallback} callback - Function that will be called - * when the event occurs with the new data. - * @param {cancelCallbackOrContext=} cancelCallbackOrContext - Optional callback that is called - * if the event subscription fails. {@link cancelCallbackOrContext} - * @param {*=} context - Optional object to bind the callbacks to when calling them. - * @returns {ReferenceEventCallback} callback function, unmodified (unbound), for - * convenience if you want to pass an inline function to on() and store it later for - * removing using off(). - * - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#on} - */ - on( - eventType: string, - callback: DataSnapshot => any, - cancelCallbackOrContext?: Object => any | Object, - context?: Object - ): Function { - if (!eventType) { - throw new Error( - 'Query.on failed: Function called with 0 arguments. Expects at least 2.' - ); - } - - if (!isString(eventType) || !ReferenceEventTypes[eventType]) { - throw new Error( - `Query.on failed: First argument must be a valid string event type: "${Object.keys( - ReferenceEventTypes - ).join(', ')}"` - ); - } - - if (!callback) { - throw new Error( - 'Query.on failed: Function called with 1 argument. Expects at least 2.' - ); - } - - if (!isFunction(callback)) { - throw new Error( - 'Query.on failed: Second argument must be a valid function.' - ); - } - - if ( - cancelCallbackOrContext && - !isFunction(cancelCallbackOrContext) && - !isObject(context) && - !isObject(cancelCallbackOrContext) - ) { - throw new Error( - 'Query.on failed: Function called with 3 arguments, but third optional argument `cancelCallbackOrContext` was not a function.' - ); - } - - if ( - cancelCallbackOrContext && - !isFunction(cancelCallbackOrContext) && - context - ) { - throw new Error( - 'Query.on failed: Function called with 4 arguments, but third optional argument `cancelCallbackOrContext` was not a function.' - ); - } - - const eventRegistrationKey = this._getRegistrationKey(eventType); - const registrationCancellationKey = `${eventRegistrationKey}$cancelled`; - const _context = - cancelCallbackOrContext && !isFunction(cancelCallbackOrContext) - ? cancelCallbackOrContext - : context; - const registrationObj = { - eventType, - ref: this, - path: this.path, - key: this._getRefKey(), - appName: this._database.app.name, - dbURL: this._database.databaseUrl, - eventRegistrationKey, - }; - - SyncTree.addRegistration({ - ...registrationObj, - listener: _context ? callback.bind(_context) : callback, - }); - - if (cancelCallbackOrContext && isFunction(cancelCallbackOrContext)) { - // cancellations have their own separate registration - // as these are one off events, and they're not guaranteed - // to occur either, only happens on failure to register on native - SyncTree.addRegistration({ - ref: this, - once: true, - path: this.path, - key: this._getRefKey(), - appName: this._database.app.name, - dbURL: this._database.databaseUrl, - eventType: `${eventType}$cancelled`, - eventRegistrationKey: registrationCancellationKey, - listener: _context - ? cancelCallbackOrContext.bind(_context) - : cancelCallbackOrContext, - }); - } - - // initialise the native listener if not already listening - getNativeModule(this._database).on({ - eventType, - path: this.path, - key: this._getRefKey(), - appName: this._database.app.name, - modifiers: this._query.getModifiers(), - hasCancellationCallback: isFunction(cancelCallbackOrContext), - registration: { - eventRegistrationKey, - key: registrationObj.key, - registrationCancellationKey, - }, - }); - - // increment number of listeners - just a short way of making - // every registration unique per .on() call - listeners += 1; - - // return original unbound successCallback for - // the purposes of calling .off(eventType, callback) at a later date - return callback; - } - - /** - * Detaches a callback previously attached with on(). - * - * Detach a callback previously attached with on(). Note that if on() was called - * multiple times with the same eventType and callback, the callback will be called - * multiple times for each event, and off() must be called multiple times to - * remove the callback. Calling off() on a parent listener will not automatically - * remove listeners registered on child nodes, off() must also be called on any - * child listeners to remove the callback. - * - * If a callback is not specified, all callbacks for the specified eventType will be removed. - * Similarly, if no eventType or callback is specified, all callbacks for the Reference will be removed. - * @param eventType - * @param originalCallback - */ - off(eventType?: string = '', originalCallback?: () => any) { - if (!arguments.length) { - // Firebase Docs: - // if no eventType or callback is specified, all callbacks for the Reference will be removed. - return SyncTree.removeListenersForRegistrations( - SyncTree.getRegistrationsByPath(this.path) - ); - } - - /* - * VALIDATE ARGS - */ - if ( - eventType && - (!isString(eventType) || !ReferenceEventTypes[eventType]) - ) { - throw new Error( - `Query.off failed: First argument must be a valid string event type: "${Object.keys( - ReferenceEventTypes - ).join(', ')}"` - ); - } - - if (originalCallback && !isFunction(originalCallback)) { - throw new Error( - 'Query.off failed: Function called with 2 arguments, but second optional argument was not a function.' - ); - } - - // Firebase Docs: - // Note that if on() was called - // multiple times with the same eventType and callback, the callback will be called - // multiple times for each event, and off() must be called multiple times to - // remove the callback. - // Remove only a single registration - if (eventType && originalCallback) { - const registration = SyncTree.getOneByPathEventListener( - this.path, - eventType, - originalCallback - ); - if (!registration) return []; - - // remove the paired cancellation registration if any exist - SyncTree.removeListenersForRegistrations([`${registration}$cancelled`]); - - // remove only the first registration to match firebase web sdk - // call multiple times to remove multiple registrations - return SyncTree.removeListenerRegistrations(originalCallback, [ - registration, - ]); - } - - // Firebase Docs: - // If a callback is not specified, all callbacks for the specified eventType will be removed. - const registrations = SyncTree.getRegistrationsByPathEvent( - this.path, - eventType - ); - - SyncTree.removeListenersForRegistrations( - SyncTree.getRegistrationsByPathEvent(this.path, `${eventType}$cancelled`) - ); - - return SyncTree.removeListenersForRegistrations(registrations); - } -} diff --git a/src/modules/database/index.js b/src/modules/database/index.js deleted file mode 100644 index fc415387..00000000 --- a/src/modules/database/index.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @flow - * Database representation wrapper - */ -import { NativeModules } from 'react-native'; - -import Reference from './Reference'; -import TransactionHandler from './transaction'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; -import firebase from '../core/firebase'; - -const NATIVE_EVENTS = [ - 'database_transaction_event', - // 'database_server_offset', // TODO -]; - -export const MODULE_NAME = 'RNFirebaseDatabase'; -export const NAMESPACE = 'database'; - -/** - * @class Database - */ -export default class Database extends ModuleBase { - _databaseURL: string; - - _offsetRef: Reference; - - _serverTimeOffset: number; - - _transactionHandler: TransactionHandler; - - constructor(appOrCustomUrl: App | string, customUrl?: string) { - let app; - let url; - - if (typeof appOrCustomUrl === 'string') { - app = firebase.app(); - url = appOrCustomUrl; - } else { - app = appOrCustomUrl; - url = customUrl || app.options.databaseURL; - } - - // enforce trailing slash - url = url.endsWith('/') ? url : `${url}/`; - - super( - app, - { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: true, - hasCustomUrlSupport: true, - namespace: NAMESPACE, - }, - url - ); - - this._serverTimeOffset = 0; - this._databaseURL = url; - this._transactionHandler = new TransactionHandler(this); - - if (app.options.persistence) { - getNativeModule(this).setPersistence(app.options.persistence); - } - - // server time listener - // setTimeout used to avoid setPersistence race conditions - // todo move this and persistence to native side, create a db configure() method natively perhaps? - // todo and then native can call setPersistence and then emit offset events - setTimeout(() => { - this._offsetRef = this.ref('.info/serverTimeOffset'); - this._offsetRef.on('value', snapshot => { - this._serverTimeOffset = snapshot.val() || this._serverTimeOffset; - }); - }, 1); - } - - /** - * - * @return {number} - */ - getServerTime(): number { - return new Date(Date.now() + this._serverTimeOffset); - } - - /** - * - */ - goOnline(): void { - getNativeModule(this).goOnline(); - } - - /** - * - */ - goOffline(): void { - getNativeModule(this).goOffline(); - } - - /** - * Returns a new firebase reference instance - * @param path - * @returns {Reference} - */ - ref(path: string): Reference { - return new Reference(this, path); - } - - /** - * Returns the database url - * @returns {string} - */ - get databaseUrl(): string { - return this._databaseURL; - } -} - -export const statics = { - ServerValue: NativeModules.RNFirebaseDatabase - ? { - TIMESTAMP: NativeModules.RNFirebaseDatabase.serverValueTimestamp || { - '.sv': 'timestamp', - }, - } - : {}, - enableLogging(enabled: boolean) { - if (NativeModules[MODULE_NAME]) { - NativeModules[MODULE_NAME].enableLogging(enabled); - } - }, -}; diff --git a/src/modules/database/transaction.js b/src/modules/database/transaction.js deleted file mode 100644 index bdfe2a2c..00000000 --- a/src/modules/database/transaction.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @flow - * Database Transaction representation wrapper - */ -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import { getNativeModule } from '../../utils/native'; -import type Database from './'; - -let transactionId = 0; - -/** - * Uses the push id generator to create a transaction id - * @returns {number} - * @private - */ -const generateTransactionId = (): number => transactionId++; - -/** - * @class TransactionHandler - */ -export default class TransactionHandler { - _database: Database; - - _transactions: { [number]: Object }; - - constructor(database: Database) { - this._transactions = {}; - this._database = database; - - SharedEventEmitter.addListener( - getAppEventName(this._database, 'database_transaction_event'), - this._handleTransactionEvent.bind(this) - ); - } - - /** - * Add a new transaction and start it natively. - * @param reference - * @param transactionUpdater - * @param onComplete - * @param applyLocally - */ - add( - reference: Object, - transactionUpdater: Function, - onComplete?: Function, - applyLocally?: boolean = false - ) { - const id = generateTransactionId(); - - this._transactions[id] = { - id, - reference, - transactionUpdater, - onComplete, - applyLocally, - completed: false, - started: true, - }; - - getNativeModule(this._database).transactionStart( - reference.path, - id, - applyLocally - ); - } - - /** - * INTERNALS - */ - - /** - * - * @param event - * @returns {*} - * @private - */ - _handleTransactionEvent(event: Object = {}) { - switch (event.type) { - case 'update': - return this._handleUpdate(event); - case 'error': - return this._handleError(event); - case 'complete': - return this._handleComplete(event); - default: - getLogger(this._database).warn( - `Unknown transaction event type: '${event.type}'`, - event - ); - return undefined; - } - } - - /** - * - * @param event - * @private - */ - _handleUpdate(event: Object = {}) { - let newValue; - const { id, value } = event; - - try { - const transaction = this._transactions[id]; - if (!transaction) return; - - newValue = transaction.transactionUpdater(value); - } finally { - let abort = false; - - if (newValue === undefined) { - abort = true; - } - - getNativeModule(this._database).transactionTryCommit(id, { - value: newValue, - abort, - }); - } - } - - /** - * - * @param event - * @private - */ - _handleError(event: Object = {}) { - const transaction = this._transactions[event.id]; - if (transaction && !transaction.completed) { - transaction.completed = true; - try { - transaction.onComplete(event.error, false, null); - } finally { - setImmediate(() => { - delete this._transactions[event.id]; - }); - } - } - } - - /** - * - * @param event - * @private - */ - _handleComplete(event: Object = {}) { - const transaction = this._transactions[event.id]; - if (transaction && !transaction.completed) { - transaction.completed = true; - try { - transaction.onComplete( - null, - event.committed, - Object.assign({}, event.snapshot) - ); - } finally { - setImmediate(() => { - delete this._transactions[event.id]; - }); - } - } - } -} diff --git a/src/modules/firestore/Blob.js b/src/modules/firestore/Blob.js deleted file mode 100644 index 8fac8b9e..00000000 --- a/src/modules/firestore/Blob.js +++ /dev/null @@ -1,91 +0,0 @@ -import Base64 from '../../utils/Base64'; - -export default class Blob { - _binaryString: string; - - constructor(binaryString: string) { - this._binaryString = binaryString; - } - - /** - * Creates a new Blob from the given Base64 string - * - * @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#.fromBase64String - * @param base64 string - */ - static fromBase64String(base64: string): Blob { - if (typeof base64 !== 'string' || base64.length < 1) { - throw new Error( - 'firestore.Blob.fromBase64String expects a string of at least 1 character in length' - ); - } - - return new Blob(Base64.atob(base64)); - } - - /** - * Creates a new Blob from the given Uint8Array. - * - * @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#.fromUint8Array - * @param array Array - */ - static fromUint8Array(array: Uint8Array): Blob { - if (!(array instanceof Uint8Array)) { - throw new Error( - 'firestore.Blob.fromUint8Array expects an instance of Uint8Array' - ); - } - - return new Blob( - Array.prototype.map - .call(array, (char: number) => String.fromCharCode(char)) - .join('') - ); - } - - /** - * Returns 'true' if this Blob is equal to the provided one. - * @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#isEqual - * @param {*} blob Blob The Blob to compare against. Value must not be null. - * @returns boolean 'true' if this Blob is equal to the provided one. - */ - isEqual(blob: Blob): boolean { - if (!(blob instanceof Blob)) { - throw new Error('firestore.Blob.isEqual expects an instance of Blob'); - } - - return this._binaryString === blob._binaryString; - } - - /** - * Returns the bytes of a Blob as a Base64-encoded string. - * - * @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#toBase64 - * @returns string The Base64-encoded string created from the Blob object. - */ - toBase64(): string { - return Base64.btoa(this._binaryString); - } - - /** - * Returns the bytes of a Blob in a new Uint8Array. - * - * @url https://firebase.google.com/docs/reference/js/firebase.firestore.Blob#toUint8Array - * @returns non-null Uint8Array The Uint8Array created from the Blob object. - */ - toUint8Array(): Uint8Array { - return new Uint8Array( - this._binaryString.split('').map(c => c.charCodeAt(0)) - ); - } - - /** - * Returns a string representation of this blob instance - * - * @returns {string} - * @memberof Blob - */ - toString(): string { - return `firestore.Blob(base64: ${this.toBase64()})`; - } -} diff --git a/src/modules/firestore/CollectionReference.js b/src/modules/firestore/CollectionReference.js deleted file mode 100644 index a2f3bfcf..00000000 --- a/src/modules/firestore/CollectionReference.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @flow - * CollectionReference representation wrapper - */ -import Query from './Query'; -import DocumentReference from './DocumentReference'; -import { firestoreAutoId } from '../../utils'; - -import type Firestore from './'; -import type { - GetOptions, - MetadataChanges, - QueryDirection, - QueryOperator, -} from './firestoreTypes.flow'; -import type FieldPath from './FieldPath'; -import type Path from './Path'; -import type { Observer, ObserverOnError, ObserverOnNext } from './Query'; -import type QuerySnapshot from './QuerySnapshot'; - -/** - * @class CollectionReference - */ -export default class CollectionReference { - _collectionPath: Path; - - _firestore: Firestore; - - _query: Query; - - constructor(firestore: Firestore, collectionPath: Path) { - this._collectionPath = collectionPath; - this._firestore = firestore; - this._query = new Query(firestore, collectionPath); - } - - get firestore(): Firestore { - return this._firestore; - } - - get id(): string { - return this._collectionPath.id; - } - - get parent(): DocumentReference | null { - const parentPath = this._collectionPath.parent(); - return parentPath - ? new DocumentReference(this._firestore, parentPath) - : null; - } - - add(data: Object): Promise { - const documentRef = this.doc(); - return documentRef.set(data).then(() => Promise.resolve(documentRef)); - } - - doc(documentPath?: string): DocumentReference { - const newPath = documentPath || firestoreAutoId(); - - const path = this._collectionPath.child(newPath); - if (!path.isDocument) { - throw new Error('Argument "documentPath" must point to a document.'); - } - - return new DocumentReference(this._firestore, path); - } - - // From Query - endAt(...snapshotOrVarArgs: any[]): Query { - return this._query.endAt(snapshotOrVarArgs); - } - - endBefore(...snapshotOrVarArgs: any[]): Query { - return this._query.endBefore(snapshotOrVarArgs); - } - - get(options?: GetOptions): Promise { - return this._query.get(options); - } - - limit(limit: number): Query { - return this._query.limit(limit); - } - - onSnapshot( - optionsOrObserverOrOnNext: MetadataChanges | Observer | ObserverOnNext, - observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError - ): () => void { - return this._query.onSnapshot( - optionsOrObserverOrOnNext, - observerOrOnNextOrOnError, - onError - ); - } - - orderBy(fieldPath: string | FieldPath, directionStr?: QueryDirection): Query { - return this._query.orderBy(fieldPath, directionStr); - } - - startAfter(...snapshotOrVarArgs: any[]): Query { - return this._query.startAfter(snapshotOrVarArgs); - } - - startAt(...snapshotOrVarArgs: any[]): Query { - return this._query.startAt(snapshotOrVarArgs); - } - - where(fieldPath: string, opStr: QueryOperator, value: any): Query { - return this._query.where(fieldPath, opStr, value); - } -} diff --git a/src/modules/firestore/DocumentChange.js b/src/modules/firestore/DocumentChange.js deleted file mode 100644 index 32d61a27..00000000 --- a/src/modules/firestore/DocumentChange.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @flow - * DocumentChange representation wrapper - */ -import DocumentSnapshot from './DocumentSnapshot'; - -import type Firestore from './'; -import type { NativeDocumentChange } from './firestoreTypes.flow'; - -/** - * @class DocumentChange - */ -export default class DocumentChange { - _document: DocumentSnapshot; - - _newIndex: number; - - _oldIndex: number; - - _type: 'added' | 'modified' | 'removed'; - - constructor(firestore: Firestore, nativeData: NativeDocumentChange) { - this._document = new DocumentSnapshot(firestore, nativeData.document); - this._newIndex = nativeData.newIndex; - this._oldIndex = nativeData.oldIndex; - this._type = nativeData.type; - } - - get doc(): DocumentSnapshot { - return this._document; - } - - get newIndex(): number { - return this._newIndex; - } - - get oldIndex(): number { - return this._oldIndex; - } - - get type(): string { - return this._type; - } -} diff --git a/src/modules/firestore/DocumentReference.js b/src/modules/firestore/DocumentReference.js deleted file mode 100644 index 1c707e72..00000000 --- a/src/modules/firestore/DocumentReference.js +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @flow - * DocumentReference representation wrapper - */ -import SnapshotError from './SnapshotError'; -import DocumentSnapshot from './DocumentSnapshot'; -import CollectionReference from './CollectionReference'; -import { parseUpdateArgs } from './utils'; -import { buildNativeMap } from './utils/serialize'; -import { getNativeModule } from '../../utils/native'; -import { firestoreAutoId, isFunction, isObject } from '../../utils'; -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; - -import type Firestore from './'; -import type { - GetOptions, - MetadataChanges, - NativeDocumentSnapshot, - SetOptions, -} from './firestoreTypes.flow'; -import type Path from './Path'; -import type { NativeErrorResponse } from '../../common/commonTypes.flow'; - -type ObserverOnError = SnapshotError => void; -type ObserverOnNext = DocumentSnapshot => void; - -type Observer = { - error?: ObserverOnError, - next: ObserverOnNext, -}; - -/** - * @class DocumentReference - */ -export default class DocumentReference { - _documentPath: Path; - - _firestore: Firestore; - - constructor(firestore: Firestore, documentPath: Path) { - this._documentPath = documentPath; - this._firestore = firestore; - } - - get firestore(): Firestore { - return this._firestore; - } - - get id(): string { - return this._documentPath.id; - } - - get parent(): CollectionReference { - const parentPath = this._documentPath.parent(); - // $FlowExpectedError: parentPath can never be null - return new CollectionReference(this._firestore, parentPath); - } - - get path(): string { - return this._documentPath.relativeName; - } - - collection(collectionPath: string): CollectionReference { - const path = this._documentPath.child(collectionPath); - if (!path.isCollection) { - throw new Error('Argument "collectionPath" must point to a collection.'); - } - - return new CollectionReference(this._firestore, path); - } - - delete(): Promise { - return getNativeModule(this._firestore).documentDelete(this.path); - } - - get(options?: GetOptions): Promise { - if (options) { - if (!isObject(options)) { - return Promise.reject( - new Error( - 'DocumentReference.get failed: First argument must be an object.' - ) - ); - } - if ( - options.source && - (options.source !== 'default' && - options.source !== 'server' && - options.source !== 'cache') - ) { - return Promise.reject( - new Error( - 'DocumentReference.get failed: GetOptions.source must be one of `default`, `server` or `cache`.' - ) - ); - } - } - return getNativeModule(this._firestore) - .documentGet(this.path, options) - .then(result => new DocumentSnapshot(this._firestore, result)); - } - - onSnapshot( - optionsOrObserverOrOnNext: MetadataChanges | Observer | ObserverOnNext, - observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError - ) { - let observer: Observer; - let docListenOptions = {}; - // Called with: onNext, ?onError - if (isFunction(optionsOrObserverOrOnNext)) { - if (observerOrOnNextOrOnError && !isFunction(observerOrOnNextOrOnError)) { - throw new Error( - 'DocumentReference.onSnapshot failed: Second argument must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: optionsOrObserverOrOnNext, - error: observerOrOnNextOrOnError, - }; - } else if ( - optionsOrObserverOrOnNext && - isObject(optionsOrObserverOrOnNext) - ) { - // Called with: Observer - if (optionsOrObserverOrOnNext.next) { - if (isFunction(optionsOrObserverOrOnNext.next)) { - if ( - optionsOrObserverOrOnNext.error && - !isFunction(optionsOrObserverOrOnNext.error) - ) { - throw new Error( - 'DocumentReference.onSnapshot failed: Observer.error must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: optionsOrObserverOrOnNext.next, - error: optionsOrObserverOrOnNext.error, - }; - } else { - throw new Error( - 'DocumentReference.onSnapshot failed: Observer.next must be a valid function.' - ); - } - } else if ( - Object.prototype.hasOwnProperty.call( - optionsOrObserverOrOnNext, - 'includeMetadataChanges' - ) - ) { - docListenOptions = optionsOrObserverOrOnNext; - // Called with: Options, onNext, ?onError - if (isFunction(observerOrOnNextOrOnError)) { - if (onError && !isFunction(onError)) { - throw new Error( - 'DocumentReference.onSnapshot failed: Third argument must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: observerOrOnNextOrOnError, - error: onError, - }; - // Called with Options, Observer - } else if ( - observerOrOnNextOrOnError && - isObject(observerOrOnNextOrOnError) && - observerOrOnNextOrOnError.next - ) { - if (isFunction(observerOrOnNextOrOnError.next)) { - if ( - observerOrOnNextOrOnError.error && - !isFunction(observerOrOnNextOrOnError.error) - ) { - throw new Error( - 'DocumentReference.onSnapshot failed: Observer.error must be a valid function.' - ); - } - observer = { - next: observerOrOnNextOrOnError.next, - error: observerOrOnNextOrOnError.error, - }; - } else { - throw new Error( - 'DocumentReference.onSnapshot failed: Observer.next must be a valid function.' - ); - } - } else { - throw new Error( - 'DocumentReference.onSnapshot failed: Second argument must be a function or observer.' - ); - } - } else { - throw new Error( - 'DocumentReference.onSnapshot failed: First argument must be a function, observer or options.' - ); - } - } else { - throw new Error( - 'DocumentReference.onSnapshot failed: Called with invalid arguments.' - ); - } - const listenerId = firestoreAutoId(); - - const listener = (nativeDocumentSnapshot: NativeDocumentSnapshot) => { - const documentSnapshot = new DocumentSnapshot( - this.firestore, - nativeDocumentSnapshot - ); - observer.next(documentSnapshot); - }; - - // Listen to snapshot events - const snapshotSubscription = SharedEventEmitter.addListener( - getAppEventName(this._firestore, `onDocumentSnapshot:${listenerId}`), - listener - ); - - let unsubscribe: () => void; - - // listen for snapshot error events - const errorSubscription = SharedEventEmitter.addListener( - getAppEventName(this._firestore, `onDocumentSnapshotError:${listenerId}`), - (e: NativeErrorResponse) => { - if (unsubscribe) unsubscribe(); - const error = new SnapshotError(e); - if (observer.error) observer.error(error); - else this.firestore.log.error(error); - } - ); - - // Add the native listener - getNativeModule(this._firestore).documentOnSnapshot( - this.path, - listenerId, - docListenOptions - ); - - // return an unsubscribe method - unsubscribe = () => { - snapshotSubscription.remove(); - errorSubscription.remove(); - // cancel native listener - getNativeModule(this._firestore).documentOffSnapshot( - this.path, - listenerId - ); - }; - - return unsubscribe; - } - - set(data: Object, options?: SetOptions): Promise { - const nativeData = buildNativeMap(data); - return getNativeModule(this._firestore).documentSet( - this.path, - nativeData, - options - ); - } - - update(...args: any[]): Promise { - const data = parseUpdateArgs(args, 'DocumentReference.update'); - const nativeData = buildNativeMap(data); - return getNativeModule(this._firestore).documentUpdate( - this.path, - nativeData - ); - } -} diff --git a/src/modules/firestore/DocumentSnapshot.js b/src/modules/firestore/DocumentSnapshot.js deleted file mode 100644 index 5b75c1d8..00000000 --- a/src/modules/firestore/DocumentSnapshot.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @flow - * DocumentSnapshot representation wrapper - */ -import DocumentReference from './DocumentReference'; -import FieldPath from './FieldPath'; -import Path from './Path'; -import { isObject, deepGet } from '../../utils'; -import { parseNativeMap } from './utils/serialize'; - -import type Firestore from './'; -import type { - NativeDocumentSnapshot, - SnapshotMetadata, -} from './firestoreTypes.flow'; - -const extractFieldPathData = (data: Object | void, segments: string[]): any => { - if (!data || !isObject(data)) { - return undefined; - } - const pathValue = data[segments[0]]; - if (segments.length === 1) { - return pathValue; - } - return extractFieldPathData(pathValue, segments.slice(1)); -}; - -/** - * @class DocumentSnapshot - */ -export default class DocumentSnapshot { - _data: Object | void; - - _metadata: SnapshotMetadata; - - _ref: DocumentReference; - - constructor(firestore: Firestore, nativeData: NativeDocumentSnapshot) { - this._data = parseNativeMap(firestore, nativeData.data); - this._metadata = nativeData.metadata; - this._ref = new DocumentReference( - firestore, - Path.fromName(nativeData.path) - ); - } - - get exists(): boolean { - return this._data !== undefined; - } - - get id(): string { - return this._ref.id; - } - - get metadata(): SnapshotMetadata { - return this._metadata; - } - - get ref(): DocumentReference { - return this._ref; - } - - data = (): Object | void => this._data; - - get = (fieldPath: string | FieldPath): any => { - if (fieldPath instanceof FieldPath) { - return extractFieldPathData(this._data, fieldPath._segments); - } - - return deepGet(this._data, fieldPath, '.'); - }; -} diff --git a/src/modules/firestore/FieldPath.js b/src/modules/firestore/FieldPath.js deleted file mode 100644 index 202f3309..00000000 --- a/src/modules/firestore/FieldPath.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @flow - * FieldPath representation wrapper - */ - -/** - * @class FieldPath - */ -export default class FieldPath { - _segments: string[]; - - constructor(...segments: string[]) { - // TODO: Validation - this._segments = segments; - } - - static documentId(): FieldPath { - return DOCUMENT_ID; - } -} - -export const DOCUMENT_ID = new FieldPath('__name__'); diff --git a/src/modules/firestore/FieldValue.js b/src/modules/firestore/FieldValue.js deleted file mode 100644 index 390b309c..00000000 --- a/src/modules/firestore/FieldValue.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @flow - * FieldValue representation wrapper - */ -import AnyJs from './utils/any'; -import { buildNativeArray } from './utils/serialize'; - -// TODO: Salakar: Refactor in v6 -export default class FieldValue { - _type: string; - - _elements: AnyJs[] | any; - - constructor(type: string, elements?: AnyJs[]) { - this._type = type; - this._elements = elements; - } - - get type(): string { - return this._type; - } - - get elements(): AnyJs[] { - return this._elements; - } - - static delete(): FieldValue { - return new FieldValue(TypeFieldValueDelete); - } - - static serverTimestamp(): FieldValue { - return new FieldValue(TypeFieldValueTimestamp); - } - - static arrayUnion(...elements: AnyJs[]) { - // TODO Salakar: v6: validate elements, any primitive or FirestoreReference allowed - // TODO Salakar: v6: explicitly deny use of serverTimestamp - only allowed on set/update - // TODO Salakar: v6: explicitly deny use of nested arrays - not supported on sdk - return new FieldValue(TypeFieldValueUnion, buildNativeArray(elements)); - } - - static arrayRemove(...elements: AnyJs[]) { - // TODO Salakar: v6: validate elements, any primitive or FirestoreReference allowed - // TODO Salakar: v6: explicitly deny use of serverTimestamp - only allowed on set/update - // TODO Salakar: v6: explicitly deny use of nested arrays - not supported on sdk - return new FieldValue(TypeFieldValueRemove, buildNativeArray(elements)); - } -} - -export const TypeFieldValueDelete = 'delete'; -export const TypeFieldValueRemove = 'remove'; -export const TypeFieldValueUnion = 'union'; -export const TypeFieldValueTimestamp = 'timestamp'; diff --git a/src/modules/firestore/GeoPoint.js b/src/modules/firestore/GeoPoint.js deleted file mode 100644 index 9c31ef6c..00000000 --- a/src/modules/firestore/GeoPoint.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @flow - * GeoPoint representation wrapper - */ - -/** - * @class GeoPoint - */ -export default class GeoPoint { - _latitude: number; - - _longitude: number; - - constructor(latitude: number, longitude: number) { - // TODO: Validation - // validate.isNumber('latitude', latitude); - // validate.isNumber('longitude', longitude); - - this._latitude = latitude; - this._longitude = longitude; - } - - get latitude(): number { - return this._latitude; - } - - get longitude(): number { - return this._longitude; - } -} diff --git a/src/modules/firestore/Path.js b/src/modules/firestore/Path.js deleted file mode 100644 index cda33079..00000000 --- a/src/modules/firestore/Path.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @flow - * Path representation wrapper - */ - -/** - * @class Path - */ -export default class Path { - _parts: string[]; - - constructor(pathComponents: string[]) { - this._parts = pathComponents; - } - - get id(): string { - // TODO is length check required? - return this._parts.length ? this._parts[this._parts.length - 1] : ''; - } - - get isDocument(): boolean { - return this._parts.length % 2 === 0; - } - - get isCollection(): boolean { - return this._parts.length % 2 === 1; - } - - get relativeName(): string { - return this._parts.join('/'); - } - - child(relativePath: string): Path { - return new Path(this._parts.concat(relativePath.split('/'))); - } - - parent(): Path | null { - return this._parts.length > 1 - ? new Path(this._parts.slice(0, this._parts.length - 1)) - : null; - } - - /** - * - * @package - */ - static fromName(name: string): Path { - if (!name) return new Path([]); - const parts = name.split('/'); - return new Path(parts); - } -} diff --git a/src/modules/firestore/Query.js b/src/modules/firestore/Query.js deleted file mode 100644 index 0fce27d8..00000000 --- a/src/modules/firestore/Query.js +++ /dev/null @@ -1,481 +0,0 @@ -/** - * @flow - * Query representation wrapper - */ -import FieldPath from './FieldPath'; -import QuerySnapshot from './QuerySnapshot'; -import SnapshotError from './SnapshotError'; -import DocumentSnapshot from './DocumentSnapshot'; -import { getNativeModule } from '../../utils/native'; -import { buildNativeArray, buildTypeMap } from './utils/serialize'; -import { firestoreAutoId, isFunction, isObject } from '../../utils'; -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; - -import type Firestore from './'; -import type Path from './Path'; -import type { - MetadataChanges, - QueryDirection, - QueryOperator, - GetOptions, -} from './firestoreTypes.flow'; -import type { NativeErrorResponse } from '../../common/commonTypes.flow'; - -const DIRECTIONS: { [QueryDirection]: string } = { - ASC: 'ASCENDING', - asc: 'ASCENDING', - DESC: 'DESCENDING', - desc: 'DESCENDING', -}; - -const OPERATORS: { [QueryOperator]: string } = { - '=': 'EQUAL', - '==': 'EQUAL', - '>': 'GREATER_THAN', - '>=': 'GREATER_THAN_OR_EQUAL', - '<': 'LESS_THAN', - '<=': 'LESS_THAN_OR_EQUAL', - 'array-contains': 'ARRAY_CONTAINS', -}; - -type NativeFieldPath = {| - elements?: string[], - string?: string, - type: 'fieldpath' | 'string', -|}; - -type FieldFilter = {| - fieldPath: NativeFieldPath, - operator: string, - value: any, -|}; - -type FieldOrder = {| - direction: string, - fieldPath: NativeFieldPath, -|}; - -type QueryOptions = { - endAt?: any[], - endBefore?: any[], - limit?: number, - offset?: number, - selectFields?: string[], - startAfter?: any[], - startAt?: any[], -}; - -export type ObserverOnError = SnapshotError => void; -export type ObserverOnNext = QuerySnapshot => void; -export type Observer = { - error?: ObserverOnError, - next: ObserverOnNext, -}; - -function buildNativeFieldPath(fieldPath: string | FieldPath): NativeFieldPath { - if (fieldPath instanceof FieldPath) { - return { - elements: fieldPath._segments, - type: 'fieldpath', - }; - } - return { - string: fieldPath, - type: 'string', - }; -} - -/** - * @class Query - */ -export default class Query { - _fieldFilters: FieldFilter[]; - - _fieldOrders: FieldOrder[]; - - _firestore: Firestore; - - _iid: number; - - _queryOptions: QueryOptions; - - _referencePath: Path; - - constructor( - firestore: Firestore, - path: Path, - fieldFilters?: FieldFilter[], - fieldOrders?: FieldOrder[], - queryOptions?: QueryOptions - ) { - this._fieldFilters = fieldFilters || []; - this._fieldOrders = fieldOrders || []; - this._firestore = firestore; - this._queryOptions = queryOptions || {}; - this._referencePath = path; - } - - get firestore(): Firestore { - return this._firestore; - } - - endAt(...snapshotOrVarArgs: any[]): Query { - const options = { - ...this._queryOptions, - endAt: this._buildOrderByOption(snapshotOrVarArgs), - }; - - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - this._fieldOrders, - options - ); - } - - endBefore(...snapshotOrVarArgs: any[]): Query { - const options = { - ...this._queryOptions, - endBefore: this._buildOrderByOption(snapshotOrVarArgs), - }; - - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - this._fieldOrders, - options - ); - } - - get(options?: GetOptions): Promise { - if (options) { - if (!isObject(options)) { - return Promise.reject( - new Error('Query.get failed: First argument must be an object.') - ); - } - if ( - options.source && - (options.source !== 'default' && - options.source !== 'server' && - options.source !== 'cache') - ) { - return Promise.reject( - new Error( - 'Query.get failed: GetOptions.source must be one of `default`, `server` or `cache`.' - ) - ); - } - } - - return getNativeModule(this._firestore) - .collectionGet( - this._referencePath.relativeName, - this._fieldFilters, - this._fieldOrders, - this._queryOptions, - options - ) - .then(nativeData => new QuerySnapshot(this._firestore, this, nativeData)); - } - - limit(limit: number): Query { - // TODO: Validation - // validate.isInteger('n', n); - - const options = { - ...this._queryOptions, - limit, - }; - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - this._fieldOrders, - options - ); - } - - onSnapshot( - optionsOrObserverOrOnNext: MetadataChanges | Observer | ObserverOnNext, - observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError, - onError?: ObserverOnError - ) { - // TODO refactor this 💩 - let observer: Observer; - let metadataChanges = {}; - // Called with: onNext, ?onError - if (isFunction(optionsOrObserverOrOnNext)) { - if (observerOrOnNextOrOnError && !isFunction(observerOrOnNextOrOnError)) { - throw new Error( - 'Query.onSnapshot failed: Second argument must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: optionsOrObserverOrOnNext, - error: observerOrOnNextOrOnError, - }; - } else if ( - optionsOrObserverOrOnNext && - isObject(optionsOrObserverOrOnNext) - ) { - // Called with: Observer - if (optionsOrObserverOrOnNext.next) { - if (isFunction(optionsOrObserverOrOnNext.next)) { - if ( - optionsOrObserverOrOnNext.error && - !isFunction(optionsOrObserverOrOnNext.error) - ) { - throw new Error( - 'Query.onSnapshot failed: Observer.error must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: optionsOrObserverOrOnNext.next, - error: optionsOrObserverOrOnNext.error, - }; - } else { - throw new Error( - 'Query.onSnapshot failed: Observer.next must be a valid function.' - ); - } - } else if ( - Object.prototype.hasOwnProperty.call( - optionsOrObserverOrOnNext, - 'includeMetadataChanges' - ) - ) { - metadataChanges = optionsOrObserverOrOnNext; - // Called with: Options, onNext, ?onError - if (isFunction(observerOrOnNextOrOnError)) { - if (onError && !isFunction(onError)) { - throw new Error( - 'Query.onSnapshot failed: Third argument must be a valid function.' - ); - } - // $FlowExpectedError: Not coping with the overloaded method signature - observer = { - next: observerOrOnNextOrOnError, - error: onError, - }; - // Called with Options, Observer - } else if ( - observerOrOnNextOrOnError && - isObject(observerOrOnNextOrOnError) && - observerOrOnNextOrOnError.next - ) { - if (isFunction(observerOrOnNextOrOnError.next)) { - if ( - observerOrOnNextOrOnError.error && - !isFunction(observerOrOnNextOrOnError.error) - ) { - throw new Error( - 'Query.onSnapshot failed: Observer.error must be a valid function.' - ); - } - observer = { - next: observerOrOnNextOrOnError.next, - error: observerOrOnNextOrOnError.error, - }; - } else { - throw new Error( - 'Query.onSnapshot failed: Observer.next must be a valid function.' - ); - } - } else { - throw new Error( - 'Query.onSnapshot failed: Second argument must be a function or observer.' - ); - } - } else { - throw new Error( - 'Query.onSnapshot failed: First argument must be a function, observer or options.' - ); - } - } else { - throw new Error( - 'Query.onSnapshot failed: Called with invalid arguments.' - ); - } - const listenerId = firestoreAutoId(); - - const listener = nativeQuerySnapshot => { - const querySnapshot = new QuerySnapshot( - this._firestore, - this, - nativeQuerySnapshot - ); - observer.next(querySnapshot); - }; - - let unsubscribe: () => void; - - // Listen to snapshot events - const snapshotSubscription = SharedEventEmitter.addListener( - getAppEventName(this._firestore, `onQuerySnapshot:${listenerId}`), - listener - ); - - // listen for snapshot error events - const errorSubscription = SharedEventEmitter.addListener( - getAppEventName(this._firestore, `onQuerySnapshotError:${listenerId}`), - (e: NativeErrorResponse) => { - if (unsubscribe) unsubscribe(); - const error = new SnapshotError(e); - if (observer.error) observer.error(error); - else this.firestore.log.error(error); - } - ); - - // Add the native listener - getNativeModule(this._firestore).collectionOnSnapshot( - this._referencePath.relativeName, - this._fieldFilters, - this._fieldOrders, - this._queryOptions, - listenerId, - metadataChanges - ); - - // return an unsubscribe method - unsubscribe = () => { - snapshotSubscription.remove(); - errorSubscription.remove(); - // cancel native listener - getNativeModule(this._firestore).collectionOffSnapshot( - this._referencePath.relativeName, - this._fieldFilters, - this._fieldOrders, - this._queryOptions, - listenerId - ); - }; - - return unsubscribe; - } - - orderBy( - fieldPath: string | FieldPath, - directionStr?: QueryDirection = 'asc' - ): Query { - // TODO: Validation - // validate.isFieldPath('fieldPath', fieldPath); - // validate.isOptionalFieldOrder('directionStr', directionStr); - - if ( - this._queryOptions.startAt || - this._queryOptions.startAfter || - this._queryOptions.endAt || - this._queryOptions.endBefore - ) { - throw new Error( - 'Cannot specify an orderBy() constraint after calling ' + - 'startAt(), startAfter(), endBefore() or endAt().' - ); - } - - const newOrder: FieldOrder = { - direction: DIRECTIONS[directionStr], - fieldPath: buildNativeFieldPath(fieldPath), - }; - const combinedOrders = this._fieldOrders.concat(newOrder); - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - combinedOrders, - this._queryOptions - ); - } - - startAfter(...snapshotOrVarArgs: any[]): Query { - const options = { - ...this._queryOptions, - startAfter: this._buildOrderByOption(snapshotOrVarArgs), - }; - - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - this._fieldOrders, - options - ); - } - - startAt(...snapshotOrVarArgs: any[]): Query { - const options = { - ...this._queryOptions, - startAt: this._buildOrderByOption(snapshotOrVarArgs), - }; - - return new Query( - this.firestore, - this._referencePath, - this._fieldFilters, - this._fieldOrders, - options - ); - } - - where( - fieldPath: string | FieldPath, - opStr: QueryOperator, - value: any - ): Query { - // TODO: Validation - // validate.isFieldPath('fieldPath', fieldPath); - // validate.isFieldFilter('fieldFilter', opStr, value); - const nativeValue = buildTypeMap(value); - const newFilter: FieldFilter = { - fieldPath: buildNativeFieldPath(fieldPath), - operator: OPERATORS[opStr], - value: nativeValue, - }; - - const combinedFilters = this._fieldFilters.concat(newFilter); - return new Query( - this.firestore, - this._referencePath, - combinedFilters, - this._fieldOrders, - this._queryOptions - ); - } - - /** - * INTERNALS - */ - - _buildOrderByOption(snapshotOrVarArgs: any[]) { - // TODO: Validation - let values; - if ( - snapshotOrVarArgs.length === 1 && - snapshotOrVarArgs[0] instanceof DocumentSnapshot - ) { - const docSnapshot: DocumentSnapshot = snapshotOrVarArgs[0]; - values = []; - for (let i = 0; i < this._fieldOrders.length; i++) { - const fieldOrder = this._fieldOrders[i]; - if ( - fieldOrder.fieldPath.type === 'string' && - fieldOrder.fieldPath.string - ) { - values.push(docSnapshot.get(fieldOrder.fieldPath.string)); - } else if (fieldOrder.fieldPath.elements) { - const fieldPath = new FieldPath(...fieldOrder.fieldPath.elements); - values.push(docSnapshot.get(fieldPath)); - } - } - } else { - values = snapshotOrVarArgs; - } - - return buildNativeArray(values); - } -} diff --git a/src/modules/firestore/QuerySnapshot.js b/src/modules/firestore/QuerySnapshot.js deleted file mode 100644 index ffeebe13..00000000 --- a/src/modules/firestore/QuerySnapshot.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @flow - * QuerySnapshot representation wrapper - */ -import DocumentChange from './DocumentChange'; -import DocumentSnapshot from './DocumentSnapshot'; - -import type Firestore from './'; -import type { - NativeDocumentChange, - NativeDocumentSnapshot, - SnapshotMetadata, -} from './firestoreTypes.flow'; -import type Query from './Query'; - -type NativeQuerySnapshot = { - changes: NativeDocumentChange[], - documents: NativeDocumentSnapshot[], - metadata: SnapshotMetadata, -}; - -/** - * @class QuerySnapshot - */ -export default class QuerySnapshot { - _changes: DocumentChange[]; - - _docs: DocumentSnapshot[]; - - _metadata: SnapshotMetadata; - - _query: Query; - - constructor( - firestore: Firestore, - query: Query, - nativeData: NativeQuerySnapshot - ) { - this._changes = nativeData.changes.map( - change => new DocumentChange(firestore, change) - ); - this._docs = nativeData.documents.map( - doc => new DocumentSnapshot(firestore, doc) - ); - this._metadata = nativeData.metadata; - this._query = query; - } - - get docChanges(): DocumentChange[] { - return this._changes; - } - - get docs(): DocumentSnapshot[] { - return this._docs; - } - - get empty(): boolean { - return this._docs.length === 0; - } - - get metadata(): SnapshotMetadata { - return this._metadata; - } - - get query(): Query { - return this._query; - } - - get size(): number { - return this._docs.length; - } - - forEach(callback: DocumentSnapshot => any) { - // TODO: Validation - // validate.isFunction('callback', callback); - - this._docs.forEach(doc => { - callback(doc); - }); - } -} diff --git a/src/modules/firestore/SnapshotError.js b/src/modules/firestore/SnapshotError.js deleted file mode 100644 index 105574d5..00000000 --- a/src/modules/firestore/SnapshotError.js +++ /dev/null @@ -1,12 +0,0 @@ -import NativeError from '../../common/NativeError'; -import type { SnapshotErrorInterface } from './firestoreTypes.flow'; -import type { NativeErrorResponse } from '../../common/commonTypes.flow'; - -export default class SnapshotError extends NativeError - implements SnapshotErrorInterface { - constructor(nativeErrorMap: NativeErrorResponse) { - super(nativeErrorMap.error); - this.path = nativeErrorMap.path; - this.appName = nativeErrorMap.appName; - } -} diff --git a/src/modules/firestore/Transaction.js b/src/modules/firestore/Transaction.js deleted file mode 100644 index 0f96640a..00000000 --- a/src/modules/firestore/Transaction.js +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @flow - * Firestore Transaction representation wrapper - */ -import { parseUpdateArgs } from './utils'; -import { buildNativeMap } from './utils/serialize'; - -import type Firestore from './'; -import type { TransactionMeta } from './TransactionHandler'; -import type DocumentReference from './DocumentReference'; -import DocumentSnapshot from './DocumentSnapshot'; -import { getNativeModule } from '../../utils/native'; - -type Command = { - type: 'set' | 'update' | 'delete', - path: string, - data?: { [string]: any }, - options?: SetOptions | {}, -}; - -type SetOptions = { - merge: boolean, -}; - -// TODO docs state all get requests must be made FIRST before any modifications -// TODO so need to validate that - -/** - * @class Transaction - */ -export default class Transaction { - _pendingResult: ?any; - - _firestore: Firestore; - - _meta: TransactionMeta; - - _commandBuffer: Array; - - constructor(firestore: Firestore, meta: TransactionMeta) { - this._meta = meta; - this._commandBuffer = []; - this._firestore = firestore; - this._pendingResult = undefined; - } - - /** - * ------------- - * INTERNAL API - * ------------- - */ - - /** - * Clears the command buffer and any pending result in prep for - * the next transaction iteration attempt. - * - * @private - */ - _prepare() { - this._commandBuffer = []; - this._pendingResult = undefined; - } - - /** - * ------------- - * PUBLIC API - * ------------- - */ - - /** - * Reads the document referenced by the provided DocumentReference. - * - * @param documentRef DocumentReference A reference to the document to be retrieved. Value must not be null. - * - * @returns Promise - */ - get(documentRef: DocumentReference): Promise { - // todo validate doc ref - return getNativeModule(this._firestore) - .transactionGetDocument(this._meta.id, documentRef.path) - .then(result => new DocumentSnapshot(this._firestore, result)); - } - - /** - * Writes to the document referred to by the provided DocumentReference. - * If the document does not exist yet, it will be created. If you pass options, - * the provided data can be merged into the existing document. - * - * @param documentRef DocumentReference A reference to the document to be created. Value must not be null. - * @param data Object An object of the fields and values for the document. - * @param options SetOptions An object to configure the set behavior. - * Pass {merge: true} to only replace the values specified in the data argument. - * Fields omitted will remain untouched. - * - * @returns {Transaction} - */ - set( - documentRef: DocumentReference, - data: Object, - options?: SetOptions - ): Transaction { - // todo validate doc ref - // todo validate data is object - this._commandBuffer.push({ - type: 'set', - path: documentRef.path, - data: buildNativeMap(data), - options: options || {}, - }); - - return this; - } - - /** - * Updates fields in the document referred to by this DocumentReference. - * The update will fail if applied to a document that does not exist. Nested - * fields can be updated by providing dot-separated field path strings or by providing FieldPath objects. - * - * @param documentRef DocumentReference A reference to the document to be updated. Value must not be null. - * @param args any Either an object containing all of the fields and values to update, - * or a series of arguments alternating between fields (as string or FieldPath - * objects) and values. - * - * @returns {Transaction} - */ - update(documentRef: DocumentReference, ...args: Array): Transaction { - // todo validate doc ref - const data = parseUpdateArgs(args, 'Transaction.update'); - this._commandBuffer.push({ - type: 'update', - path: documentRef.path, - data: buildNativeMap(data), - }); - - return this; - } - - /** - * Deletes the document referred to by the provided DocumentReference. - * - * @param documentRef DocumentReference A reference to the document to be deleted. Value must not be null. - * - * @returns {Transaction} - */ - delete(documentRef: DocumentReference): Transaction { - // todo validate doc ref - this._commandBuffer.push({ - type: 'delete', - path: documentRef.path, - }); - - return this; - } -} diff --git a/src/modules/firestore/TransactionHandler.js b/src/modules/firestore/TransactionHandler.js deleted file mode 100644 index 624acf0a..00000000 --- a/src/modules/firestore/TransactionHandler.js +++ /dev/null @@ -1,242 +0,0 @@ -/** - * @flow - * Firestore Transaction representation wrapper - */ -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; -import { getNativeModule } from '../../utils/native'; -import Transaction from './Transaction'; -import type Firestore from './'; - -let transactionId = 0; - -/** - * Uses the push id generator to create a transaction id - * @returns {number} - * @private - */ -const generateTransactionId = (): number => transactionId++; - -export type TransactionMeta = { - id: number, - stack: string[], - reject?: Function, - resolve?: Function, - transaction: Transaction, - updateFunction: (transaction: Transaction) => Promise, -}; - -type TransactionEvent = { - id: number, - type: 'update' | 'error' | 'complete', - error: ?{ code: string, message: string }, -}; - -/** - * @class TransactionHandler - */ -export default class TransactionHandler { - _firestore: Firestore; - - _pending: { - [number]: { - meta: TransactionMeta, - transaction: Transaction, - }, - }; - - constructor(firestore: Firestore) { - this._pending = {}; - this._firestore = firestore; - SharedEventEmitter.addListener( - getAppEventName(this._firestore, 'firestore_transaction_event'), - this._handleTransactionEvent.bind(this) - ); - } - - /** - * ------------- - * INTERNAL API - * ------------- - */ - - /** - * Add a new transaction and start it natively. - * @param updateFunction - */ - _add( - updateFunction: (transaction: Transaction) => Promise - ): Promise { - const id = generateTransactionId(); - // $FlowExpectedError: Transaction has to be populated - const meta: TransactionMeta = { - id, - updateFunction, - stack: new Error().stack - .split('\n') - .slice(2) - .join('\n'), - }; - - this._pending[id] = { - meta, - transaction: new Transaction(this._firestore, meta), - }; - - // deferred promise - return new Promise((resolve, reject) => { - getNativeModule(this._firestore).transactionBegin(id); - meta.resolve = r => { - resolve(r); - this._remove(id); - }; - meta.reject = e => { - reject(e); - this._remove(id); - }; - }); - } - - /** - * Destroys a local instance of a transaction meta - * - * @param id - * @private - */ - _remove(id) { - getNativeModule(this._firestore).transactionDispose(id); - delete this._pending[id]; - } - - /** - * ------------- - * EVENTS - * ------------- - */ - - /** - * Handles incoming native transaction events and distributes to correct - * internal handler by event.type - * - * @param event - * @returns {*} - * @private - */ - _handleTransactionEvent(event: TransactionEvent) { - // eslint-disable-next-line default-case - switch (event.type) { - case 'update': - this._handleUpdate(event); - break; - case 'error': - this._handleError(event); - break; - case 'complete': - this._handleComplete(event); - break; - } - } - - /** - * Handles incoming native transaction update events - * - * @param event - * @private - */ - async _handleUpdate(event: TransactionEvent) { - const { id } = event; - // abort if no longer exists js side - if (!this._pending[id]) return this._remove(id); - - const { meta, transaction } = this._pending[id]; - const { updateFunction, reject } = meta; - - // clear any saved state from previous transaction runs - transaction._prepare(); - - let finalError; - let updateFailed; - let pendingResult; - - // run the users custom update functionality - try { - const possiblePromise = updateFunction(transaction); - - // validate user has returned a promise in their update function - // TODO must it actually return a promise? Can't find any usages of it without one... - if (!possiblePromise || !possiblePromise.then) { - finalError = new Error( - 'Update function for `firestore.runTransaction(updateFunction)` must return a Promise.' - ); - } else { - pendingResult = await possiblePromise; - } - } catch (exception) { - // exception can still be falsey if user `Promise.reject();` 's with no args - // so we track the exception with a updateFailed boolean to ensure no fall-through - updateFailed = true; - finalError = exception; - } - - // reject the final promise and remove from native - // update is failed when either the users updateFunction - // throws an error or rejects a promise - if (updateFailed || finalError) { - // $FlowExpectedError: Reject will always be present - return reject(finalError); - } - - // capture the resolved result as we'll need this - // to resolve the runTransaction() promise when - // native emits that the transaction is final - transaction._pendingResult = pendingResult; - - // send the buffered update/set/delete commands for native to process - return getNativeModule(this._firestore).transactionApplyBuffer( - id, - transaction._commandBuffer - ); - } - - /** - * Handles incoming native transaction error events - * - * @param event - * @private - */ - _handleError(event: TransactionEvent) { - const { id, error } = event; - const { meta } = this._pending[id]; - - if (meta && error) { - const { code, message } = error; - // build a JS error and replace its stack - // with the captured one at start of transaction - // so it's actually relevant to the user - const errorWithStack = new Error(message); - // $FlowExpectedError: code is needed for Firebase errors - errorWithStack.code = code; - // $FlowExpectedError: stack should be a stack trace - errorWithStack.stack = `Error: ${message}\n${meta.stack}`; - - // $FlowExpectedError: Reject will always be present - meta.reject(errorWithStack); - } - } - - /** - * Handles incoming native transaction complete events - * - * @param event - * @private - */ - _handleComplete(event: TransactionEvent) { - const { id } = event; - const { meta, transaction } = this._pending[id]; - - if (meta) { - const pendingResult = transaction._pendingResult; - // $FlowExpectedError: Resolve will always be present - meta.resolve(pendingResult); - } - } -} diff --git a/src/modules/firestore/WriteBatch.js b/src/modules/firestore/WriteBatch.js deleted file mode 100644 index 01f827eb..00000000 --- a/src/modules/firestore/WriteBatch.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @flow - * WriteBatch representation wrapper - */ -import { parseUpdateArgs } from './utils'; -import { buildNativeMap } from './utils/serialize'; -import { getNativeModule } from '../../utils/native'; - -import type DocumentReference from './DocumentReference'; -import type Firestore from './'; -import type { SetOptions } from './firestoreTypes.flow'; - -type DocumentWrite = { - data?: Object, - options?: Object, - path: string, - type: 'DELETE' | 'SET' | 'UPDATE', -}; - -/** - * @class WriteBatch - */ -export default class WriteBatch { - _firestore: Firestore; - - _writes: DocumentWrite[]; - - constructor(firestore: Firestore) { - this._firestore = firestore; - this._writes = []; - } - - commit(): Promise { - return getNativeModule(this._firestore).documentBatch(this._writes); - } - - delete(docRef: DocumentReference): WriteBatch { - // TODO: Validation - // validate.isDocumentReference('docRef', docRef); - // validate.isOptionalPrecondition('deleteOptions', deleteOptions); - this._writes.push({ - path: docRef.path, - type: 'DELETE', - }); - - return this; - } - - set(docRef: DocumentReference, data: Object, options?: SetOptions) { - // TODO: Validation - // validate.isDocumentReference('docRef', docRef); - // validate.isDocument('data', data); - // validate.isOptionalPrecondition('options', writeOptions); - const nativeData = buildNativeMap(data); - this._writes.push({ - data: nativeData, - options, - path: docRef.path, - type: 'SET', - }); - - return this; - } - - update(docRef: DocumentReference, ...args: any[]): WriteBatch { - // TODO: Validation - // validate.isDocumentReference('docRef', docRef); - const data = parseUpdateArgs(args, 'WriteBatch.update'); - this._writes.push({ - data: buildNativeMap(data), - path: docRef.path, - type: 'UPDATE', - }); - - return this; - } -} diff --git a/src/modules/firestore/firestoreTypes.flow.js b/src/modules/firestore/firestoreTypes.flow.js deleted file mode 100644 index 22276a2a..00000000 --- a/src/modules/firestore/firestoreTypes.flow.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * @flow - */ -import type { NativeErrorInterface } from '../../common/commonTypes.flow'; - -export type MetadataChanges = {| - includeMetadataChanges: boolean, -|}; - -export type QueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc'; - -export type QueryOperator = - | '<' - | '<=' - | '=' - | '==' - | '>' - | '>=' - | 'array-contains'; - -export type GetOptions = { - source: 'default' | 'server' | 'cache', -}; - -export type SetOptions = { - merge?: boolean, -}; - -export type SnapshotMetadata = { - fromCache: boolean, - hasPendingWrites: boolean, -}; - -export type NativeDocumentChange = { - document: NativeDocumentSnapshot, - newIndex: number, - oldIndex: number, - type: 'added' | 'modified' | 'removed', -}; - -export type NativeDocumentSnapshot = { - data: { [string]: NativeTypeMap }, - metadata: SnapshotMetadata, - path: string, -}; - -export type NativeTypeMap = { - type: - | 'nan' - | 'infinity' - | 'array' - | 'boolean' - | 'date' - | 'blob' - | 'documentid' - | 'fieldvalue' - | 'geopoint' - | 'null' - | 'number' - | 'object' - | 'reference' - | 'string', - value: any, -}; - -export interface SnapshotErrorInterface extends NativeErrorInterface { - +path: string; - +appName: string; -} diff --git a/src/modules/firestore/index.js b/src/modules/firestore/index.js deleted file mode 100644 index e17489a6..00000000 --- a/src/modules/firestore/index.js +++ /dev/null @@ -1,282 +0,0 @@ -/** - * @flow - * Firestore representation wrapper - */ -import { NativeModules } from 'react-native'; - -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; -import ModuleBase from '../../utils/ModuleBase'; -import CollectionReference from './CollectionReference'; -import DocumentReference from './DocumentReference'; -import FieldPath from './FieldPath'; -import FieldValue from './FieldValue'; -import GeoPoint from './GeoPoint'; -import Blob from './Blob'; -import Path from './Path'; -import WriteBatch from './WriteBatch'; -import TransactionHandler from './TransactionHandler'; -import Transaction from './Transaction'; -import { isBoolean, isObject, isString, hop } from '../../utils'; -import { getNativeModule } from '../../utils/native'; - -import type DocumentSnapshot from './DocumentSnapshot'; -import type App from '../core/app'; -import type QuerySnapshot from './QuerySnapshot'; - -type CollectionSyncEvent = { - appName: string, - querySnapshot?: QuerySnapshot, - error?: Object, - listenerId: string, - path: string, -}; - -type DocumentSyncEvent = { - appName: string, - documentSnapshot?: DocumentSnapshot, - error?: Object, - listenerId: string, - path: string, -}; - -type Settings = { - host?: string, - persistence?: boolean, - ssl?: boolean, - timestampsInSnapshots?: boolean, -}; - -const NATIVE_EVENTS = [ - 'firestore_transaction_event', - 'firestore_document_sync_event', - 'firestore_collection_sync_event', -]; - -const LogLevels = ['debug', 'error', 'silent']; - -export const MODULE_NAME = 'RNFirebaseFirestore'; -export const NAMESPACE = 'firestore'; - -/** - * @class Firestore - */ -export default class Firestore extends ModuleBase { - _referencePath: Path; - - _transactionHandler: TransactionHandler; - - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: true, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - - this._referencePath = new Path([]); - this._transactionHandler = new TransactionHandler(this); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onCollectionSnapshot - getAppEventName(this, 'firestore_collection_sync_event'), - this._onCollectionSyncEvent.bind(this) - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onDocumentSnapshot - getAppEventName(this, 'firestore_document_sync_event'), - this._onDocumentSyncEvent.bind(this) - ); - } - - /** - * ------------- - * PUBLIC API - * ------------- - */ - - /** - * Creates a write batch, used for performing multiple writes as a single atomic operation. - * - * @returns {WriteBatch} - */ - batch(): WriteBatch { - return new WriteBatch(this); - } - - /** - * Gets a CollectionReference instance that refers to the collection at the specified path. - * - * @param collectionPath - * @returns {CollectionReference} - */ - collection(collectionPath: string): CollectionReference { - const path = this._referencePath.child(collectionPath); - if (!path.isCollection) { - throw new Error('Argument "collectionPath" must point to a collection.'); - } - - return new CollectionReference(this, path); - } - - disableNetwork(): void { - return getNativeModule(this).disableNetwork(); - } - - /** - * Gets a DocumentReference instance that refers to the document at the specified path. - * - * @param documentPath - * @returns {DocumentReference} - */ - doc(documentPath: string): DocumentReference { - const path = this._referencePath.child(documentPath); - if (!path.isDocument) { - throw new Error('Argument "documentPath" must point to a document.'); - } - - return new DocumentReference(this, path); - } - - enableNetwork(): Promise { - return getNativeModule(this).enableNetwork(); - } - - /** - * Executes the given updateFunction and then attempts to commit the - * changes applied within the transaction. If any document read within - * the transaction has changed, Cloud Firestore retries the updateFunction. - * - * If it fails to commit after 5 attempts, the transaction fails. - * - * @param updateFunction - * @returns {void|Promise} - */ - runTransaction( - updateFunction: (transaction: Transaction) => Promise - ): Promise { - return this._transactionHandler._add(updateFunction); - } - - settings(settings: Settings): Promise { - if (!isObject(settings)) { - return Promise.reject( - new Error('Firestore.settings failed: settings must be an object.') - ); - } - if (hop(settings, 'host') && !isString(settings.host)) { - return Promise.reject( - new Error('Firestore.settings failed: settings.host must be a string.') - ); - } - if (hop(settings, 'persistence') && !isBoolean(settings.persistence)) { - return Promise.reject( - new Error( - 'Firestore.settings failed: settings.persistence must be boolean.' - ) - ); - } - if (hop(settings, 'ssl') && !isBoolean(settings.ssl)) { - return Promise.reject( - new Error('Firestore.settings failed: settings.ssl must be boolean.') - ); - } - if ( - hop(settings, 'timestampsInSnapshots') && - !isBoolean(settings.timestampsInSnapshots) - ) { - return Promise.reject( - new Error( - 'Firestore.settings failed: settings.timestampsInSnapshots must be boolean.' - ) - ); - } - return getNativeModule(this).settings(settings); - } - - /** - * ------------- - * UNSUPPORTED - * ------------- - */ - - enablePersistence(): Promise { - console.warn( - 'Due to restrictions in the native SDK, persistence must be configured in firebase.firestore().settings()' - ); - return Promise.resolve(); - } - - /** - * ------------- - * INTERNALS - * ------------- - */ - - /** - * Internal collection sync listener - * - * @param event - * @private - */ - _onCollectionSyncEvent(event: CollectionSyncEvent) { - if (event.error) { - SharedEventEmitter.emit( - getAppEventName(this, `onQuerySnapshotError:${event.listenerId}`), - event - ); - } else { - SharedEventEmitter.emit( - getAppEventName(this, `onQuerySnapshot:${event.listenerId}`), - event.querySnapshot - ); - } - } - - /** - * Internal document sync listener - * - * @param event - * @private - */ - _onDocumentSyncEvent(event: DocumentSyncEvent) { - if (event.error) { - SharedEventEmitter.emit( - getAppEventName(this, `onDocumentSnapshotError:${event.listenerId}`), - event - ); - } else { - SharedEventEmitter.emit( - getAppEventName(this, `onDocumentSnapshot:${event.listenerId}`), - event.documentSnapshot - ); - } - } -} - -export const statics = { - Blob, - FieldPath, - FieldValue, - GeoPoint, - enableLogging(enabled: boolean): void { - // DEPRECATED: Remove method in v4.1.0 - console.warn( - 'firebase.firestore.enableLogging is deprecated, use firebase.firestore().setLogLevel instead.' - ); - this.setLogLevel(enabled ? 'debug' : 'silent'); - }, - setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void { - if (LogLevels.indexOf(logLevel) === -1) { - throw new Error( - 'Argument `logLevel` must be one of: `debug`, `error`, `silent`' - ); - } - if (NativeModules[MODULE_NAME]) { - NativeModules[MODULE_NAME].setLogLevel(logLevel); - } - }, -}; diff --git a/src/modules/firestore/utils/any.js b/src/modules/firestore/utils/any.js deleted file mode 100644 index af9d484d..00000000 --- a/src/modules/firestore/utils/any.js +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @url https://github.com/firebase/firebase-js-sdk/blob/master/packages/firestore/src/util/misc.ts#L26 - */ -export type AnyJs = null | undefined | boolean | number | string | object; diff --git a/src/modules/firestore/utils/index.js b/src/modules/firestore/utils/index.js deleted file mode 100644 index bafb1966..00000000 --- a/src/modules/firestore/utils/index.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @flow - */ -import FieldPath from '../FieldPath'; -import { isObject, isString } from '../../../utils'; - -const buildFieldPathData = (segments: string[], value: any): Object => { - if (segments.length === 1) { - return { - [segments[0]]: value, - }; - } - return { - [segments[0]]: buildFieldPathData(segments.slice(1), value), - }; -}; - -// eslint-disable-next-line import/prefer-default-export -export const mergeFieldPathData = ( - data: Object, - segments: string[], - value: any -): Object => { - if (segments.length === 1) { - return { - ...data, - [segments[0]]: value, - }; - } - if (data[segments[0]]) { - return { - ...data, - [segments[0]]: mergeFieldPathData( - data[segments[0]], - segments.slice(1), - value - ), - }; - } - return { - ...data, - [segments[0]]: buildFieldPathData(segments.slice(1), value), - }; -}; - -export const parseUpdateArgs = (args: any[], methodName: string) => { - let data = {}; - if (args.length === 1) { - if (!isObject(args[0])) { - throw new Error( - `${methodName} failed: If using a single update argument, it must be an object.` - ); - } - [data] = args; - } else if (args.length % 2 === 1) { - throw new Error( - `${methodName} failed: The update arguments must be either a single object argument, or equal numbers of key/value pairs.` - ); - } else { - for (let i = 0; i < args.length; i += 2) { - const key = args[i]; - const value = args[i + 1]; - if (isString(key)) { - data[key] = value; - } else if (key instanceof FieldPath) { - data = mergeFieldPathData(data, key._segments, value); - } else { - throw new Error( - `${methodName} failed: Argument at index ${i} must be a string or FieldPath` - ); - } - } - } - return data; -}; diff --git a/src/modules/firestore/utils/serialize.js b/src/modules/firestore/utils/serialize.js deleted file mode 100644 index 77e9fc5a..00000000 --- a/src/modules/firestore/utils/serialize.js +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @flow - */ - -import DocumentReference from '../DocumentReference'; -import Blob from '../Blob'; -import { DOCUMENT_ID } from '../FieldPath'; -import FieldValue from '../FieldValue'; -import GeoPoint from '../GeoPoint'; -import Path from '../Path'; -import { typeOf } from '../../../utils'; - -import type Firestore from '..'; -import type { NativeTypeMap } from '../firestoreTypes.flow'; - -/* - * Functions that build up the data needed to represent - * the different types available within Firestore - * for transmission to the native side - */ - -export const buildNativeMap = (data: Object): { [string]: NativeTypeMap } => { - const nativeData = {}; - if (data) { - Object.keys(data).forEach(key => { - const typeMap = buildTypeMap(data[key]); - if (typeMap) { - nativeData[key] = typeMap; - } - }); - } - return nativeData; -}; - -export const buildNativeArray = (array: Object[]): NativeTypeMap[] => { - const nativeArray = []; - if (array) { - array.forEach(value => { - const typeMap = buildTypeMap(value); - if (typeMap) { - nativeArray.push(typeMap); - } - }); - } - return nativeArray; -}; - -export const buildTypeMap = (value: any): NativeTypeMap | null => { - const type = typeOf(value); - - if (Number.isNaN(value)) { - return { - type: 'nan', - value: null, - }; - } - - if (value === Infinity) { - return { - type: 'infinity', - value: null, - }; - } - - if (value === null || value === undefined) { - return { - type: 'null', - value: null, - }; - } - - if (value === DOCUMENT_ID) { - return { - type: 'documentid', - value: null, - }; - } - - if (type === 'boolean' || type === 'number' || type === 'string') { - return { - type, - value, - }; - } - - if (type === 'array') { - return { - type, - value: buildNativeArray(value), - }; - } - - if (type === 'object') { - if (value instanceof DocumentReference) { - return { - type: 'reference', - value: value.path, - }; - } - - if (value instanceof GeoPoint) { - return { - type: 'geopoint', - value: { - latitude: value.latitude, - longitude: value.longitude, - }, - }; - } - - if (value instanceof Date) { - return { - type: 'date', - value: value.getTime(), - }; - } - - if (value instanceof Blob) { - return { - type: 'blob', - value: value.toBase64(), - }; - } - - // TODO: Salakar: Refactor in v6 - add internal `type` flag - if (value instanceof FieldValue) { - return { - type: 'fieldvalue', - value: { - elements: value.elements, - type: value.type, - }, - }; - } - - return { - type: 'object', - value: buildNativeMap(value), - }; - } - - console.warn(`Unknown data type received ${type}`); - return null; -}; - -/* - * Functions that parse the received from the native - * side and converts to the correct Firestore JS types - */ - -export const parseNativeMap = ( - firestore: Firestore, - nativeData: { [string]: NativeTypeMap } -): Object | void => { - let data; - if (nativeData) { - data = {}; - Object.keys(nativeData).forEach(key => { - data[key] = parseTypeMap(firestore, nativeData[key]); - }); - } - return data; -}; - -const parseNativeArray = ( - firestore: Firestore, - nativeArray: NativeTypeMap[] -): any[] => { - const array = []; - if (nativeArray) { - nativeArray.forEach(typeMap => { - array.push(parseTypeMap(firestore, typeMap)); - }); - } - return array; -}; - -const parseTypeMap = (firestore: Firestore, typeMap: NativeTypeMap): any => { - const { type, value } = typeMap; - if (type === 'null') { - return null; - } - - if (type === 'boolean' || type === 'number' || type === 'string') { - return value; - } - - if (type === 'array') { - return parseNativeArray(firestore, value); - } - - if (type === 'object') { - return parseNativeMap(firestore, value); - } - - if (type === 'reference') { - return new DocumentReference(firestore, Path.fromName(value)); - } - - if (type === 'geopoint') { - return new GeoPoint(value.latitude, value.longitude); - } - - if (type === 'date') { - return new Date(value); - } - - if (type === 'blob') { - return Blob.fromBase64String(value); - } - - if (type === 'infinity') { - return Infinity; - } - - if (type === 'nan') { - return NaN; - } - - console.warn(`Unknown data type received ${type}`); - return value; -}; diff --git a/src/modules/functions/HttpsError.js b/src/modules/functions/HttpsError.js deleted file mode 100644 index e2c7ed3f..00000000 --- a/src/modules/functions/HttpsError.js +++ /dev/null @@ -1,16 +0,0 @@ -import type { FunctionsErrorCode } from './types.flow'; - -export default class HttpsError extends Error { - +details: ?any; - - +message: string; - - +code: FunctionsErrorCode; - - constructor(code: FunctionsErrorCode, message?: string, details?: any) { - super(message); - this.code = code; - this.details = details; - this.message = message; - } -} diff --git a/src/modules/functions/index.js b/src/modules/functions/index.js deleted file mode 100644 index 24256f3f..00000000 --- a/src/modules/functions/index.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @flow - * Functions representation wrapper - */ -import ModuleBase from '../../utils/ModuleBase'; -import { isObject } from '../../utils'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; -import firebase from '../core/firebase'; - -import HttpsError from './HttpsError'; - -import type { - HttpsCallable, - HttpsErrorCode, - HttpsCallablePromise, -} from './types.flow'; - -export const NAMESPACE = 'functions'; -export const MODULE_NAME = 'RNFirebaseFunctions'; - -/** - * ------------- - * INTERNALS - * ------------- - */ -function errorOrResult(possibleError): HttpsCallablePromise { - if (isObject(possibleError) && possibleError.__error) { - const { code, message, details } = possibleError; - return Promise.reject( - new HttpsError( - statics.HttpsErrorCode[code] || statics.HttpsErrorCode.UNKNOWN, - message, - details - ) - ); - } - - return Promise.resolve(possibleError); -} - -/** - * ------------- - * functions() - * ------------- - */ -export default class Functions extends ModuleBase { - constructor(appOrRegion: App, region?: string) { - let _app = appOrRegion; - let _region = region || 'us-central1'; - - if (typeof _app === 'string') { - _region = _app; - _app = firebase.app(); - } - - super( - _app, - { - hasMultiAppSupport: true, - hasCustomUrlSupport: false, - hasRegionsSupport: true, - namespace: NAMESPACE, - moduleName: MODULE_NAME, - }, - _region - ); - } - - /** - * ------------- - * PUBLIC API - * ------------- - */ - - /** - * Returns a reference to the callable https trigger with the given name. - * @param name The name of the trigger. - */ - httpsCallable(name: string): HttpsCallable { - return (data?: any): HttpsCallablePromise => { - const promise = getNativeModule(this).httpsCallable(name, { - data, - }); - - return promise.then(errorOrResult); - }; - } - - /** - * Changes this instance to point to a Cloud Functions emulator running - * locally. - * - * See https://firebase.google.com/docs/functions/local-emulator - * - * @param origin the origin string of the local emulator started via firebase tools - * "http://10.0.0.8:1337". - */ - useFunctionsEmulator(origin: string): Promise { - return getNativeModule(this).useFunctionsEmulator(origin); - } -} - -export const statics: { HttpsErrorCode: HttpsErrorCode } = { - HttpsErrorCode: { - OK: 'ok', - CANCELLED: 'cancelled', - UNKNOWN: 'unknown', - INVALID_ARGUMENT: 'invalid-argument', - DEADLINE_EXCEEDED: 'deadline-exceeded', - NOT_FOUND: 'not-found', - ALREADY_EXISTS: 'already-exists', - PERMISSION_DENIED: 'permission-denied', - UNAUTHENTICATED: 'unauthenticated', - RESOURCE_EXHAUSTED: 'resource-exhausted', - FAILED_PRECONDITION: 'failed-precondition', - ABORTED: 'aborted', - OUT_OF_RANGE: 'out-of-range', - UNIMPLEMENTED: 'unimplemented', - INTERNAL: 'internal', - UNAVAILABLE: 'unavailable', - DATA_LOSS: 'data-loss', - }, -}; diff --git a/src/modules/functions/types.flow.js b/src/modules/functions/types.flow.js deleted file mode 100644 index 86608279..00000000 --- a/src/modules/functions/types.flow.js +++ /dev/null @@ -1,30 +0,0 @@ -export type HttpsCallableResult = { - data: Object, -}; - -export type FunctionsErrorCode = - | 'ok' - | 'cancelled' - | 'unknown' - | 'invalid-argument' - | 'deadline-exceeded' - | 'not-found' - | 'already-exists' - | 'permission-denied' - | 'resource-exhausted' - | 'failed-precondition' - | 'aborted' - | 'out-of-range' - | 'unimplemented' - | 'internal' - | 'unavailable' - | 'data-loss' - | 'unauthenticated'; - -export type HttpsCallablePromise = - | Promise - | Promise; - -export type HttpsCallable = (data?: any) => HttpsCallablePromise; - -export type HttpsErrorCode = { [name: string]: FunctionsErrorCode }; diff --git a/src/modules/iid/index.js b/src/modules/iid/index.js deleted file mode 100644 index f6ce3a85..00000000 --- a/src/modules/iid/index.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @flow - * Instance ID representation wrapper - */ -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -export const NAMESPACE = 'iid'; -export const MODULE_NAME = 'RNFirebaseInstanceId'; - -export default class InstanceId extends ModuleBase { - constructor(app: App) { - super(app, { - hasCustomUrlSupport: false, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - namespace: NAMESPACE, - }); - } - - /** - * Get the current Instance ID. - * - * @returns {*} - */ - get(): Promise { - return getNativeModule(this).get(); - } - - /** - * Delete the current Instance ID. - * - * @returns {*} - */ - delete(): Promise { - return getNativeModule(this).delete(); - } - - /** - * Get a token that authorizes an Entity to perform an action on behalf - * of the application identified by Instance ID. - * - * @param authorizedEntity - * @param scope - * @returns {Promise} - */ - getToken(authorizedEntity?: string, scope?: string): Promise { - return getNativeModule(this).getToken( - authorizedEntity || this.app.options.messagingSenderId, - scope || '*' - ); - } - - /** - * Revokes access to a scope (action) for an entity previously authorized by getToken(). - * - * @param authorizedEntity - * @param scope - * @returns {Promise} - */ - deleteToken(authorizedEntity?: string, scope?: string): Promise { - return getNativeModule(this).deleteToken( - authorizedEntity || this.app.options.messagingSenderId, - scope || '*' - ); - } -} - -export const statics = {}; diff --git a/src/modules/invites/AndroidInvitation.js b/src/modules/invites/AndroidInvitation.js deleted file mode 100644 index b5827547..00000000 --- a/src/modules/invites/AndroidInvitation.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @flow - * AndroidInvitation representation wrapper - */ -import type Invitation from './Invitation'; -import type { NativeAndroidInvitation } from './types'; - -export default class AndroidInvitation { - _additionalReferralParameters: { [string]: string } | void; - - _emailHtmlContent: string | void; - - _emailSubject: string | void; - - _googleAnalyticsTrackingId: string | void; - - _invitation: Invitation; - - constructor(invitation: Invitation) { - this._invitation = invitation; - } - - /** - * - * @param additionalReferralParameters - * @returns {Invitation} - */ - setAdditionalReferralParameters(additionalReferralParameters: { - [string]: string, - }): Invitation { - this._additionalReferralParameters = additionalReferralParameters; - return this._invitation; - } - - /** - * - * @param emailHtmlContent - * @returns {Invitation} - */ - setEmailHtmlContent(emailHtmlContent: string): Invitation { - this._emailHtmlContent = emailHtmlContent; - return this._invitation; - } - - /** - * - * @param emailSubject - * @returns {Invitation} - */ - setEmailSubject(emailSubject: string): Invitation { - this._emailSubject = emailSubject; - return this._invitation; - } - - /** - * - * @param googleAnalyticsTrackingId - * @returns {Invitation} - */ - setGoogleAnalyticsTrackingId(googleAnalyticsTrackingId: string): Invitation { - this._googleAnalyticsTrackingId = googleAnalyticsTrackingId; - return this._invitation; - } - - build(): NativeAndroidInvitation { - return { - additionalReferralParameters: this._additionalReferralParameters, - emailHtmlContent: this._emailHtmlContent, - emailSubject: this._emailSubject, - googleAnalyticsTrackingId: this._googleAnalyticsTrackingId, - }; - } -} diff --git a/src/modules/invites/Invitation.js b/src/modules/invites/Invitation.js deleted file mode 100644 index 81233109..00000000 --- a/src/modules/invites/Invitation.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @flow - * Invitation representation wrapper - */ -import { Platform } from 'react-native'; -import AndroidInvitation from './AndroidInvitation'; - -import type { NativeInvitation } from './types'; - -export default class Invitation { - _android: AndroidInvitation; - - _androidClientId: string | void; - - _androidMinimumVersionCode: number | void; - - _callToActionText: string | void; - - _customImage: string | void; - - _deepLink: string | void; - - _iosClientId: string | void; - - _message: string; - - _title: string; - - constructor(title: string, message: string) { - this._android = new AndroidInvitation(this); - this._message = message; - this._title = title; - } - - get android(): AndroidInvitation { - return this._android; - } - - /** - * - * @param androidClientId - * @returns {Invitation} - */ - setAndroidClientId(androidClientId: string): Invitation { - this._androidClientId = androidClientId; - return this; - } - - /** - * - * @param androidMinimumVersionCode - * @returns {Invitation} - */ - setAndroidMinimumVersionCode(androidMinimumVersionCode: number): Invitation { - this._androidMinimumVersionCode = androidMinimumVersionCode; - return this; - } - - /** - * - * @param callToActionText - * @returns {Invitation} - */ - setCallToActionText(callToActionText: string): Invitation { - this._callToActionText = callToActionText; - return this; - } - - /** - * - * @param customImage - * @returns {Invitation} - */ - setCustomImage(customImage: string): Invitation { - this._customImage = customImage; - return this; - } - - /** - * - * @param deepLink - * @returns {Invitation} - */ - setDeepLink(deepLink: string): Invitation { - this._deepLink = deepLink; - return this; - } - - /** - * - * @param iosClientId - * @returns {Invitation} - */ - setIOSClientId(iosClientId: string): Invitation { - this._iosClientId = iosClientId; - return this; - } - - build(): NativeInvitation { - if (!this._message) { - throw new Error('Invitation: Missing required `message` property'); - } else if (!this._title) { - throw new Error('Invitation: Missing required `title` property'); - } - - return { - android: Platform.OS === 'android' ? this._android.build() : undefined, - androidClientId: this._androidClientId, - androidMinimumVersionCode: this._androidMinimumVersionCode, - callToActionText: this._callToActionText, - customImage: this._customImage, - deepLink: this._deepLink, - iosClientId: this._iosClientId, - message: this._message, - title: this._title, - }; - } -} diff --git a/src/modules/invites/index.js b/src/modules/invites/index.js deleted file mode 100644 index d253762d..00000000 --- a/src/modules/invites/index.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @flow - * Invites representation wrapper - */ -import { Platform } from 'react-native'; -import { SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; -import Invitation from './Invitation'; - -import type App from '../core/app'; - -export const MODULE_NAME = 'RNFirebaseInvites'; -export const NAMESPACE = 'invites'; -const NATIVE_EVENTS = ['invites_invitation_received']; - -type InvitationOpen = { - deepLink: string, - invitationId: string, -}; - -export default class Invites extends ModuleBase { - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - hasCustomUrlSupport: false, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - namespace: NAMESPACE, - }); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onMessage - 'invites_invitation_received', - (invitation: InvitationOpen) => { - SharedEventEmitter.emit('onInvitation', invitation); - } - ); - - // Tell the native module that we're ready to receive events - if (Platform.OS === 'ios') { - getNativeModule(this).jsInitialised(); - } - } - - /** - * Returns the invitation that triggered application open - * @returns {Promise.} - */ - getInitialInvitation(): Promise { - return getNativeModule(this).getInitialInvitation(); - } - - /** - * Subscribe to invites - * @param listener - * @returns {Function} - */ - onInvitation(listener: InvitationOpen => any) { - getLogger(this).info('Creating onInvitation listener'); - - SharedEventEmitter.addListener('onInvitation', listener); - - return () => { - getLogger(this).info('Removing onInvitation listener'); - SharedEventEmitter.removeListener('onInvitation', listener); - }; - } - - sendInvitation(invitation: Invitation): Promise { - if (!(invitation instanceof Invitation)) { - return Promise.reject( - new Error( - `Invites:sendInvitation expects an 'Invitation' but got type ${typeof invitation}` - ) - ); - } - try { - return getNativeModule(this).sendInvitation(invitation.build()); - } catch (error) { - return Promise.reject(error); - } - } -} - -export const statics = { - Invitation, -}; diff --git a/src/modules/invites/types.js b/src/modules/invites/types.js deleted file mode 100644 index 45e24727..00000000 --- a/src/modules/invites/types.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @flow - */ -export type NativeAndroidInvitation = {| - additionalReferralParameters?: { [string]: string }, - emailHtmlContent?: string, - emailSubject?: string, - googleAnalyticsTrackingId?: string, -|}; - -export type NativeInvitation = {| - android?: NativeAndroidInvitation, - androidClientId?: string, - androidMinimumVersionCode?: number, - callToActionText?: string, - customImage?: string, - deepLink?: string, - iosClientId?: string, - message: string, - title: string, -|}; diff --git a/src/modules/links/AnalyticsParameters.js b/src/modules/links/AnalyticsParameters.js deleted file mode 100644 index bbe83757..00000000 --- a/src/modules/links/AnalyticsParameters.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @flow - * AnalyticsParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeAnalyticsParameters } from './types'; - -export default class AnalyticsParameters { - _campaign: string | void; - - _content: string | void; - - _link: DynamicLink; - - _medium: string | void; - - _source: string | void; - - _term: string | void; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param campaign - * @returns {DynamicLink} - */ - setCampaign(campaign: string): DynamicLink { - this._campaign = campaign; - return this._link; - } - - /** - * - * @param content - * @returns {DynamicLink} - */ - setContent(content: string): DynamicLink { - this._content = content; - return this._link; - } - - /** - * - * @param medium - * @returns {DynamicLink} - */ - setMedium(medium: string): DynamicLink { - this._medium = medium; - return this._link; - } - - /** - * - * @param source - * @returns {DynamicLink} - */ - setSource(source: string): DynamicLink { - this._source = source; - return this._link; - } - - /** - * - * @param term - * @returns {DynamicLink} - */ - setTerm(term: string): DynamicLink { - this._term = term; - return this._link; - } - - build(): NativeAnalyticsParameters { - return { - campaign: this._campaign, - content: this._content, - medium: this._medium, - source: this._source, - term: this._term, - }; - } -} diff --git a/src/modules/links/AndroidParameters.js b/src/modules/links/AndroidParameters.js deleted file mode 100644 index 3c592cfb..00000000 --- a/src/modules/links/AndroidParameters.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @flow - * AndroidParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeAndroidParameters } from './types'; - -export default class AndroidParameters { - _fallbackUrl: string | void; - - _link: DynamicLink; - - _minimumVersion: number | void; - - _packageName: string | void; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param fallbackUrl - * @returns {DynamicLink} - */ - setFallbackUrl(fallbackUrl: string): DynamicLink { - this._fallbackUrl = fallbackUrl; - return this._link; - } - - /** - * - * @param minimumVersion - * @returns {DynamicLink} - */ - setMinimumVersion(minimumVersion: number): DynamicLink { - this._minimumVersion = minimumVersion; - return this._link; - } - - /** - * - * @param packageName - * @returns {DynamicLink} - */ - setPackageName(packageName: string): DynamicLink { - this._packageName = packageName; - return this._link; - } - - build(): NativeAndroidParameters { - if ((this._fallbackUrl || this._minimumVersion) && !this._packageName) { - throw new Error( - 'AndroidParameters: Missing required `packageName` property' - ); - } - return { - fallbackUrl: this._fallbackUrl, - minimumVersion: this._minimumVersion, - packageName: this._packageName, - }; - } -} diff --git a/src/modules/links/DynamicLink.js b/src/modules/links/DynamicLink.js deleted file mode 100644 index 9617e3f9..00000000 --- a/src/modules/links/DynamicLink.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @flow - * DynamicLink representation wrapper - */ -import AnalyticsParameters from './AnalyticsParameters'; -import AndroidParameters from './AndroidParameters'; -import IOSParameters from './IOSParameters'; -import ITunesParameters from './ITunesParameters'; -import NavigationParameters from './NavigationParameters'; -import SocialParameters from './SocialParameters'; - -import type { NativeDynamicLink } from './types'; - -export default class DynamicLink { - _analytics: AnalyticsParameters; - - _android: AndroidParameters; - - _dynamicLinkDomain: string; - - _ios: IOSParameters; - - _itunes: ITunesParameters; - - _link: string; - - _navigation: NavigationParameters; - - _social: SocialParameters; - - constructor(link: string, dynamicLinkDomain: string) { - this._analytics = new AnalyticsParameters(this); - this._android = new AndroidParameters(this); - this._dynamicLinkDomain = dynamicLinkDomain; - this._ios = new IOSParameters(this); - this._itunes = new ITunesParameters(this); - this._link = link; - this._navigation = new NavigationParameters(this); - this._social = new SocialParameters(this); - } - - get analytics(): AnalyticsParameters { - return this._analytics; - } - - get android(): AndroidParameters { - return this._android; - } - - get ios(): IOSParameters { - return this._ios; - } - - get itunes(): ITunesParameters { - return this._itunes; - } - - get navigation(): NavigationParameters { - return this._navigation; - } - - get social(): SocialParameters { - return this._social; - } - - build(): NativeDynamicLink { - if (!this._link) { - throw new Error('DynamicLink: Missing required `link` property'); - } else if (!this._dynamicLinkDomain) { - throw new Error( - 'DynamicLink: Missing required `dynamicLinkDomain` property' - ); - } - - return { - analytics: this._analytics.build(), - android: this._android.build(), - dynamicLinkDomain: this._dynamicLinkDomain, - ios: this._ios.build(), - itunes: this._itunes.build(), - link: this._link, - navigation: this._navigation.build(), - social: this._social.build(), - }; - } -} diff --git a/src/modules/links/IOSParameters.js b/src/modules/links/IOSParameters.js deleted file mode 100644 index f7939677..00000000 --- a/src/modules/links/IOSParameters.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @flow - * IOSParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeIOSParameters } from './types'; - -export default class IOSParameters { - _appStoreId: string | void; - - _bundleId: string | void; - - _customScheme: string | void; - - _fallbackUrl: string | void; - - _iPadBundleId: string | void; - - _iPadFallbackUrl: string | void; - - _link: DynamicLink; - - _minimumVersion: string | void; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param appStoreId - * @returns {DynamicLink} - */ - setAppStoreId(appStoreId: string): DynamicLink { - this._appStoreId = appStoreId; - return this._link; - } - - /** - * - * @param bundleId - * @returns {DynamicLink} - */ - setBundleId(bundleId: string): DynamicLink { - this._bundleId = bundleId; - return this._link; - } - - /** - * - * @param customScheme - * @returns {DynamicLink} - */ - setCustomScheme(customScheme: string): DynamicLink { - this._customScheme = customScheme; - return this._link; - } - - /** - * - * @param fallbackUrl - * @returns {DynamicLink} - */ - setFallbackUrl(fallbackUrl: string): DynamicLink { - this._fallbackUrl = fallbackUrl; - return this._link; - } - - /** - * - * @param iPadBundleId - * @returns {DynamicLink} - */ - setIPadBundleId(iPadBundleId: string): DynamicLink { - this._iPadBundleId = iPadBundleId; - return this._link; - } - - /** - * - * @param iPadFallbackUrl - * @returns {DynamicLink} - */ - setIPadFallbackUrl(iPadFallbackUrl: string): DynamicLink { - this._iPadFallbackUrl = iPadFallbackUrl; - return this._link; - } - - /** - * - * @param minimumVersion - * @returns {DynamicLink} - */ - setMinimumVersion(minimumVersion: string): DynamicLink { - this._minimumVersion = minimumVersion; - return this._link; - } - - build(): NativeIOSParameters { - if ( - (this._appStoreId || - this._customScheme || - this._fallbackUrl || - this._iPadBundleId || - this._iPadFallbackUrl || - this._minimumVersion) && - !this._bundleId - ) { - throw new Error('IOSParameters: Missing required `bundleId` property'); - } - return { - appStoreId: this._appStoreId, - bundleId: this._bundleId, - customScheme: this._customScheme, - fallbackUrl: this._fallbackUrl, - iPadBundleId: this._iPadBundleId, - iPadFallbackUrl: this._iPadFallbackUrl, - minimumVersion: this._minimumVersion, - }; - } -} diff --git a/src/modules/links/ITunesParameters.js b/src/modules/links/ITunesParameters.js deleted file mode 100644 index ec51894b..00000000 --- a/src/modules/links/ITunesParameters.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @flow - * ITunesParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeITunesParameters } from './types'; - -export default class ITunesParameters { - _affiliateToken: string | void; - - _campaignToken: string | void; - - _link: DynamicLink; - - _providerToken: string | void; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param affiliateToken - * @returns {DynamicLink} - */ - setAffiliateToken(affiliateToken: string): DynamicLink { - this._affiliateToken = affiliateToken; - return this._link; - } - - /** - * - * @param campaignToken - * @returns {DynamicLink} - */ - setCampaignToken(campaignToken: string): DynamicLink { - this._campaignToken = campaignToken; - return this._link; - } - - /** - * - * @param providerToken - * @returns {DynamicLink} - */ - setProviderToken(providerToken: string): DynamicLink { - this._providerToken = providerToken; - return this._link; - } - - build(): NativeITunesParameters { - return { - affiliateToken: this._affiliateToken, - campaignToken: this._campaignToken, - providerToken: this._providerToken, - }; - } -} diff --git a/src/modules/links/NavigationParameters.js b/src/modules/links/NavigationParameters.js deleted file mode 100644 index 4f682896..00000000 --- a/src/modules/links/NavigationParameters.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @flow - * NavigationParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeNavigationParameters } from './types'; - -export default class NavigationParameters { - _forcedRedirectEnabled: boolean | void; - - _link: DynamicLink; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param forcedRedirectEnabled - * @returns {DynamicLink} - */ - setForcedRedirectEnabled(forcedRedirectEnabled: boolean): DynamicLink { - this._forcedRedirectEnabled = forcedRedirectEnabled; - return this._link; - } - - build(): NativeNavigationParameters { - return { - forcedRedirectEnabled: this._forcedRedirectEnabled, - }; - } -} diff --git a/src/modules/links/SocialParameters.js b/src/modules/links/SocialParameters.js deleted file mode 100644 index 32c76d61..00000000 --- a/src/modules/links/SocialParameters.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @flow - * SocialParameters representation wrapper - */ -import type DynamicLink from './DynamicLink'; -import type { NativeSocialParameters } from './types'; - -export default class SocialParameters { - _descriptionText: string | void; - - _imageUrl: string | void; - - _link: DynamicLink; - - _title: string | void; - - constructor(link: DynamicLink) { - this._link = link; - } - - /** - * - * @param descriptionText - * @returns {DynamicLink} - */ - setDescriptionText(descriptionText: string): DynamicLink { - this._descriptionText = descriptionText; - return this._link; - } - - /** - * - * @param imageUrl - * @returns {DynamicLink} - */ - setImageUrl(imageUrl: string): DynamicLink { - this._imageUrl = imageUrl; - return this._link; - } - - /** - * - * @param title - * @returns {DynamicLink} - */ - setTitle(title: string): DynamicLink { - this._title = title; - return this._link; - } - - build(): NativeSocialParameters { - return { - descriptionText: this._descriptionText, - imageUrl: this._imageUrl, - title: this._title, - }; - } -} diff --git a/src/modules/links/index.js b/src/modules/links/index.js deleted file mode 100644 index cb2f3b23..00000000 --- a/src/modules/links/index.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @flow - * Dynamic Links representation wrapper - */ -import { Platform } from 'react-native'; -import DynamicLink from './DynamicLink'; -import { SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -const NATIVE_EVENTS = ['links_link_received']; - -export const MODULE_NAME = 'RNFirebaseLinks'; -export const NAMESPACE = 'links'; - -/** - * @class Links - */ -export default class Links extends ModuleBase { - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onMessage - 'links_link_received', - (link: string) => { - SharedEventEmitter.emit('onLink', link); - } - ); - - // Tell the native module that we're ready to receive events - if (Platform.OS === 'ios') { - getNativeModule(this).jsInitialised(); - } - } - - /** - * Create long Dynamic Link from parameters - * @param parameters - * @returns {Promise.} - */ - createDynamicLink(link: DynamicLink): Promise { - if (!(link instanceof DynamicLink)) { - return Promise.reject( - new Error( - `Links:createDynamicLink expects a 'DynamicLink' but got type ${typeof link}` - ) - ); - } - try { - return getNativeModule(this).createDynamicLink(link.build()); - } catch (error) { - return Promise.reject(error); - } - } - - /** - * Create short Dynamic Link from parameters - * @param parameters - * @returns {Promise.} - */ - createShortDynamicLink( - link: DynamicLink, - type?: 'SHORT' | 'UNGUESSABLE' - ): Promise { - if (!(link instanceof DynamicLink)) { - return Promise.reject( - new Error( - `Links:createShortDynamicLink expects a 'DynamicLink' but got type ${typeof link}` - ) - ); - } - try { - return getNativeModule(this).createShortDynamicLink(link.build(), type); - } catch (error) { - return Promise.reject(error); - } - } - - /** - * Returns the link that triggered application open - * @returns {Promise.} - */ - getInitialLink(): Promise { - return getNativeModule(this).getInitialLink(); - } - - /** - * Subscribe to dynamic links - * @param listener - * @returns {Function} - */ - onLink(listener: string => any): () => any { - getLogger(this).info('Creating onLink listener'); - - SharedEventEmitter.addListener('onLink', listener); - - return () => { - getLogger(this).info('Removing onLink listener'); - SharedEventEmitter.removeListener('onLink', listener); - }; - } -} - -export const statics = { - DynamicLink, -}; diff --git a/src/modules/links/types.js b/src/modules/links/types.js deleted file mode 100644 index 3effff76..00000000 --- a/src/modules/links/types.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @flow - */ -export type NativeAnalyticsParameters = {| - campaign?: string, - content?: string, - medium?: string, - source?: string, - term?: string, -|}; - -export type NativeAndroidParameters = {| - fallbackUrl?: string, - minimumVersion?: number, - packageName?: string, -|}; - -export type NativeIOSParameters = {| - appStoreId?: string, - bundleId?: string, - customScheme?: string, - fallbackUrl?: string, - iPadBundleId?: string, - iPadFallbackUrl?: string, - minimumVersion?: string, -|}; - -export type NativeITunesParameters = {| - affiliateToken?: string, - campaignToken?: string, - providerToken?: string, -|}; - -export type NativeNavigationParameters = {| - forcedRedirectEnabled?: boolean, -|}; - -export type NativeSocialParameters = {| - descriptionText?: string, - imageUrl?: string, - title?: string, -|}; - -export type NativeDynamicLink = {| - analytics: NativeAnalyticsParameters, - android: NativeAndroidParameters, - dynamicLinkDomain: string, - ios: NativeIOSParameters, - itunes: NativeITunesParameters, - link: string, - navigation: NativeNavigationParameters, - social: NativeSocialParameters, -|}; diff --git a/src/modules/messaging/IOSMessaging.js b/src/modules/messaging/IOSMessaging.js deleted file mode 100644 index a97bf75b..00000000 --- a/src/modules/messaging/IOSMessaging.js +++ /dev/null @@ -1,25 +0,0 @@ -import { getNativeModule } from '../../utils/native'; - -import { isIOS } from '../../utils'; - -import type Messaging from './'; - -export default class IOSMessaging { - constructor(messaging: Messaging) { - this._messaging = messaging; - } - - getAPNSToken(): Promise { - if (!isIOS) { - return null; - } - return getNativeModule(this._messaging).getAPNSToken(); - } - - registerForRemoteNotifications(): Promise { - if (!isIOS) { - return undefined; - } - return getNativeModule(this._messaging).registerForRemoteNotifications(); - } -} diff --git a/src/modules/messaging/RemoteMessage.js b/src/modules/messaging/RemoteMessage.js deleted file mode 100644 index d076e231..00000000 --- a/src/modules/messaging/RemoteMessage.js +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @flow - * RemoteMessage representation wrapper - */ -import { isObject, generatePushID } from '../../utils'; - -import type { - NativeInboundRemoteMessage, - NativeOutboundRemoteMessage, -} from './types'; - -export default class RemoteMessage { - _collapseKey: string | void; - - _data: { [string]: string }; - - _from: string | void; - - _messageId: string; - - _messageType: string | void; - - _sentTime: number | void; - - _to: string; - - _ttl: number; - - constructor(inboundMessage?: NativeInboundRemoteMessage) { - if (inboundMessage) { - this._collapseKey = inboundMessage.collapseKey; - this._data = inboundMessage.data; - this._from = inboundMessage.from; - this._messageId = inboundMessage.messageId; - this._messageType = inboundMessage.messageType; - this._sentTime = inboundMessage.sentTime; - } - // defaults - this._data = this._data || {}; - // TODO: Is this the best way to generate an ID? - this._messageId = this._messageId || generatePushID(); - this._ttl = 3600; - } - - get collapseKey(): ?string { - return this._collapseKey; - } - - get data(): { [string]: string } { - return this._data; - } - - get from(): ?string { - return this._from; - } - - get messageId(): ?string { - return this._messageId; - } - - get messageType(): ?string { - return this._messageType; - } - - get sentTime(): ?number { - return this._sentTime; - } - - get to(): ?string { - return this._to; - } - - get ttl(): ?number { - return this._ttl; - } - - /** - * - * @param collapseKey - * @returns {RemoteMessage} - */ - setCollapseKey(collapseKey: string): RemoteMessage { - this._collapseKey = collapseKey; - return this; - } - - /** - * - * @param data - * @returns {RemoteMessage} - */ - setData(data: { [string]: string } = {}) { - if (!isObject(data)) { - throw new Error( - `RemoteMessage:setData expects an object but got type '${typeof data}'.` - ); - } - this._data = data; - return this; - } - - /** - * - * @param messageId - * @returns {RemoteMessage} - */ - setMessageId(messageId: string): RemoteMessage { - this._messageId = messageId; - return this; - } - - /** - * - * @param messageType - * @returns {RemoteMessage} - */ - setMessageType(messageType: string): RemoteMessage { - this._messageType = messageType; - return this; - } - - /** - * - * @param to - * @returns {RemoteMessage} - */ - setTo(to: string): RemoteMessage { - this._to = to; - return this; - } - - /** - * - * @param ttl - * @returns {RemoteMessage} - */ - setTtl(ttl: number): RemoteMessage { - this._ttl = ttl; - return this; - } - - build(): NativeOutboundRemoteMessage { - if (!this._data) { - throw new Error('RemoteMessage: Missing required `data` property'); - } else if (!this._messageId) { - throw new Error('RemoteMessage: Missing required `messageId` property'); - } else if (!this._to) { - throw new Error('RemoteMessage: Missing required `to` property'); - } else if (!this._ttl) { - throw new Error('RemoteMessage: Missing required `ttl` property'); - } - - return { - collapseKey: this._collapseKey, - data: this._data, - messageId: this._messageId, - messageType: this._messageType, - to: this._to, - ttl: this._ttl, - }; - } -} diff --git a/src/modules/messaging/index.js b/src/modules/messaging/index.js deleted file mode 100644 index 988be949..00000000 --- a/src/modules/messaging/index.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @flow - * Messaging (FCM) representation wrapper - */ -import { Platform } from 'react-native'; -import { SharedEventEmitter } from '../../utils/events'; -import INTERNALS from '../../utils/internals'; -import { getLogger } from '../../utils/log'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; -import { isFunction, isObject } from '../../utils'; -import IOSMessaging from './IOSMessaging'; -import RemoteMessage from './RemoteMessage'; - -import type App from '../core/app'; -import type { NativeInboundRemoteMessage } from './types'; - -type OnMessage = RemoteMessage => any; - -type OnMessageObserver = { - next: OnMessage, -}; - -type OnTokenRefresh = string => any; - -type OnTokenRefreshObserver = { - next: OnTokenRefresh, -}; - -const NATIVE_EVENTS = [ - 'messaging_message_received', - 'messaging_token_refreshed', -]; - -export const MODULE_NAME = 'RNFirebaseMessaging'; -export const NAMESPACE = 'messaging'; - -/** - * @class Messaging - */ -export default class Messaging extends ModuleBase { - _ios: IOSMessaging; - - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - this._ios = new IOSMessaging(this); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onMessage - 'messaging_message_received', - (message: NativeInboundRemoteMessage) => { - SharedEventEmitter.emit('onMessage', new RemoteMessage(message)); - } - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onMessage - 'messaging_token_refreshed', - (token: string) => { - SharedEventEmitter.emit('onTokenRefresh', token); - } - ); - - // Tell the native module that we're ready to receive events - if (Platform.OS === 'ios') { - getNativeModule(this).jsInitialised(); - } - } - - get ios(): IOSMessaging { - return this._ios; - } - - getToken(): Promise { - return getNativeModule(this).getToken(); - } - - deleteToken(): Promise { - return getNativeModule(this).deleteToken(); - } - - onMessage(nextOrObserver: OnMessage | OnMessageObserver): () => any { - let listener: RemoteMessage => any; - if (isFunction(nextOrObserver)) { - // $FlowExpectedError: Not coping with the overloaded method signature - listener = nextOrObserver; - } else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) { - listener = nextOrObserver.next; - } else { - throw new Error( - 'Messaging.onMessage failed: First argument must be a function or observer object with a `next` function.' - ); - } - - getLogger(this).info('Creating onMessage listener'); - - SharedEventEmitter.addListener('onMessage', listener); - - return () => { - getLogger(this).info('Removing onMessage listener'); - SharedEventEmitter.removeListener('onMessage', listener); - }; - } - - onTokenRefresh( - nextOrObserver: OnTokenRefresh | OnTokenRefreshObserver - ): () => any { - let listener: string => any; - if (isFunction(nextOrObserver)) { - // $FlowExpectedError: Not coping with the overloaded method signature - listener = nextOrObserver; - } else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) { - listener = nextOrObserver.next; - } else { - throw new Error( - 'Messaging.onTokenRefresh failed: First argument must be a function or observer object with a `next` function.' - ); - } - - getLogger(this).info('Creating onTokenRefresh listener'); - SharedEventEmitter.addListener('onTokenRefresh', listener); - - return () => { - getLogger(this).info('Removing onTokenRefresh listener'); - SharedEventEmitter.removeListener('onTokenRefresh', listener); - }; - } - - requestPermission(): Promise { - return getNativeModule(this).requestPermission(); - } - - /** - * NON WEB-SDK METHODS - */ - hasPermission(): Promise { - return getNativeModule(this).hasPermission(); - } - - sendMessage(remoteMessage: RemoteMessage): Promise { - if (!(remoteMessage instanceof RemoteMessage)) { - return Promise.reject( - new Error( - `Messaging:sendMessage expects a 'RemoteMessage' but got type ${typeof remoteMessage}` - ) - ); - } - try { - return getNativeModule(this).sendMessage(remoteMessage.build()); - } catch (error) { - return Promise.reject(error); - } - } - - subscribeToTopic(topic: string): Promise { - return getNativeModule(this).subscribeToTopic(topic); - } - - unsubscribeFromTopic(topic: string): Promise { - return getNativeModule(this).unsubscribeFromTopic(topic); - } - - /** - * KNOWN UNSUPPORTED METHODS - */ - - setBackgroundMessageHandler() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'messaging', - 'setBackgroundMessageHandler' - ) - ); - } - - useServiceWorker() { - throw new Error( - INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD( - 'messaging', - 'useServiceWorker' - ) - ); - } -} - -export const statics = { - RemoteMessage, -}; diff --git a/src/modules/messaging/types.js b/src/modules/messaging/types.js deleted file mode 100644 index e2cbe647..00000000 --- a/src/modules/messaging/types.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @flow - */ -export type Notification = { - body: string, - bodyLocalizationArgs?: string[], - bodyLocalizationKey?: string, - clickAction?: string, - color?: string, - icon?: string, - link?: string, - sound: string, - subtitle?: string, - tag?: string, - title: string, - titleLocalizationArgs?: string[], - titleLocalizationKey?: string, -}; - -export type NativeInboundRemoteMessage = { - collapseKey?: string, - data: { [string]: string }, - from?: string, - messageId: string, - messageType?: string, - sentTime?: number, - to?: string, - ttl?: number, -}; - -export type NativeOutboundRemoteMessage = { - collapseKey?: string, - data: { [string]: string }, - messageId: string, - messageType?: string, - to: string, - ttl: number, -}; diff --git a/src/modules/notifications/AndroidAction.js b/src/modules/notifications/AndroidAction.js deleted file mode 100644 index 5da48dc2..00000000 --- a/src/modules/notifications/AndroidAction.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * @flow - * AndroidAction representation wrapper - */ -import RemoteInput, { - fromNativeAndroidRemoteInput, -} from './AndroidRemoteInput'; -import { SemanticAction } from './types'; -import type { NativeAndroidAction, SemanticActionType } from './types'; - -export default class AndroidAction { - _action: string; - - _allowGeneratedReplies: boolean | void; - - _icon: string; - - _remoteInputs: RemoteInput[]; - - _semanticAction: SemanticActionType | void; - - _showUserInterface: boolean | void; - - _title: string; - - constructor(action: string, icon: string, title: string) { - this._action = action; - this._icon = icon; - this._remoteInputs = []; - this._showUserInterface = true; - this._title = title; - } - - get action(): string { - return this._action; - } - - get allowGeneratedReplies(): ?boolean { - return this._allowGeneratedReplies; - } - - get icon(): string { - return this._icon; - } - - get remoteInputs(): RemoteInput[] { - return this._remoteInputs; - } - - get semanticAction(): ?SemanticActionType { - return this._semanticAction; - } - - get showUserInterface(): ?boolean { - return this._showUserInterface; - } - - get title(): string { - return this._title; - } - - /** - * - * @param remoteInput - * @returns {AndroidAction} - */ - addRemoteInput(remoteInput: RemoteInput): AndroidAction { - if (!(remoteInput instanceof RemoteInput)) { - throw new Error( - `AndroidAction:addRemoteInput expects an 'RemoteInput' but got type ${typeof remoteInput}` - ); - } - this._remoteInputs.push(remoteInput); - return this; - } - - /** - * - * @param allowGeneratedReplies - * @returns {AndroidAction} - */ - setAllowGenerateReplies(allowGeneratedReplies: boolean): AndroidAction { - this._allowGeneratedReplies = allowGeneratedReplies; - return this; - } - - /** - * - * @param semanticAction - * @returns {AndroidAction} - */ - setSemanticAction(semanticAction: SemanticActionType): AndroidAction { - if (!Object.values(SemanticAction).includes(semanticAction)) { - throw new Error( - `AndroidAction:setSemanticAction Invalid Semantic Action: ${semanticAction}` - ); - } - this._semanticAction = semanticAction; - return this; - } - - /** - * - * @param showUserInterface - * @returns {AndroidAction} - */ - setShowUserInterface(showUserInterface: boolean): AndroidAction { - this._showUserInterface = showUserInterface; - return this; - } - - build(): NativeAndroidAction { - if (!this._action) { - throw new Error('AndroidAction: Missing required `action` property'); - } else if (!this._icon) { - throw new Error('AndroidAction: Missing required `icon` property'); - } else if (!this._title) { - throw new Error('AndroidAction: Missing required `title` property'); - } - - return { - action: this._action, - allowGeneratedReplies: this._allowGeneratedReplies, - icon: this._icon, - remoteInputs: this._remoteInputs.map(remoteInput => remoteInput.build()), - semanticAction: this._semanticAction, - showUserInterface: this._showUserInterface, - title: this._title, - }; - } -} - -export const fromNativeAndroidAction = ( - nativeAction: NativeAndroidAction -): AndroidAction => { - const action = new AndroidAction( - nativeAction.action, - nativeAction.icon, - nativeAction.title - ); - if (nativeAction.allowGeneratedReplies) { - action.setAllowGenerateReplies(nativeAction.allowGeneratedReplies); - } - if (nativeAction.remoteInputs) { - nativeAction.remoteInputs.forEach(remoteInput => { - action.addRemoteInput(fromNativeAndroidRemoteInput(remoteInput)); - }); - } - if (nativeAction.semanticAction) { - action.setSemanticAction(nativeAction.semanticAction); - } - if (nativeAction.showUserInterface) { - action.setShowUserInterface(nativeAction.showUserInterface); - } - - return action; -}; diff --git a/src/modules/notifications/AndroidChannel.js b/src/modules/notifications/AndroidChannel.js deleted file mode 100644 index 3e936513..00000000 --- a/src/modules/notifications/AndroidChannel.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * @flow - * AndroidChannel representation wrapper - */ -import { Importance, Visibility } from './types'; -import type { ImportanceType, VisibilityType } from './types'; - -type NativeAndroidChannel = {| - bypassDnd?: boolean, - channelId: string, - description?: string, - group?: string, - importance: ImportanceType, - lightColor?: string, - lightsEnabled?: boolean, - lockScreenVisibility?: VisibilityType, - name: string, - showBadge?: boolean, - sound?: string, - vibrationEnabled?: boolean, - vibrationPattern?: number[], -|}; - -export default class AndroidChannel { - _bypassDnd: boolean | void; - - _channelId: string; - - _description: string | void; - - _group: string | void; - - _importance: ImportanceType; - - _lightColor: string | void; - - _lightsEnabled: boolean | void; - - _lockScreenVisibility: VisibilityType; - - _name: string; - - _showBadge: boolean | void; - - _sound: string | void; - - _vibrationEnabled: boolean | void; - - _vibrationPattern: number[] | void; - - constructor(channelId: string, name: string, importance: ImportanceType) { - if (!Object.values(Importance).includes(importance)) { - throw new Error(`AndroidChannel() Invalid Importance: ${importance}`); - } - this._channelId = channelId; - this._name = name; - this._importance = importance; - } - - get bypassDnd(): ?boolean { - return this._bypassDnd; - } - - get channelId(): string { - return this._channelId; - } - - get description(): ?string { - return this._description; - } - - get group(): ?string { - return this._group; - } - - get importance(): ImportanceType { - return this._importance; - } - - get lightColor(): ?string { - return this._lightColor; - } - - get lightsEnabled(): ?boolean { - return this._lightsEnabled; - } - - get lockScreenVisibility(): ?VisibilityType { - return this._lockScreenVisibility; - } - - get name(): string { - return this._name; - } - - get showBadge(): ?boolean { - return this._showBadge; - } - - get sound(): ?string { - return this._sound; - } - - get vibrationEnabled(): ?boolean { - return this._vibrationEnabled; - } - - get vibrationPattern(): ?(number[]) { - return this._vibrationPattern; - } - - /** - * - * @param lightsEnabled - * @returns {AndroidChannel} - */ - enableLights(lightsEnabled: boolean): AndroidChannel { - this._lightsEnabled = lightsEnabled; - return this; - } - - /** - * - * @param vibrationEnabled - * @returns {AndroidChannel} - */ - enableVibration(vibrationEnabled: boolean): AndroidChannel { - this._vibrationEnabled = vibrationEnabled; - return this; - } - - /** - * - * @param bypassDnd - * @returns {AndroidChannel} - */ - setBypassDnd(bypassDnd: boolean): AndroidChannel { - this._bypassDnd = bypassDnd; - return this; - } - - /** - * - * @param description - * @returns {AndroidChannel} - */ - setDescription(description: string): AndroidChannel { - this._description = description; - return this; - } - - /** - * - * @param group - * @returns {AndroidChannel} - */ - setGroup(groupId: string): AndroidChannel { - this._group = groupId; - return this; - } - - /** - * - * @param lightColor - * @returns {AndroidChannel} - */ - setLightColor(lightColor: string): AndroidChannel { - this._lightColor = lightColor; - return this; - } - - /** - * - * @param lockScreenVisibility - * @returns {AndroidChannel} - */ - setLockScreenVisibility( - lockScreenVisibility: VisibilityType - ): AndroidChannel { - if (!Object.values(Visibility).includes(lockScreenVisibility)) { - throw new Error( - `AndroidChannel:setLockScreenVisibility Invalid Visibility: ${lockScreenVisibility}` - ); - } - this._lockScreenVisibility = lockScreenVisibility; - return this; - } - - /** - * - * @param showBadge - * @returns {AndroidChannel} - */ - setShowBadge(showBadge: boolean): AndroidChannel { - this._showBadge = showBadge; - return this; - } - - /** - * - * @param sound - * @returns {AndroidChannel} - */ - setSound(sound: string): AndroidChannel { - this._sound = sound; - return this; - } - - /** - * - * @param vibrationPattern - * @returns {AndroidChannel} - */ - setVibrationPattern(vibrationPattern: number[]): AndroidChannel { - this._vibrationPattern = vibrationPattern; - return this; - } - - build(): NativeAndroidChannel { - if (!this._channelId) { - throw new Error('AndroidChannel: Missing required `channelId` property'); - } else if (!this._importance) { - throw new Error('AndroidChannel: Missing required `importance` property'); - } else if (!this._name) { - throw new Error('AndroidChannel: Missing required `name` property'); - } - - return { - bypassDnd: this._bypassDnd, - channelId: this._channelId, - description: this._description, - group: this._group, - importance: this._importance, - lightColor: this._lightColor, - lightsEnabled: this._lightsEnabled, - lockScreenVisibility: this._lockScreenVisibility, - name: this._name, - showBadge: this._showBadge, - sound: this._sound, - vibrationEnabled: this._vibrationEnabled, - vibrationPattern: this._vibrationPattern, - }; - } -} diff --git a/src/modules/notifications/AndroidChannelGroup.js b/src/modules/notifications/AndroidChannelGroup.js deleted file mode 100644 index c5d5fd7b..00000000 --- a/src/modules/notifications/AndroidChannelGroup.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @flow - * AndroidChannelGroup representation wrapper - */ - -type NativeAndroidChannelGroup = {| - groupId: string, - name: string, -|}; - -export default class AndroidChannelGroup { - _groupId: string; - - _name: string; - - constructor(groupId: string, name: string) { - this._groupId = groupId; - this._name = name; - } - - get groupId(): string { - return this._groupId; - } - - get name(): string { - return this._name; - } - - build(): NativeAndroidChannelGroup { - if (!this._groupId) { - throw new Error( - 'AndroidChannelGroup: Missing required `groupId` property' - ); - } else if (!this._name) { - throw new Error('AndroidChannelGroup: Missing required `name` property'); - } - - return { - groupId: this._groupId, - name: this._name, - }; - } -} diff --git a/src/modules/notifications/AndroidNotification.js b/src/modules/notifications/AndroidNotification.js deleted file mode 100644 index a090c8ff..00000000 --- a/src/modules/notifications/AndroidNotification.js +++ /dev/null @@ -1,783 +0,0 @@ -/** - * @flow - * AndroidNotification representation wrapper - */ -import AndroidAction, { fromNativeAndroidAction } from './AndroidAction'; -import { BadgeIconType, Category, GroupAlert, Priority } from './types'; -import type Notification from './Notification'; -import type { - BadgeIconTypeType, - BigPicture, - BigText, - CategoryType, - DefaultsType, - GroupAlertType, - Lights, - NativeAndroidNotification, - PriorityType, - Progress, - SmallIcon, - VisibilityType, -} from './types'; - -export default class AndroidNotification { - _actions: AndroidAction[]; - - _autoCancel: boolean | void; - - _badgeIconType: BadgeIconTypeType | void; - - _bigPicture: BigPicture | void; - - _bigText: BigText | void; - - _category: CategoryType | void; - - _channelId: string; - - _clickAction: string | void; - - _color: string | void; - - _colorized: boolean | void; - - _contentInfo: string | void; - - _defaults: DefaultsType[] | void; - - _group: string | void; - - _groupAlertBehaviour: GroupAlertType | void; - - _groupSummary: boolean | void; - - _largeIcon: string | void; - - _lights: Lights | void; - - _localOnly: boolean | void; - - _notification: Notification; - - _number: number | void; - - _ongoing: boolean | void; - - _onlyAlertOnce: boolean | void; - - _people: string[]; - - _priority: PriorityType | void; - - _progress: Progress | void; - - // _publicVersion: Notification; - _remoteInputHistory: string[] | void; - - _shortcutId: string | void; - - _showWhen: boolean | void; - - _smallIcon: SmallIcon; - - _sortKey: string | void; - - // TODO: style: Style; // Need to figure out if this can work - _tag: string | void; - - _ticker: string | void; - - _timeoutAfter: number | void; - - _usesChronometer: boolean | void; - - _vibrate: number[] | void; - - _visibility: VisibilityType | void; - - _when: number | void; - - // android unsupported - // content: RemoteViews - // contentIntent: PendingIntent - need to look at what this is - // customBigContentView: RemoteViews - // customContentView: RemoteViews - // customHeadsUpContentView: RemoteViews - // deleteIntent: PendingIntent - // fullScreenIntent: PendingIntent - // sound.streamType - - constructor(notification: Notification, data?: NativeAndroidNotification) { - this._notification = notification; - - if (data) { - this._actions = data.actions - ? data.actions.map(action => fromNativeAndroidAction(action)) - : []; - this._autoCancel = data.autoCancel; - this._badgeIconType = data.badgeIconType; - this._bigPicture = data.bigPicture; - this._bigText = data.bigText; - this._category = data.category; - this._channelId = data.channelId; - this._clickAction = data.clickAction; - this._color = data.color; - this._colorized = data.colorized; - this._contentInfo = data.contentInfo; - this._defaults = data.defaults; - this._group = data.group; - this._groupAlertBehaviour = data.groupAlertBehaviour; - this._groupSummary = data.groupSummary; - this._largeIcon = data.largeIcon; - this._lights = data.lights; - this._localOnly = data.localOnly; - this._number = data.number; - this._ongoing = data.ongoing; - this._onlyAlertOnce = data.onlyAlertOnce; - this._people = data.people; - this._priority = data.priority; - this._progress = data.progress; - // _publicVersion: Notification; - this._remoteInputHistory = data.remoteInputHistory; - this._shortcutId = data.shortcutId; - this._showWhen = data.showWhen; - this._smallIcon = data.smallIcon; - this._sortKey = data.sortKey; - this._tag = data.tag; - this._ticker = data.ticker; - this._timeoutAfter = data.timeoutAfter; - this._usesChronometer = data.usesChronometer; - this._vibrate = data.vibrate; - this._visibility = data.visibility; - this._when = data.when; - } - - // Defaults - this._actions = this._actions || []; - this._people = this._people || []; - this._smallIcon = this._smallIcon || { - icon: 'ic_launcher', - }; - } - - get actions(): AndroidAction[] { - return this._actions; - } - - get autoCancel(): ?boolean { - return this._autoCancel; - } - - get badgeIconType(): ?BadgeIconTypeType { - return this._badgeIconType; - } - - get bigPicture(): ?BigPicture { - return this._bigPicture; - } - - get bigText(): ?BigText { - return this._bigText; - } - - get category(): ?CategoryType { - return this._category; - } - - get channelId(): string { - return this._channelId; - } - - get clickAction(): ?string { - return this._clickAction; - } - - get color(): ?string { - return this._color; - } - - get colorized(): ?boolean { - return this._colorized; - } - - get contentInfo(): ?string { - return this._contentInfo; - } - - get defaults(): ?(DefaultsType[]) { - return this._defaults; - } - - get group(): ?string { - return this._group; - } - - get groupAlertBehaviour(): ?GroupAlertType { - return this._groupAlertBehaviour; - } - - get groupSummary(): ?boolean { - return this._groupSummary; - } - - get largeIcon(): ?string { - return this._largeIcon; - } - - get lights(): ?Lights { - return this._lights; - } - - get localOnly(): ?boolean { - return this._localOnly; - } - - get number(): ?number { - return this._number; - } - - get ongoing(): ?boolean { - return this._ongoing; - } - - get onlyAlertOnce(): ?boolean { - return this._onlyAlertOnce; - } - - get people(): string[] { - return this._people; - } - - get priority(): ?PriorityType { - return this._priority; - } - - get progress(): ?Progress { - return this._progress; - } - - get remoteInputHistory(): ?(string[]) { - return this._remoteInputHistory; - } - - get shortcutId(): ?string { - return this._shortcutId; - } - - get showWhen(): ?boolean { - return this._showWhen; - } - - get smallIcon(): SmallIcon { - return this._smallIcon; - } - - get sortKey(): ?string { - return this._sortKey; - } - - get tag(): ?string { - return this._tag; - } - - get ticker(): ?string { - return this._ticker; - } - - get timeoutAfter(): ?number { - return this._timeoutAfter; - } - - get usesChronometer(): ?boolean { - return this._usesChronometer; - } - - get vibrate(): ?(number[]) { - return this._vibrate; - } - - get visibility(): ?VisibilityType { - return this._visibility; - } - - get when(): ?number { - return this._when; - } - - /** - * - * @param action - * @returns {Notification} - */ - addAction(action: AndroidAction): Notification { - if (!(action instanceof AndroidAction)) { - throw new Error( - `AndroidNotification:addAction expects an 'AndroidAction' but got type ${typeof action}` - ); - } - this._actions.push(action); - return this._notification; - } - - /** - * - * @param person - * @returns {Notification} - */ - addPerson(person: string): Notification { - this._people.push(person); - return this._notification; - } - - /** - * - * @param autoCancel - * @returns {Notification} - */ - setAutoCancel(autoCancel: boolean): Notification { - this._autoCancel = autoCancel; - return this._notification; - } - - /** - * - * @param badgeIconType - * @returns {Notification} - */ - setBadgeIconType(badgeIconType: BadgeIconTypeType): Notification { - if (!Object.values(BadgeIconType).includes(badgeIconType)) { - throw new Error( - `AndroidNotification:setBadgeIconType Invalid BadgeIconType: ${badgeIconType}` - ); - } - this._badgeIconType = badgeIconType; - return this._notification; - } - - setBigPicture( - picture: string, - largeIcon?: string, - contentTitle?: string, - summaryText?: string - ): Notification { - this._bigPicture = { - contentTitle, - largeIcon, - picture, - summaryText, - }; - return this._notification; - } - - setBigText( - text: string, - contentTitle?: string, - summaryText?: string - ): Notification { - this._bigText = { - contentTitle, - summaryText, - text, - }; - return this._notification; - } - - /** - * - * @param category - * @returns {Notification} - */ - setCategory(category: CategoryType): Notification { - if (!Object.values(Category).includes(category)) { - throw new Error( - `AndroidNotification:setCategory Invalid Category: ${category}` - ); - } - this._category = category; - return this._notification; - } - - /** - * - * @param channelId - * @returns {Notification} - */ - setChannelId(channelId: string): Notification { - this._channelId = channelId; - return this._notification; - } - - /** - * - * @param clickAction - * @returns {Notification} - */ - setClickAction(clickAction: string): Notification { - this._clickAction = clickAction; - return this._notification; - } - - /** - * - * @param color - * @returns {Notification} - */ - setColor(color: string): Notification { - this._color = color; - return this._notification; - } - - /** - * - * @param colorized - * @returns {Notification} - */ - setColorized(colorized: boolean): Notification { - this._colorized = colorized; - return this._notification; - } - - /** - * - * @param contentInfo - * @returns {Notification} - */ - setContentInfo(contentInfo: string): Notification { - this._contentInfo = contentInfo; - return this._notification; - } - - /** - * - * @param defaults - * @returns {Notification} - */ - setDefaults(defaults: DefaultsType[]): Notification { - this._defaults = defaults; - return this._notification; - } - - /** - * - * @param group - * @returns {Notification} - */ - setGroup(group: string): Notification { - this._group = group; - return this._notification; - } - - /** - * - * @param groupAlertBehaviour - * @returns {Notification} - */ - setGroupAlertBehaviour(groupAlertBehaviour: GroupAlertType): Notification { - if (!Object.values(GroupAlert).includes(groupAlertBehaviour)) { - throw new Error( - `AndroidNotification:setGroupAlertBehaviour Invalid GroupAlert: ${groupAlertBehaviour}` - ); - } - this._groupAlertBehaviour = groupAlertBehaviour; - return this._notification; - } - - /** - * - * @param groupSummary - * @returns {Notification} - */ - setGroupSummary(groupSummary: boolean): Notification { - this._groupSummary = groupSummary; - return this._notification; - } - - /** - * - * @param largeIcon - * @returns {Notification} - */ - setLargeIcon(largeIcon: string): Notification { - this._largeIcon = largeIcon; - return this._notification; - } - - /** - * - * @param argb - * @param onMs - * @param offMs - * @returns {Notification} - */ - setLights(argb: number, onMs: number, offMs: number): Notification { - this._lights = { - argb, - onMs, - offMs, - }; - return this._notification; - } - - /** - * - * @param localOnly - * @returns {Notification} - */ - setLocalOnly(localOnly: boolean): Notification { - this._localOnly = localOnly; - return this._notification; - } - - /** - * - * @param number - * @returns {Notification} - */ - setNumber(number: number): Notification { - this._number = number; - return this._notification; - } - - /** - * - * @param ongoing - * @returns {Notification} - */ - setOngoing(ongoing: boolean): Notification { - this._ongoing = ongoing; - return this._notification; - } - - /** - * - * @param onlyAlertOnce - * @returns {Notification} - */ - setOnlyAlertOnce(onlyAlertOnce: boolean): Notification { - this._onlyAlertOnce = onlyAlertOnce; - return this._notification; - } - - /** - * - * @param priority - * @returns {Notification} - */ - setPriority(priority: PriorityType): Notification { - if (!Object.values(Priority).includes(priority)) { - throw new Error( - `AndroidNotification:setPriority Invalid Priority: ${priority}` - ); - } - this._priority = priority; - return this._notification; - } - - /** - * - * @param max - * @param progress - * @param indeterminate - * @returns {Notification} - */ - setProgress( - max: number, - progress: number, - indeterminate: boolean - ): Notification { - this._progress = { - max, - progress, - indeterminate, - }; - return this._notification; - } - - /** - * - * @param publicVersion - * @returns {Notification} - */ - /* setPublicVersion(publicVersion: Notification): Notification { - this._publicVersion = publicVersion; - return this._notification; - } */ - - /** - * - * @param remoteInputHistory - * @returns {Notification} - */ - setRemoteInputHistory(remoteInputHistory: string[]): Notification { - this._remoteInputHistory = remoteInputHistory; - return this._notification; - } - - /** - * - * @param shortcutId - * @returns {Notification} - */ - setShortcutId(shortcutId: string): Notification { - this._shortcutId = shortcutId; - return this._notification; - } - - /** - * - * @param showWhen - * @returns {Notification} - */ - setShowWhen(showWhen: boolean): Notification { - this._showWhen = showWhen; - return this._notification; - } - - /** - * - * @param icon - * @param level - * @returns {Notification} - */ - setSmallIcon(icon: string, level?: number): Notification { - this._smallIcon = { - icon, - level, - }; - return this._notification; - } - - /** - * - * @param sortKey - * @returns {Notification} - */ - setSortKey(sortKey: string): Notification { - this._sortKey = sortKey; - return this._notification; - } - - /** - * - * @param tag - * @returns {Notification} - */ - setTag(tag: string): Notification { - this._tag = tag; - return this._notification; - } - - /** - * - * @param ticker - * @returns {Notification} - */ - setTicker(ticker: string): Notification { - this._ticker = ticker; - return this._notification; - } - - /** - * - * @param timeoutAfter - * @returns {Notification} - */ - setTimeoutAfter(timeoutAfter: number): Notification { - this._timeoutAfter = timeoutAfter; - return this._notification; - } - - /** - * - * @param usesChronometer - * @returns {Notification} - */ - setUsesChronometer(usesChronometer: boolean): Notification { - this._usesChronometer = usesChronometer; - return this._notification; - } - - /** - * - * @param vibrate - * @returns {Notification} - */ - setVibrate(vibrate: number[]): Notification { - this._vibrate = vibrate; - return this._notification; - } - - /** - * - * @param visibility - * @returns {Notification} - */ - setVisibility(visibility: VisibilityType): Notification { - this._visibility = visibility; - return this._notification; - } - - /** - * - * @param when - * @returns {Notification} - */ - setWhen(when: number): Notification { - this._when = when; - return this._notification; - } - - build(): NativeAndroidNotification { - // TODO: Validation of required fields - if (!this._channelId) { - throw new Error( - 'AndroidNotification: Missing required `channelId` property' - ); - } else if (!this._smallIcon) { - throw new Error( - 'AndroidNotification: Missing required `smallIcon` property' - ); - } - - return { - actions: this._actions.map(action => action.build()), - autoCancel: this._autoCancel, - badgeIconType: this._badgeIconType, - bigPicture: this._bigPicture, - bigText: this._bigText, - category: this._category, - channelId: this._channelId, - clickAction: this._clickAction, - color: this._color, - colorized: this._colorized, - contentInfo: this._contentInfo, - defaults: this._defaults, - group: this._group, - groupAlertBehaviour: this._groupAlertBehaviour, - groupSummary: this._groupSummary, - largeIcon: this._largeIcon, - lights: this._lights, - localOnly: this._localOnly, - number: this._number, - ongoing: this._ongoing, - onlyAlertOnce: this._onlyAlertOnce, - people: this._people, - priority: this._priority, - progress: this._progress, - // publicVersion: this._publicVersion, - remoteInputHistory: this._remoteInputHistory, - shortcutId: this._shortcutId, - showWhen: this._showWhen, - smallIcon: this._smallIcon, - sortKey: this._sortKey, - // TODO: style: Style, - tag: this._tag, - ticker: this._ticker, - timeoutAfter: this._timeoutAfter, - usesChronometer: this._usesChronometer, - vibrate: this._vibrate, - visibility: this._visibility, - when: this._when, - }; - } -} diff --git a/src/modules/notifications/AndroidNotifications.js b/src/modules/notifications/AndroidNotifications.js deleted file mode 100644 index c697d6fd..00000000 --- a/src/modules/notifications/AndroidNotifications.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @flow - * AndroidNotifications representation wrapper - */ -import { Platform } from 'react-native'; -import AndroidChannel from './AndroidChannel'; -import AndroidChannelGroup from './AndroidChannelGroup'; -import { getNativeModule } from '../../utils/native'; - -import type Notifications from './'; - -export default class AndroidNotifications { - _notifications: Notifications; - - constructor(notifications: Notifications) { - this._notifications = notifications; - } - - createChannel(channel: AndroidChannel): Promise { - if (Platform.OS === 'android') { - if (!(channel instanceof AndroidChannel)) { - throw new Error( - `AndroidNotifications:createChannel expects an 'AndroidChannel' but got type ${typeof channel}` - ); - } - return getNativeModule(this._notifications).createChannel( - channel.build() - ); - } - return Promise.resolve(); - } - - createChannelGroup(channelGroup: AndroidChannelGroup): Promise { - if (Platform.OS === 'android') { - if (!(channelGroup instanceof AndroidChannelGroup)) { - throw new Error( - `AndroidNotifications:createChannelGroup expects an 'AndroidChannelGroup' but got type ${typeof channelGroup}` - ); - } - return getNativeModule(this._notifications).createChannelGroup( - channelGroup.build() - ); - } - return Promise.resolve(); - } - - createChannelGroups(channelGroups: AndroidChannelGroup[]): Promise { - if (Platform.OS === 'android') { - if (!Array.isArray(channelGroups)) { - throw new Error( - `AndroidNotifications:createChannelGroups expects an 'Array' but got type ${typeof channelGroups}` - ); - } - const nativeChannelGroups = []; - for (let i = 0; i < channelGroups.length; i++) { - const channelGroup = channelGroups[i]; - if (!(channelGroup instanceof AndroidChannelGroup)) { - throw new Error( - `AndroidNotifications:createChannelGroups expects array items of type 'AndroidChannelGroup' but got type ${typeof channelGroup}` - ); - } - nativeChannelGroups.push(channelGroup.build()); - } - return getNativeModule(this._notifications).createChannelGroups( - nativeChannelGroups - ); - } - return Promise.resolve(); - } - - createChannels(channels: AndroidChannel[]): Promise { - if (Platform.OS === 'android') { - if (!Array.isArray(channels)) { - throw new Error( - `AndroidNotifications:createChannels expects an 'Array' but got type ${typeof channels}` - ); - } - const nativeChannels = []; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - if (!(channel instanceof AndroidChannel)) { - throw new Error( - `AndroidNotifications:createChannels expects array items of type 'AndroidChannel' but got type ${typeof channel}` - ); - } - nativeChannels.push(channel.build()); - } - return getNativeModule(this._notifications).createChannels( - nativeChannels - ); - } - return Promise.resolve(); - } - - removeDeliveredNotificationsByTag(tag: string): Promise { - if (Platform.OS === 'android') { - if (typeof tag !== 'string') { - throw new Error( - `AndroidNotifications:removeDeliveredNotificationsByTag expects an 'string' but got type ${typeof tag}` - ); - } - return getNativeModule( - this._notifications - ).removeDeliveredNotificationsByTag(tag); - } - return Promise.resolve(); - } - - deleteChannelGroup(groupId: string): Promise { - if (Platform.OS === 'android') { - if (typeof groupId !== 'string') { - throw new Error( - `AndroidNotifications:deleteChannelGroup expects an 'string' but got type ${typeof groupId}` - ); - } - return getNativeModule(this._notifications).deleteChannelGroup(groupId); - } - return Promise.resolve(); - } - - deleteChannel(channelId: string): Promise { - if (Platform.OS === 'android') { - if (typeof channelId !== 'string') { - throw new Error( - `AndroidNotifications:deleteChannel expects an 'string' but got type ${typeof channelId}` - ); - } - return getNativeModule(this._notifications).deleteChannel(channelId); - } - return Promise.resolve(); - } -} diff --git a/src/modules/notifications/AndroidRemoteInput.js b/src/modules/notifications/AndroidRemoteInput.js deleted file mode 100644 index f04ff47e..00000000 --- a/src/modules/notifications/AndroidRemoteInput.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @flow - * AndroidRemoteInput representation wrapper - */ - -import type { AndroidAllowDataType, NativeAndroidRemoteInput } from './types'; - -export default class AndroidRemoteInput { - _allowedDataTypes: AndroidAllowDataType[]; - - _allowFreeFormInput: boolean | void; - - _choices: string[]; - - _label: string | void; - - _resultKey: string; - - constructor(resultKey: string) { - this._allowedDataTypes = []; - this._choices = []; - this._resultKey = resultKey; - } - - get allowedDataTypes(): AndroidAllowDataType[] { - return this._allowedDataTypes; - } - - get allowFreeFormInput(): ?boolean { - return this._allowFreeFormInput; - } - - get choices(): string[] { - return this._choices; - } - - get label(): ?string { - return this._label; - } - - get resultKey(): string { - return this._resultKey; - } - - /** - * - * @param mimeType - * @param allow - * @returns {AndroidRemoteInput} - */ - setAllowDataType(mimeType: string, allow: boolean): AndroidRemoteInput { - this._allowedDataTypes.push({ - allow, - mimeType, - }); - return this; - } - - /** - * - * @param allowFreeFormInput - * @returns {AndroidRemoteInput} - */ - setAllowFreeFormInput(allowFreeFormInput: boolean): AndroidRemoteInput { - this._allowFreeFormInput = allowFreeFormInput; - return this; - } - - /** - * - * @param choices - * @returns {AndroidRemoteInput} - */ - setChoices(choices: string[]): AndroidRemoteInput { - this._choices = choices; - return this; - } - - /** - * - * @param label - * @returns {AndroidRemoteInput} - */ - setLabel(label: string): AndroidRemoteInput { - this._label = label; - return this; - } - - build(): NativeAndroidRemoteInput { - if (!this._resultKey) { - throw new Error( - 'AndroidRemoteInput: Missing required `resultKey` property' - ); - } - - return { - allowedDataTypes: this._allowedDataTypes, - allowFreeFormInput: this._allowFreeFormInput, - choices: this._choices, - label: this._label, - resultKey: this._resultKey, - }; - } -} - -export const fromNativeAndroidRemoteInput = ( - nativeRemoteInput: NativeAndroidRemoteInput -): AndroidRemoteInput => { - const remoteInput = new AndroidRemoteInput(nativeRemoteInput.resultKey); - if (nativeRemoteInput.allowedDataTypes) { - for (let i = 0; i < nativeRemoteInput.allowedDataTypes.length; i++) { - const allowDataType = nativeRemoteInput.allowedDataTypes[i]; - remoteInput.setAllowDataType(allowDataType.mimeType, allowDataType.allow); - } - } - if (nativeRemoteInput.allowFreeFormInput) { - remoteInput.setAllowFreeFormInput(nativeRemoteInput.allowFreeFormInput); - } - if (nativeRemoteInput.choices) { - remoteInput.setChoices(nativeRemoteInput.choices); - } - if (nativeRemoteInput.label) { - remoteInput.setLabel(nativeRemoteInput.label); - } - - return remoteInput; -}; diff --git a/src/modules/notifications/IOSNotification.js b/src/modules/notifications/IOSNotification.js deleted file mode 100644 index aad3f0df..00000000 --- a/src/modules/notifications/IOSNotification.js +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @flow - * IOSNotification representation wrapper - */ -import type Notification from './Notification'; -import type Notifications from './'; -import { type BackgroundFetchResultValue } from './IOSNotifications'; -import type { - IOSAttachment, - IOSAttachmentOptions, - NativeIOSNotification, -} from './types'; - -import { isIOS } from '../../utils'; -import { getLogger } from '../../utils/log'; -import { getNativeModule } from '../../utils/native'; - -type CompletionHandler = BackgroundFetchResultValue => void; - -export default class IOSNotification { - _alertAction: string | void; - - _attachments: IOSAttachment[]; - - _badge: number | void; - - _category: string | void; - - _hasAction: boolean | void; - - _launchImage: string | void; - - _notification: Notification; - - _threadIdentifier: string | void; - - _complete: CompletionHandler; - - constructor( - notification: Notification, - notifications?: Notifications, - data?: NativeIOSNotification - ) { - this._notification = notification; - - if (data) { - this._alertAction = data.alertAction; - this._attachments = data.attachments || []; - this._badge = data.badge; - this._category = data.category; - this._hasAction = data.hasAction; - this._launchImage = data.launchImage; - this._threadIdentifier = data.threadIdentifier; - } else { - this._attachments = []; - } - - if (!isIOS || !notifications || !notifications.ios) { - return this; - } - - // IOS + Native Notification Only - const complete = (fetchResult: BackgroundFetchResultValue) => { - const { notificationId } = notification; - // && notifications check for Flow - if (notificationId && notifications) { - getLogger(notifications).debug( - `Completion handler called for notificationId=${notificationId}` - ); - getNativeModule(notifications).complete(notificationId, fetchResult); - } - }; - - if (notifications.ios.shouldAutoComplete) { - complete(notifications.ios.backgroundFetchResult.noData); - } else { - this._complete = complete; - } - } - - get alertAction(): ?string { - return this._alertAction; - } - - get attachments(): IOSAttachment[] { - return this._attachments; - } - - get badge(): ?number { - return this._badge; - } - - get category(): ?string { - return this._category; - } - - get hasAction(): ?boolean { - return this._hasAction; - } - - get launchImage(): ?string { - return this._launchImage; - } - - get threadIdentifier(): ?string { - return this._threadIdentifier; - } - - get complete(): CompletionHandler { - return this._complete; - } - - /** - * - * @param identifier - * @param url - * @param options - * @returns {Notification} - */ - addAttachment( - identifier: string, - url: string, - options?: IOSAttachmentOptions - ): Notification { - this._attachments.push({ - identifier, - options, - url, - }); - return this._notification; - } - - /** - * - * @param alertAction - * @returns {Notification} - */ - setAlertAction(alertAction: string): Notification { - this._alertAction = alertAction; - return this._notification; - } - - /** - * - * @param badge - * @returns {Notification} - */ - setBadge(badge: number): Notification { - this._badge = badge; - return this._notification; - } - - /** - * - * @param category - * @returns {Notification} - */ - setCategory(category: string): Notification { - this._category = category; - return this._notification; - } - - /** - * - * @param hasAction - * @returns {Notification} - */ - setHasAction(hasAction: boolean): Notification { - this._hasAction = hasAction; - return this._notification; - } - - /** - * - * @param launchImage - * @returns {Notification} - */ - setLaunchImage(launchImage: string): Notification { - this._launchImage = launchImage; - return this._notification; - } - - /** - * - * @param threadIdentifier - * @returns {Notification} - */ - setThreadIdentifier(threadIdentifier: string): Notification { - this._threadIdentifier = threadIdentifier; - return this._notification; - } - - build(): NativeIOSNotification { - // TODO: Validation of required fields - - return { - alertAction: this._alertAction, - attachments: this._attachments, - badge: this._badge, - category: this._category, - hasAction: this._hasAction, - launchImage: this._launchImage, - threadIdentifier: this._threadIdentifier, - }; - } -} diff --git a/src/modules/notifications/IOSNotifications.js b/src/modules/notifications/IOSNotifications.js deleted file mode 100644 index f2ea8caf..00000000 --- a/src/modules/notifications/IOSNotifications.js +++ /dev/null @@ -1,31 +0,0 @@ -import { getNativeModule } from '../../utils/native'; - -import type Notifications from './'; - -export type BackgroundFetchResultValue = string; -type BackgroundFetchResult = { - noData: BackgroundFetchResultValue, - newData: BackgroundFetchResultValue, - failure: BackgroundFetchResultValue, -}; - -export default class IOSNotifications { - _backgroundFetchResult: BackgroundFetchResult; - - shouldAutoComplete: boolean; - - constructor(notifications: Notifications) { - this.shouldAutoComplete = true; - - const nativeModule = getNativeModule(notifications); - this._backgroundFetchResult = { - noData: nativeModule.backgroundFetchResultNoData, - newData: nativeModule.backgroundFetchResultNewData, - failure: nativeModule.backgroundFetchResultFailed, - }; - } - - get backgroundFetchResult(): BackgroundFetchResult { - return { ...this._backgroundFetchResult }; - } -} diff --git a/src/modules/notifications/Notification.js b/src/modules/notifications/Notification.js deleted file mode 100644 index 80d68124..00000000 --- a/src/modules/notifications/Notification.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * @flow - * Notification representation wrapper - */ -import { Platform } from 'react-native'; -import AndroidNotification from './AndroidNotification'; -import IOSNotification from './IOSNotification'; -import { generatePushID, isObject } from '../../utils'; - -import type { NativeNotification } from './types'; -import type Notifications from './'; - -export type NotificationOpen = {| - action: string, - notification: Notification, - results?: { [string]: string }, -|}; - -export default class Notification { - // iOS 8/9 | 10+ | Android - _android: AndroidNotification; - - _body: string; - - // alertBody | body | contentText - _data: { [string]: string }; - - // userInfo | userInfo | extras - _ios: IOSNotification; - - _notificationId: string; - - _sound: string | void; - - // soundName | sound | sound - _subtitle: string | void; - - // N/A | subtitle | subText - _title: string; // alertTitle | title | contentTitle - - constructor( - nativeNotification?: NativeNotification, - notifications?: Notifications - ) { - if (nativeNotification) { - this._body = nativeNotification.body; - this._data = nativeNotification.data; - this._notificationId = nativeNotification.notificationId; - this._sound = nativeNotification.sound; - this._subtitle = nativeNotification.subtitle; - this._title = nativeNotification.title; - } - - this._android = new AndroidNotification( - this, - nativeNotification && nativeNotification.android - ); - - this._ios = new IOSNotification( - this, - notifications, - nativeNotification && nativeNotification.ios - ); - - // Defaults - this._data = this._data || {}; - // TODO: Is this the best way to generate an ID? - this._notificationId = this._notificationId || generatePushID(); - } - - get android(): AndroidNotification { - return this._android; - } - - get body(): string { - return this._body; - } - - get data(): { [string]: string } { - return this._data; - } - - get ios(): IOSNotification { - return this._ios; - } - - get notificationId(): string { - return this._notificationId; - } - - get sound(): ?string { - return this._sound; - } - - get subtitle(): ?string { - return this._subtitle; - } - - get title(): string { - return this._title; - } - - /** - * - * @param body - * @returns {Notification} - */ - setBody(body: string): Notification { - this._body = body; - return this; - } - - /** - * - * @param data - * @returns {Notification} - */ - setData(data: Object = {}): Notification { - if (!isObject(data)) { - throw new Error( - `Notification:withData expects an object but got type '${typeof data}'.` - ); - } - this._data = data; - return this; - } - - /** - * - * @param notificationId - * @returns {Notification} - */ - setNotificationId(notificationId: string): Notification { - this._notificationId = notificationId; - return this; - } - - /** - * - * @param sound - * @returns {Notification} - */ - setSound(sound: string): Notification { - this._sound = sound; - return this; - } - - /** - * - * @param subtitle - * @returns {Notification} - */ - setSubtitle(subtitle: string): Notification { - this._subtitle = subtitle; - return this; - } - - /** - * - * @param title - * @returns {Notification} - */ - setTitle(title: string): Notification { - this._title = title; - return this; - } - - build(): NativeNotification { - if (!this._notificationId) { - throw new Error( - 'Notification: Missing required `notificationId` property' - ); - } - - return { - android: Platform.OS === 'android' ? this._android.build() : undefined, - body: this._body, - data: this._data, - ios: Platform.OS === 'ios' ? this._ios.build() : undefined, - notificationId: this._notificationId, - sound: this._sound, - subtitle: this._subtitle, - title: this._title, - }; - } -} diff --git a/src/modules/notifications/index.js b/src/modules/notifications/index.js deleted file mode 100644 index 34e4ee30..00000000 --- a/src/modules/notifications/index.js +++ /dev/null @@ -1,348 +0,0 @@ -/** - * @flow - * Notifications representation wrapper - */ -import { Platform } from 'react-native'; -import { SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; -import { isFunction, isObject } from '../../utils'; -import AndroidAction from './AndroidAction'; -import AndroidChannel from './AndroidChannel'; -import AndroidChannelGroup from './AndroidChannelGroup'; -import AndroidNotifications from './AndroidNotifications'; -import IOSNotifications from './IOSNotifications'; -import AndroidRemoteInput from './AndroidRemoteInput'; -import Notification from './Notification'; -import { - BadgeIconType, - Category, - Defaults, - GroupAlert, - Importance, - Priority, - SemanticAction, - Visibility, -} from './types'; - -import type App from '../core/app'; -import type { NotificationOpen } from './Notification'; -import type { - NativeNotification, - NativeNotificationOpen, - Schedule, -} from './types'; - -type OnNotification = Notification => any; - -type OnNotificationObserver = { - next: OnNotification, -}; - -type OnNotificationOpened = NotificationOpen => any; - -type OnNotificationOpenedObserver = { - next: NotificationOpen, -}; - -const NATIVE_EVENTS = [ - 'notifications_notification_displayed', - 'notifications_notification_opened', - 'notifications_notification_received', -]; - -export const MODULE_NAME = 'RNFirebaseNotifications'; -export const NAMESPACE = 'notifications'; - -// iOS 8/9 scheduling -// fireDate: Date; -// timeZone: TimeZone; -// repeatInterval: NSCalendar.Unit; -// repeatCalendar: Calendar; -// region: CLRegion; -// regionTriggersOnce: boolean; - -// iOS 10 scheduling -// TODO - -// Android scheduling -// TODO - -/** - * @class Notifications - */ -export default class Notifications extends ModuleBase { - _android: AndroidNotifications; - - _ios: IOSNotifications; - - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - hasCustomUrlSupport: false, - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - namespace: NAMESPACE, - }); - this._android = new AndroidNotifications(this); - this._ios = new IOSNotifications(this); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onNotificationDisplayed - 'notifications_notification_displayed', - (notification: NativeNotification) => { - SharedEventEmitter.emit( - 'onNotificationDisplayed', - new Notification(notification, this) - ); - } - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onNotificationOpened - 'notifications_notification_opened', - (notificationOpen: NativeNotificationOpen) => { - SharedEventEmitter.emit('onNotificationOpened', { - action: notificationOpen.action, - notification: new Notification(notificationOpen.notification, this), - results: notificationOpen.results, - }); - } - ); - - SharedEventEmitter.addListener( - // sub to internal native event - this fans out to - // public event name: onNotification - 'notifications_notification_received', - (notification: NativeNotification) => { - SharedEventEmitter.emit( - 'onNotification', - new Notification(notification, this) - ); - } - ); - - // Tell the native module that we're ready to receive events - if (Platform.OS === 'ios') { - getNativeModule(this).jsInitialised(); - } - } - - get android(): AndroidNotifications { - return this._android; - } - - get ios(): IOSNotifications { - return this._ios; - } - - /** - * Cancel all notifications - */ - cancelAllNotifications(): Promise { - return getNativeModule(this).cancelAllNotifications(); - } - - /** - * Cancel a notification by id. - * @param notificationId - */ - cancelNotification(notificationId: string): Promise { - if (!notificationId) { - return Promise.reject( - new Error( - 'Notifications: cancelNotification expects a `notificationId`' - ) - ); - } - return getNativeModule(this).cancelNotification(notificationId); - } - - /** - * Display a notification - * @param notification - * @returns {*} - */ - displayNotification(notification: Notification): Promise { - if (!(notification instanceof Notification)) { - return Promise.reject( - new Error( - `Notifications:displayNotification expects a 'Notification' but got type ${typeof notification}` - ) - ); - } - try { - return getNativeModule(this).displayNotification(notification.build()); - } catch (error) { - return Promise.reject(error); - } - } - - getBadge(): Promise { - return getNativeModule(this).getBadge(); - } - - getInitialNotification(): Promise { - return getNativeModule(this) - .getInitialNotification() - .then((notificationOpen: NativeNotificationOpen) => { - if (notificationOpen) { - return { - action: notificationOpen.action, - notification: new Notification(notificationOpen.notification, this), - results: notificationOpen.results, - }; - } - return null; - }); - } - - /** - * Returns an array of all scheduled notifications - * @returns {Promise.} - */ - getScheduledNotifications(): Promise { - return getNativeModule(this).getScheduledNotifications(); - } - - onNotification( - nextOrObserver: OnNotification | OnNotificationObserver - ): () => any { - let listener; - if (isFunction(nextOrObserver)) { - listener = nextOrObserver; - } else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) { - listener = nextOrObserver.next; - } else { - throw new Error( - 'Notifications.onNotification failed: First argument must be a function or observer object with a `next` function.' - ); - } - - getLogger(this).info('Creating onNotification listener'); - SharedEventEmitter.addListener('onNotification', listener); - - return () => { - getLogger(this).info('Removing onNotification listener'); - SharedEventEmitter.removeListener('onNotification', listener); - }; - } - - onNotificationDisplayed( - nextOrObserver: OnNotification | OnNotificationObserver - ): () => any { - let listener; - if (isFunction(nextOrObserver)) { - listener = nextOrObserver; - } else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) { - listener = nextOrObserver.next; - } else { - throw new Error( - 'Notifications.onNotificationDisplayed failed: First argument must be a function or observer object with a `next` function.' - ); - } - - getLogger(this).info('Creating onNotificationDisplayed listener'); - SharedEventEmitter.addListener('onNotificationDisplayed', listener); - - return () => { - getLogger(this).info('Removing onNotificationDisplayed listener'); - SharedEventEmitter.removeListener('onNotificationDisplayed', listener); - }; - } - - onNotificationOpened( - nextOrObserver: OnNotificationOpened | OnNotificationOpenedObserver - ): () => any { - let listener; - if (isFunction(nextOrObserver)) { - listener = nextOrObserver; - } else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) { - listener = nextOrObserver.next; - } else { - throw new Error( - 'Notifications.onNotificationOpened failed: First argument must be a function or observer object with a `next` function.' - ); - } - - getLogger(this).info('Creating onNotificationOpened listener'); - SharedEventEmitter.addListener('onNotificationOpened', listener); - - return () => { - getLogger(this).info('Removing onNotificationOpened listener'); - SharedEventEmitter.removeListener('onNotificationOpened', listener); - }; - } - - /** - * Remove all delivered notifications. - */ - removeAllDeliveredNotifications(): Promise { - return getNativeModule(this).removeAllDeliveredNotifications(); - } - - /** - * Remove a delivered notification. - * @param notificationId - */ - removeDeliveredNotification(notificationId: string): Promise { - if (!notificationId) { - return Promise.reject( - new Error( - 'Notifications: removeDeliveredNotification expects a `notificationId`' - ) - ); - } - return getNativeModule(this).removeDeliveredNotification(notificationId); - } - - /** - * Schedule a notification - * @param notification - * @returns {*} - */ - scheduleNotification( - notification: Notification, - schedule: Schedule - ): Promise { - if (!(notification instanceof Notification)) { - return Promise.reject( - new Error( - `Notifications:scheduleNotification expects a 'Notification' but got type ${typeof notification}` - ) - ); - } - try { - const nativeNotification = notification.build(); - nativeNotification.schedule = schedule; - return getNativeModule(this).scheduleNotification(nativeNotification); - } catch (error) { - return Promise.reject(error); - } - } - - setBadge(badge: number): Promise { - return getNativeModule(this).setBadge(badge); - } -} - -export const statics = { - Android: { - Action: AndroidAction, - BadgeIconType, - Category, - Channel: AndroidChannel, - ChannelGroup: AndroidChannelGroup, - Defaults, - GroupAlert, - Importance, - Priority, - RemoteInput: AndroidRemoteInput, - SemanticAction, - Visibility, - }, - Notification, -}; diff --git a/src/modules/notifications/types.js b/src/modules/notifications/types.js deleted file mode 100644 index f51e9da2..00000000 --- a/src/modules/notifications/types.js +++ /dev/null @@ -1,232 +0,0 @@ -/** - * @flow - */ -export const BadgeIconType = { - Large: 2, - None: 0, - Small: 1, -}; - -export const Category = { - Alarm: 'alarm', - Call: 'call', - Email: 'email', - Error: 'err', - Event: 'event', - Message: 'msg', - Progress: 'progress', - Promo: 'promo', - Recommendation: 'recommendation', - Reminder: 'reminder', - Service: 'service', - Social: 'social', - Status: 'status', - System: 'system', - Transport: 'transport', -}; - -export const Defaults = { - All: -1, - Lights: 4, - Sound: 1, - Vibrate: 2, -}; - -export const GroupAlert = { - All: 0, - Children: 2, - Summary: 1, -}; - -export const Importance = { - Default: 3, - High: 4, - Low: 2, - Max: 5, - Min: 1, - None: 0, - Unspecified: -1000, -}; - -export const Priority = { - Default: 0, - High: 1, - Low: -1, - Max: 2, - Min: -2, -}; - -export const SemanticAction = { - Archive: 5, - Call: 10, - Delete: 4, - MarkAsRead: 2, - MarkAsUnread: 3, - Mute: 6, - None: 0, - Reply: 1, - ThumbsDown: 9, - ThumbsUp: 8, - Unmute: 7, -}; - -export const Visibility = { - Private: 0, - Public: 1, - Secret: -1, -}; - -export type BadgeIconTypeType = $Values; -export type CategoryType = $Values; -export type DefaultsType = $Values; -export type GroupAlertType = $Values; -export type ImportanceType = $Values; -export type PriorityType = $Values; -export type SemanticActionType = $Values; -export type VisibilityType = $Values; - -export type BigPicture = {| - contentTitle?: string, - largeIcon?: string, - picture: string, - summaryText?: string, -|}; - -export type BigText = {| - contentTitle?: string, - summaryText?: string, - text: string, -|}; - -export type Lights = {| - argb: number, - onMs: number, - offMs: number, -|}; - -export type Progress = {| - max: number, - progress: number, - indeterminate: boolean, -|}; - -export type SmallIcon = {| - icon: string, - level?: number, -|}; - -export type AndroidAllowDataType = { - allow: boolean, - mimeType: string, -}; - -export type NativeAndroidRemoteInput = {| - allowedDataTypes: AndroidAllowDataType[], - allowFreeFormInput?: boolean, - choices: string[], - label?: string, - resultKey: string, -|}; - -export type NativeAndroidAction = {| - action: string, - allowGeneratedReplies?: boolean, - icon: string, - remoteInputs: NativeAndroidRemoteInput[], - semanticAction?: SemanticActionType, - showUserInterface?: boolean, - title: string, -|}; - -export type NativeAndroidNotification = {| - actions?: NativeAndroidAction[], - autoCancel?: boolean, - badgeIconType?: BadgeIconTypeType, - bigPicture?: BigPicture, - bigText?: BigText, - category?: CategoryType, - channelId: string, - clickAction?: string, - color?: string, - colorized?: boolean, - contentInfo?: string, - defaults?: DefaultsType[], - group?: string, - groupAlertBehaviour?: GroupAlertType, - groupSummary?: boolean, - largeIcon?: string, - lights?: Lights, - localOnly?: boolean, - number?: number, - ongoing?: boolean, - onlyAlertOnce?: boolean, - people: string[], - priority?: PriorityType, - progress?: Progress, - // publicVersion: Notification, - remoteInputHistory?: string[], - shortcutId?: string, - showWhen?: boolean, - smallIcon: SmallIcon, - sortKey?: string, - // TODO: style: Style, - tag?: string, - ticker?: string, - timeoutAfter?: number, - usesChronometer?: boolean, - vibrate?: number[], - visibility?: VisibilityType, - when?: number, -|}; - -export type IOSAttachmentOptions = {| - typeHint: string, - thumbnailHidden: boolean, - thumbnailClippingRect: { - height: number, - width: number, - x: number, - y: number, - }, - thumbnailTime: number, -|}; - -export type IOSAttachment = {| - identifier: string, - options?: IOSAttachmentOptions, - url: string, -|}; - -export type NativeIOSNotification = {| - alertAction?: string, - attachments: IOSAttachment[], - badge?: number, - category?: string, - hasAction?: boolean, - launchImage?: string, - threadIdentifier?: string, -|}; - -export type Schedule = {| - exact?: boolean, - fireDate: number, - repeatInterval?: 'minute' | 'hour' | 'day' | 'week', -|}; - -export type NativeNotification = {| - android?: NativeAndroidNotification, - body: string, - data: { [string]: string }, - ios?: NativeIOSNotification, - notificationId: string, - schedule?: Schedule, - sound?: string, - subtitle?: string, - title: string, -|}; - -export type NativeNotificationOpen = {| - action: string, - notification: NativeNotification, - results?: { [string]: string }, -|}; diff --git a/src/modules/perf/HttpMetric.js b/src/modules/perf/HttpMetric.js deleted file mode 100644 index 7016f3a9..00000000 --- a/src/modules/perf/HttpMetric.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @flow - * Trace representation wrapper - */ -import { getNativeModule } from '../../utils/native'; -import type PerformanceMonitoring from './'; - -export default class HttpMetric { - url: string; - - httpMethod: string; - - _perf: PerformanceMonitoring; - - constructor(perf: PerformanceMonitoring, url: string, httpMethod: string) { - this._perf = perf; - this.url = url; - this.httpMethod = httpMethod; - } - - getAttribute(attribute: string): Promise { - return getNativeModule(this._perf).getHttpMetricAttribute( - this.url, - this.httpMethod, - attribute - ); - } - - getAttributes(): Promise { - return getNativeModule(this._perf).getHttpMetricAttributes( - this.url, - this.httpMethod - ); - } - - putAttribute(attribute: string, value: string): Promise { - return getNativeModule(this._perf).putHttpMetricAttribute( - this.url, - this.httpMethod, - attribute, - value - ); - } - - removeAttribute(attribute: string): Promise { - return getNativeModule(this._perf).removeHttpMetricAttribute( - this.url, - this.httpMethod, - attribute - ); - } - - setHttpResponseCode(code: number): Promise { - return getNativeModule(this._perf).setHttpMetricResponseCode( - this.url, - this.httpMethod, - code - ); - } - - setRequestPayloadSize(bytes: number): Promise { - return getNativeModule(this._perf).setHttpMetricRequestPayloadSize( - this.url, - this.httpMethod, - bytes - ); - } - - setResponseContentType(type: string): Promise { - return getNativeModule(this._perf).setHttpMetricResponseContentType( - this.url, - this.httpMethod, - type - ); - } - - setResponsePayloadSize(bytes: number): Promise { - return getNativeModule(this._perf).setHttpMetricResponsePayloadSize( - this.url, - this.httpMethod, - bytes - ); - } - - start(): Promise { - return getNativeModule(this._perf).startHttpMetric( - this.url, - this.httpMethod - ); - } - - stop(): Promise { - return getNativeModule(this._perf).stopHttpMetric( - this.url, - this.httpMethod - ); - } -} diff --git a/src/modules/perf/Trace.js b/src/modules/perf/Trace.js deleted file mode 100644 index 3a84f39f..00000000 --- a/src/modules/perf/Trace.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @flow - * Trace representation wrapper - */ -import { getNativeModule } from '../../utils/native'; -import type PerformanceMonitoring from './'; - -export default class Trace { - identifier: string; - - _perf: PerformanceMonitoring; - - constructor(perf: PerformanceMonitoring, identifier: string) { - this._perf = perf; - this.identifier = identifier; - } - - getAttribute(attribute: string): Promise { - return getNativeModule(this._perf).getTraceAttribute( - this.identifier, - attribute - ); - } - - getAttributes(): Promise { - return getNativeModule(this._perf).getTraceAttributes(this.identifier); - } - - getMetric(metricName: string): Promise { - return getNativeModule(this._perf).getTraceLongMetric( - this.identifier, - metricName - ); - } - - incrementMetric(metricName: string, incrementBy: number): Promise { - return getNativeModule(this._perf).incrementTraceMetric( - this.identifier, - metricName, - incrementBy - ); - } - - putAttribute(attribute: string, value: string): Promise { - return getNativeModule(this._perf).putTraceAttribute( - this.identifier, - attribute, - value - ); - } - - putMetric(metricName: string, value: number): Promise { - return getNativeModule(this._perf).putTraceMetric( - this.identifier, - metricName, - value - ); - } - - removeAttribute(attribute: string): Promise { - return getNativeModule(this._perf).removeTraceAttribute( - this.identifier, - attribute - ); - } - - start(): Promise { - return getNativeModule(this._perf).startTrace(this.identifier); - } - - stop(): Promise { - return getNativeModule(this._perf).stopTrace(this.identifier); - } -} diff --git a/src/modules/perf/index.js b/src/modules/perf/index.js deleted file mode 100644 index bb3dc2a4..00000000 --- a/src/modules/perf/index.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @flow - * Performance monitoring representation wrapper - */ -import Trace from './Trace'; -import HttpMetric from './HttpMetric'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -export const MODULE_NAME = 'RNFirebasePerformance'; -export const NAMESPACE = 'perf'; - -const HTTP_METHODS = { - CONNECT: true, - DELETE: true, - GET: true, - HEAD: true, - OPTIONS: true, - PATCH: true, - POST: true, - PUT: true, - TRACE: true, -}; - -type HttpMethod = - | 'CONNECT' - | 'DELETE' - | 'GET' - | 'HEAD' - | 'OPTIONS' - | 'PATCH' - | 'POST' - | 'PUT' - | 'TRACE'; - -export default class PerformanceMonitoring extends ModuleBase { - constructor(app: App) { - super(app, { - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - } - - /** - * Globally enable or disable performance monitoring - * @param enabled - * @returns {*} - */ - setPerformanceCollectionEnabled(enabled: boolean): void { - if (typeof enabled !== 'boolean') { - throw new Error( - 'firebase.perf().setPerformanceCollectionEnabled() requires a boolean value' - ); - } - - return getNativeModule(this).setPerformanceCollectionEnabled(enabled); - } - - /** - * Returns a new trace instance - * @param trace - */ - newTrace(trace: string): Trace { - if (typeof trace !== 'string') { - throw new Error('firebase.perf().newTrace() requires a string value'); - } - - return new Trace(this, trace); - } - - /** - * Return a new HttpMetric instance - * @param url - * @param httpMethod - * @returns {HttpMetric} - */ - newHttpMetric(url: string, httpMethod: HttpMethod): HttpMetric { - if (typeof url !== 'string' || typeof httpMethod !== 'string') { - throw new Error( - 'firebase.perf().newHttpMetric() requires url and httpMethod string values' - ); - } - - if (!HTTP_METHODS[httpMethod]) { - throw new Error( - `firebase.perf().newHttpMetric() httpMethod should be one of ${Object.keys( - HTTP_METHODS - ).join(', ')}` - ); - } - - return new HttpMetric(this, url, httpMethod); - } -} - -export const statics = {}; diff --git a/src/modules/storage/index.js b/src/modules/storage/index.js deleted file mode 100644 index 08216090..00000000 --- a/src/modules/storage/index.js +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @flow - * Storage representation wrapper - */ -import { NativeModules } from 'react-native'; - -import StorageRef from './reference'; -import { getAppEventName, SharedEventEmitter } from '../../utils/events'; -import { getLogger } from '../../utils/log'; -import { stripTrailingSlash } from '../../utils'; -import ModuleBase from '../../utils/ModuleBase'; -import { getNativeModule } from '../../utils/native'; - -import type App from '../core/app'; - -const FirebaseStorage = NativeModules.RNFirebaseStorage; - -const NATIVE_EVENTS = ['storage_event', 'storage_error']; - -export const MODULE_NAME = 'RNFirebaseStorage'; -export const NAMESPACE = 'storage'; - -export default class Storage extends ModuleBase { - /** - * - * @param app - * @param options - */ - constructor(app: App) { - super(app, { - events: NATIVE_EVENTS, - moduleName: MODULE_NAME, - hasMultiAppSupport: true, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - - SharedEventEmitter.addListener( - getAppEventName(this, 'storage_event'), - this._handleStorageEvent.bind(this) - ); - - SharedEventEmitter.addListener( - getAppEventName(this, 'storage_error'), - this._handleStorageEvent.bind(this) - ); - } - - /** - * Returns a reference for the given path in the default bucket. - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#ref - * @param path - * @returns {StorageReference} - */ - ref(path: string): StorageRef { - return new StorageRef(this, path); - } - - /** - * Returns a reference for the given absolute URL. - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#refFromURL - * @param url - * @returns {StorageReference} - */ - refFromURL(url: string): StorageRef { - // TODO don't think this is correct? - return new StorageRef(this, `url::${url}`); - } - - /** - * setMaxOperationRetryTime - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime - * @param time The new maximum operation retry time in milliseconds. - */ - setMaxOperationRetryTime(time: number): void { - getNativeModule(this).setMaxOperationRetryTime(time); - } - - /** - * setMaxUploadRetryTime - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime - * @param time The new maximum upload retry time in milliseconds. - */ - setMaxUploadRetryTime(time: number): void { - getNativeModule(this).setMaxUploadRetryTime(time); - } - - /** - * setMaxDownloadRetryTime - * @url N/A - * @param time The new maximum download retry time in milliseconds. - */ - setMaxDownloadRetryTime(time: number): void { - getNativeModule(this).setMaxDownloadRetryTime(time); - } - - /** - * INTERNALS - */ - _getSubEventName(path: string, eventName: string) { - return getAppEventName(this, `${path}-${eventName}`); - } - - _handleStorageEvent(event: Object) { - const { path, eventName } = event; - const body = event.body || {}; - - getLogger(this).debug('_handleStorageEvent: ', path, eventName, body); - SharedEventEmitter.emit(this._getSubEventName(path, eventName), body); - } - - _handleStorageError(err: Object) { - const { path, eventName } = err; - const body = err.body || {}; - - getLogger(this).debug('_handleStorageError ->', err); - SharedEventEmitter.emit(this._getSubEventName(path, eventName), body); - } - - _addListener( - path: string, - eventName: string, - cb: (evt: Object) => Object - ): void { - SharedEventEmitter.addListener(this._getSubEventName(path, eventName), cb); - } - - _removeListener( - path: string, - eventName: string, - origCB: (evt: Object) => Object - ): void { - SharedEventEmitter.removeListener( - this._getSubEventName(path, eventName), - origCB - ); - } -} - -export const statics = { - TaskEvent: { - STATE_CHANGED: 'state_changed', - }, - TaskState: { - RUNNING: 'running', - PAUSED: 'paused', - SUCCESS: 'success', - CANCELLED: 'cancelled', - ERROR: 'error', - }, - Native: FirebaseStorage - ? { - MAIN_BUNDLE_PATH: stripTrailingSlash(FirebaseStorage.MAIN_BUNDLE_PATH), - CACHES_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.CACHES_DIRECTORY_PATH - ), - DOCUMENT_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.DOCUMENT_DIRECTORY_PATH - ), - EXTERNAL_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.EXTERNAL_DIRECTORY_PATH - ), - EXTERNAL_STORAGE_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.EXTERNAL_STORAGE_DIRECTORY_PATH - ), - TEMP_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.TEMP_DIRECTORY_PATH - ), - LIBRARY_DIRECTORY_PATH: stripTrailingSlash( - FirebaseStorage.LIBRARY_DIRECTORY_PATH - ), - FILETYPE_REGULAR: stripTrailingSlash(FirebaseStorage.FILETYPE_REGULAR), - FILETYPE_DIRECTORY: stripTrailingSlash( - FirebaseStorage.FILETYPE_DIRECTORY - ), - } - : {}, -}; diff --git a/src/modules/storage/reference.js b/src/modules/storage/reference.js deleted file mode 100644 index 5c8e9c58..00000000 --- a/src/modules/storage/reference.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @flow - * StorageReference representation wrapper - */ -import ReferenceBase from '../../utils/ReferenceBase'; -import StorageTask, { UPLOAD_TASK, DOWNLOAD_TASK } from './task'; -import { getNativeModule } from '../../utils/native'; -import type Storage from './'; - -/** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference - */ -export default class StorageReference extends ReferenceBase { - _storage: Storage; - - constructor(storage: Storage, path: string) { - super(path); - this._storage = storage; - } - - get fullPath(): string { - return this.path; - } - - toString(): string { - return `gs://${this._storage.app.options.storageBucket}${this.path}`; - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#child - * @param path - * @returns {StorageReference} - */ - child(path: string): StorageReference { - return new StorageReference(this._storage, `${this.path}/${path}`); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete - * @returns {Promise.|*} - */ - delete(): Promise { - return getNativeModule(this._storage).delete(this.path); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL - * @returns {Promise.|*} - */ - getDownloadURL(): Promise { - return getNativeModule(this._storage).getDownloadURL(this.path); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata - * @returns {Promise.|*} - */ - getMetadata(): Promise { - return getNativeModule(this._storage).getMetadata(this.path); - } - - /** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata - * @param metadata - * @returns {Promise.|*} - */ - updateMetadata(metadata: Object = {}): Promise { - return getNativeModule(this._storage).updateMetadata(this.path, metadata); - } - - /** - * Downloads a reference to the device - * @param {String} filePath Where to store the file - * @return {Promise} - */ - downloadFile(filePath: string): StorageTask { - return new StorageTask( - DOWNLOAD_TASK, - getNativeModule(this._storage).downloadFile(this.path, filePath), - this - ); - } - - /** - * Alias to putFile - * @returns {StorageReference.putFile} - */ - get put(): (Object, Object) => StorageTask { - return this.putFile; - } - - /** - * Upload a file path - * @param {string} filePath The local path of the file - * @param {object} metadata An object containing metadata - * @return {Promise} - */ - putFile(filePath: Object, metadata: Object = {}): StorageTask { - let _filePath = filePath.replace('file://', ''); - if (_filePath.includes('%')) _filePath = decodeURI(_filePath); - return new StorageTask( - UPLOAD_TASK, - getNativeModule(this._storage).putFile(this.path, _filePath, metadata), - this - ); - } -} diff --git a/src/modules/storage/task.js b/src/modules/storage/task.js deleted file mode 100644 index 7055526a..00000000 --- a/src/modules/storage/task.js +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @flow - * UploadTask representation wrapper - */ -import { statics as StorageStatics } from './'; -import { isFunction } from '../../utils'; -import type Storage from './'; -import type StorageReference from './reference'; - -export const UPLOAD_TASK = 'upload'; -export const DOWNLOAD_TASK = 'download'; - -declare type UploadTaskSnapshotType = { - bytesTransferred: number, - downloadURL: string | null, - metadata: Object, // TODO flow type def for https://firebase.google.com/docs/reference/js/firebase.storage.FullMetadata.html - ref: StorageReference, - state: - | typeof StorageStatics.TaskState.RUNNING - | typeof StorageStatics.TaskState.PAUSED - | typeof StorageStatics.TaskState.SUCCESS - | typeof StorageStatics.TaskState.CANCELLED - | typeof StorageStatics.TaskState.ERROR, - task: StorageTask, - totalBytes: number, -}; - -declare type FuncSnapshotType = - | null - | ((snapshot: UploadTaskSnapshotType) => any); - -declare type FuncErrorType = null | ((error: Error) => any); - -declare type NextOrObserverType = - | null - | { - next?: FuncSnapshotType, - error?: FuncErrorType, - complete?: FuncSnapshotType, - } - | FuncSnapshotType; - -/** - * @url https://firebase.google.com/docs/reference/js/firebase.storage.UploadTask - */ -export default class StorageTask { - type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK; - - ref: StorageReference; - - storage: Storage; - - path: string; - - then: () => Promise<*>; - - catch: () => Promise<*>; - - constructor( - type: typeof UPLOAD_TASK | typeof DOWNLOAD_TASK, - promise: Promise<*>, - storageRef: StorageReference - ) { - this.type = type; - this.ref = storageRef; - this.storage = storageRef._storage; - this.path = storageRef.path; - - // 'proxy' original promise - this.then = promise.then.bind(promise); - this.catch = promise.catch.bind(promise); - } - - /** - * Intercepts a native snapshot result object attaches ref / task instances - * and calls the original function - * @returns {Promise.} - * @private - */ - _interceptSnapshotEvent(f: ?Function): null | (() => *) { - if (!isFunction(f)) return null; - return snapshot => { - const _snapshot = Object.assign({}, snapshot); - _snapshot.task = this; - _snapshot.ref = this.ref; - return f && f(_snapshot); - }; - } - - /** - * Intercepts a error object form native and converts to a JS Error - * @param f - * @returns {*} - * @private - */ - _interceptErrorEvent(f: ?Function): null | (Error => *) { - if (!isFunction(f)) return null; - return error => { - const _error = new Error(error.message); - // $FlowExpectedError - _error.code = error.code; - return f && f(_error); - }; - } - - /** - * - * @param nextOrObserver - * @param error - * @param complete - * @returns {function()} - * @private - */ - _subscribe( - nextOrObserver: NextOrObserverType, - error: FuncErrorType, - complete: FuncSnapshotType - ): Function { - let _error; - let _next; - let _complete; - - if (typeof nextOrObserver === 'function') { - _error = this._interceptErrorEvent(error); - _next = this._interceptSnapshotEvent(nextOrObserver); - _complete = this._interceptSnapshotEvent(complete); - } else if (nextOrObserver) { - _error = this._interceptErrorEvent(nextOrObserver.error); - _next = this._interceptSnapshotEvent(nextOrObserver.next); - _complete = this._interceptSnapshotEvent(nextOrObserver.complete); - } - - if (_next) { - this.storage._addListener( - this.path, - StorageStatics.TaskEvent.STATE_CHANGED, - _next - ); - } - if (_error) { - this.storage._addListener(this.path, `${this.type}_failure`, _error); - } - if (_complete) { - this.storage._addListener(this.path, `${this.type}_success`, _complete); - } - - return () => { - if (_next) - this.storage._removeListener( - this.path, - StorageStatics.TaskEvent.STATE_CHANGED, - _next - ); - if (_error) - this.storage._removeListener(this.path, `${this.type}_failure`, _error); - if (_complete) - this.storage._removeListener( - this.path, - `${this.type}_success`, - _complete - ); - }; - } - - /** - * - * @param event - * @param nextOrObserver - * @param error - * @param complete - * @returns {function()} - */ - on( - event: string = StorageStatics.TaskEvent.STATE_CHANGED, - nextOrObserver: NextOrObserverType, - error: FuncErrorType, - complete: FuncSnapshotType - ): Function { - if (!event) { - throw new Error( - "StorageTask.on listener is missing required string argument 'event'." - ); - } - - if (event !== StorageStatics.TaskEvent.STATE_CHANGED) { - throw new Error( - `StorageTask.on event argument must be a string with a value of '${ - StorageStatics.TaskEvent.STATE_CHANGED - }'` - ); - } - - // if only event provided return the subscriber function - if (!nextOrObserver && !error && !complete) { - return this._subscribe.bind(this); - } - - return this._subscribe(nextOrObserver, error, complete); - } - - pause() { - throw new Error( - '.pause() is not currently supported by react-native-firebase' - ); - } - - resume() { - // todo - throw new Error( - '.resume() is not currently supported by react-native-firebase' - ); - } - - cancel() { - // todo - throw new Error( - '.cancel() is not currently supported by react-native-firebase' - ); - } -} diff --git a/src/modules/utils/database.js b/src/modules/utils/database.js deleted file mode 100644 index 12fda543..00000000 --- a/src/modules/utils/database.js +++ /dev/null @@ -1,12 +0,0 @@ -import SyncTree from '../../utils/SyncTree'; - -export default { - /** - * Removes all database listeners (JS & Native) - */ - cleanup(): void { - SyncTree.removeListenersForRegistrations( - Object.keys(SyncTree._reverseLookup) - ); - }, -}; diff --git a/src/modules/utils/index.js b/src/modules/utils/index.js deleted file mode 100644 index 463de928..00000000 --- a/src/modules/utils/index.js +++ /dev/null @@ -1,125 +0,0 @@ -// @flow -import { NativeModules } from 'react-native'; -import INTERNALS from '../../utils/internals'; -import { isIOS } from '../../utils'; -import ModuleBase from '../../utils/ModuleBase'; -import type App from '../core/app'; -import DatabaseUtils from './database'; - -const FirebaseCoreModule = NativeModules.RNFirebase; - -type GoogleApiAvailabilityType = { - status: number, - isAvailable: boolean, - isUserResolvableError?: boolean, - hasResolution?: boolean, - error?: string, -}; - -export const MODULE_NAME = 'RNFirebaseUtils'; -export const NAMESPACE = 'utils'; - -export default class RNFirebaseUtils extends ModuleBase { - constructor(app: App) { - super(app, { - moduleName: MODULE_NAME, - hasMultiAppSupport: false, - hasCustomUrlSupport: false, - namespace: NAMESPACE, - }); - } - - get database(): DatabaseUtils { - return DatabaseUtils; - } - - /** - * - */ - checkPlayServicesAvailability() { - if (isIOS) return; - - const { status } = this.playServicesAvailability; - - if (!this.playServicesAvailability.isAvailable) { - if ( - INTERNALS.OPTIONS.promptOnMissingPlayServices && - this.playServicesAvailability.isUserResolvableError - ) { - this.promptForPlayServices(); - } else { - const error = INTERNALS.STRINGS.ERROR_PLAY_SERVICES(status); - if (INTERNALS.OPTIONS.errorOnMissingPlayServices) { - if (status === 2) console.warn(error); - // only warn if it exists but may need an update - else throw new Error(error); - } else { - console.warn(error); - } - } - } - } - - getPlayServicesStatus(): Promise { - if (isIOS) return Promise.resolve(null); - return FirebaseCoreModule.getPlayServicesStatus(); - } - - promptForPlayServices() { - if (isIOS) return null; - return FirebaseCoreModule.promptForPlayServices(); - } - - resolutionForPlayServices() { - if (isIOS) return null; - return FirebaseCoreModule.resolutionForPlayServices(); - } - - makePlayServicesAvailable() { - if (isIOS) return null; - return FirebaseCoreModule.makePlayServicesAvailable(); - } - - /** - * Set the global logging level for all logs. - * - * @param logLevel - */ - set logLevel(logLevel: string) { - INTERNALS.OPTIONS.logLevel = logLevel; - } - - /** - * Returns props from the android GoogleApiAvailability sdk - * @android - * @return {RNFirebase.GoogleApiAvailabilityType|{isAvailable: boolean, status: number}} - */ - get playServicesAvailability(): GoogleApiAvailabilityType { - return ( - FirebaseCoreModule.playServicesAvailability || { - isAvailable: true, - status: 0, - } - ); - } - - /** - * Enable/Disable throwing an error or warning on detecting a play services problem - * @android - * @param bool - */ - set errorOnMissingPlayServices(bool: boolean) { - INTERNALS.OPTIONS.errorOnMissingPlayServices = bool; - } - - /** - * Enable/Disable automatic prompting of the play services update dialog - * @android - * @param bool - */ - set promptOnMissingPlayServices(bool: boolean) { - INTERNALS.OPTIONS.promptOnMissingPlayServices = bool; - } -} - -export const statics = {}; diff --git a/src/types/index.js b/src/types/index.js deleted file mode 100644 index bf4dd78b..00000000 --- a/src/types/index.js +++ /dev/null @@ -1,230 +0,0 @@ -/* @flow */ -import type AdMob from '../modules/admob'; -import { typeof statics as AdMobStatics } from '../modules/admob'; -import type Analytics from '../modules/analytics'; -import { typeof statics as AnalyticsStatics } from '../modules/analytics'; -import type Auth from '../modules/auth'; -import { typeof statics as AuthStatics } from '../modules/auth'; -import type Config from '../modules/config'; -import { typeof statics as ConfigStatics } from '../modules/config'; -import type Crashlytics from '../modules/crashlytics'; -import { typeof statics as CrashlyticsStatics } from '../modules/crashlytics'; -import type Database from '../modules/database'; -import { typeof statics as DatabaseStatics } from '../modules/database'; -import type Firestore from '../modules/firestore'; -import { typeof statics as FirestoreStatics } from '../modules/firestore'; -import type Functions from '../modules/functions'; -import { typeof statics as FunctionsStatics } from '../modules/functions'; -import type InstanceId from '../modules/iid'; -import { typeof statics as InstanceIdStatics } from '../modules/iid'; -import type Invites from '../modules/invites'; -import { typeof statics as InvitesStatics } from '../modules/invites'; -import type Links from '../modules/links'; -import { typeof statics as LinksStatics } from '../modules/links'; -import type Messaging from '../modules/messaging'; -import { typeof statics as MessagingStatics } from '../modules/messaging'; -import type Notifications from '../modules/notifications'; -import { typeof statics as NotificationsStatics } from '../modules/notifications'; -import type ModuleBase from '../utils/ModuleBase'; -import type Performance from '../modules/perf'; -import { typeof statics as PerformanceStatics } from '../modules/perf'; -import type Storage from '../modules/storage'; -import { typeof statics as StorageStatics } from '../modules/storage'; -import type Utils from '../modules/utils'; -import { typeof statics as UtilsStatics } from '../modules/utils'; - -/* Core types */ -export type FirebaseError = { - message: string, - name: string, - code: string, - stack: string, - path: string, - details: string, - modifiers: string, -}; - -export type FirebaseModule = $Subtype; - -export type FirebaseModuleConfig = { - events?: string[], - moduleName: FirebaseModuleName, - hasMultiAppSupport: boolean, - hasCustomUrlSupport?: boolean, - hasRegionsSupport?: boolean, - namespace: FirebaseNamespace, -}; - -export type FirebaseModuleName = - | 'RNFirebaseAdMob' - | 'RNFirebaseAnalytics' - | 'RNFirebaseAuth' - | 'RNFirebaseRemoteConfig' - | 'RNFirebaseCrashlytics' - | 'RNFirebaseDatabase' - | 'RNFirebaseFirestore' - | 'RNFirebaseFunctions' - | 'RNFirebaseInstanceId' - | 'RNFirebaseInvites' - | 'RNFirebaseLinks' - | 'RNFirebaseMessaging' - | 'RNFirebaseNotifications' - | 'RNFirebasePerformance' - | 'RNFirebaseStorage' - | 'RNFirebaseUtils'; - -export type FirebaseNamespace = - | 'admob' - | 'analytics' - | 'auth' - | 'config' - | 'crashlytics' - | 'database' - | 'firestore' - | 'functions' - | 'iid' - | 'invites' - | 'links' - | 'messaging' - | 'notifications' - | 'perf' - | 'storage' - | 'utils'; - -export type FirebaseOptions = { - apiKey: string, - appId: string, - databaseURL: string, - messagingSenderId: string, - projectId: string, - storageBucket: string, - persistence?: boolean, -}; - -export type FirebaseModuleAndStatics = { - (): M, - nativeModuleExists: boolean, -} & S; - -export type FirebaseStatics = $Subtype; - -/* Admob types */ - -export type AdMobModule = { - (): AdMob, - nativeModuleExists: boolean, -} & AdMobStatics; - -/* Analytics types */ - -export type AnalyticsModule = { - (): Analytics, - nativeModuleExists: boolean, -} & AnalyticsStatics; - -/* Remote Config types */ - -export type ConfigModule = { - (): Config, - nativeModuleExists: boolean, -} & ConfigStatics; - -/* Auth types */ - -export type AuthModule = { - (): Auth, - nativeModuleExists: boolean, -} & AuthStatics; - -/* Crashlytics types */ -export type CrashlyticsModule = { - (): Crashlytics, - nativeModuleExists: boolean, -} & CrashlyticsStatics; - -/* Database types */ - -export type DatabaseModule = { - (): Database, - nativeModuleExists: boolean, -} & DatabaseStatics; - -export type DatabaseModifier = { - id: string, - type: 'orderBy' | 'limit' | 'filter', - name?: string, - key?: string, - limit?: number, - value?: any, - valueType?: string, -}; - -/* Firestore types */ - -export type FirestoreModule = { - (): Firestore, - nativeModuleExists: boolean, -} & FirestoreStatics; - -/* Functions types */ - -export type FunctionsModule = { - (): Functions, - nativeModuleExists: boolean, -} & FunctionsStatics; - -/* InstanceId types */ - -export type InstanceIdModule = { - (): InstanceId, - nativeModuleExists: boolean, -} & InstanceIdStatics; - -/* Invites types */ - -export type InvitesModule = { - (): Invites, - nativeModuleExists: boolean, -} & InvitesStatics; - -/* Links types */ - -export type LinksModule = { - (): Links, - nativeModuleExists: boolean, -} & LinksStatics; - -/* Messaging types */ - -export type MessagingModule = { - (): Messaging, - nativeModuleExists: boolean, -} & MessagingStatics; - -/* Notifications types */ - -export type NotificationsModule = { - (): Notifications, - nativeModuleExists: boolean, -} & NotificationsStatics; - -/* Performance types */ - -export type PerformanceModule = { - (): Performance, - nativeModuleExists: boolean, -} & PerformanceStatics; - -/* Storage types */ - -export type StorageModule = { - (): Storage, - nativeModuleExists: boolean, -} & StorageStatics; - -/* Utils types */ - -export type UtilsModule = { - (): Utils, - nativeModuleExists: boolean, -} & UtilsStatics; diff --git a/src/utils/Base64.js b/src/utils/Base64.js deleted file mode 100644 index b03b28c3..00000000 --- a/src/utils/Base64.js +++ /dev/null @@ -1,68 +0,0 @@ -// @flow -/* eslint-disable */ - -const CHARS = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - -export default { - /** - * window.btoa - */ - btoa(input: string = ''): string { - let map; - let i = 0; - let block = 0; - let output = ''; - - // eslint-disable-next-line - for ( - block = 0, i = 0, map = CHARS; - input.charAt(i | 0) || ((map = '='), i % 1); - output += map.charAt(63 & (block >> (8 - (i % 1) * 8))) - ) { - const charCode = input.charCodeAt((i += 3 / 4)); - - if (charCode > 0xff) { - throw new Error( - "'RNFirebase.utils.btoa' failed: The string to be encoded contains characters outside of the Latin1 range." - ); - } - - block = (block << 8) | charCode; - } - - return output; - }, - - /** - * window.atob - */ - atob(input: string = ''): string { - let i = 0; - let bc = 0; - let bs = 0; - let buffer; - let output = ''; - - const str = input.replace(/=+$/, ''); - - if (str.length % 4 === 1) { - throw new Error( - "'RNFirebase.utils.atob' failed: The string to be decoded is not correctly encoded." - ); - } - - // eslint-disable-next-line - for ( - bc = 0, bs = 0, i = 0; - (buffer = str.charAt(i++)); - ~buffer && ((bs = bc % 4 ? bs * 64 + buffer : buffer), bc++ % 4) - ? (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) - : 0 - ) { - buffer = CHARS.indexOf(buffer); - } - - return output; - }, -}; diff --git a/src/utils/ModuleBase.js b/src/utils/ModuleBase.js deleted file mode 100644 index 535b7150..00000000 --- a/src/utils/ModuleBase.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @flow - */ -import { initialiseLogger, getLogger } from './log'; -import { initialiseNativeModule } from './native'; - -import type App from '../modules/core/app'; -import type { FirebaseModuleConfig, FirebaseNamespace } from '../types'; - -export default class ModuleBase { - _app: App; - - _customUrlOrRegion: ?string; - - namespace: FirebaseNamespace; - - /** - * - * @param app - * @param config - * @param customUrlOrRegion - */ - constructor( - app: App, - config: FirebaseModuleConfig, - customUrlOrRegion: ?string - ) { - if (!config.moduleName) { - throw new Error('Missing module name'); - } - - if (!config.namespace) { - throw new Error('Missing namespace'); - } - - const { moduleName } = config; - this._app = app; - this._customUrlOrRegion = customUrlOrRegion; - this.namespace = config.namespace; - - // check if native module exists as all native - initialiseNativeModule(this, config, customUrlOrRegion); - - initialiseLogger( - this, - `${app.name}:${moduleName.replace('RNFirebase', '')}` - ); - } - - /** - * Returns the App instance for current module - * @return {*} - */ - get app(): App { - return this._app; - } - - get log() { - return getLogger(this); - } -} diff --git a/src/utils/ReferenceBase.js b/src/utils/ReferenceBase.js deleted file mode 100644 index 32056422..00000000 --- a/src/utils/ReferenceBase.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @flow - */ -export default class ReferenceBase { - path: string; - - constructor(path: string) { - if (path) { - this.path = - path.length > 1 && path.endsWith('/') - ? path.substring(0, path.length - 1) - : path; - } else { - this.path = '/'; - } - } - - /** - * The last part of a Reference's path (after the last '/') - * The key of a root Reference is null. - * @type {String} - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#key} - */ - get key(): string | null { - return this.path === '/' - ? null - : this.path.substring(this.path.lastIndexOf('/') + 1); - } -} diff --git a/src/utils/SyncTree.js b/src/utils/SyncTree.js deleted file mode 100644 index 58d0300a..00000000 --- a/src/utils/SyncTree.js +++ /dev/null @@ -1,336 +0,0 @@ -/** - * @flow - */ -import { NativeEventEmitter, NativeModules } from 'react-native'; - -import { SharedEventEmitter } from './events'; -import DataSnapshot from '../modules/database/DataSnapshot'; -import DatabaseReference from '../modules/database/Reference'; -import { isString, nativeToJSError } from './'; - -type Listener = DataSnapshot => any; - -type Registration = { - key: string, - path: string, - once?: boolean, - appName: string, - eventType: string, - listener: Listener, - eventRegistrationKey: string, - ref: DatabaseReference, -}; - -/** - * Internally used to manage firebase database realtime event - * subscriptions and keep the listeners in sync in js vs native. - */ -class SyncTree { - _nativeEmitter: NativeEventEmitter; - - _reverseLookup: { [string]: Registration }; - - _tree: { [string]: { [string]: { [string]: Listener } } }; - - constructor() { - this._tree = {}; - this._reverseLookup = {}; - if (NativeModules.RNFirebaseDatabase) { - this._nativeEmitter = new NativeEventEmitter( - NativeModules.RNFirebaseDatabase - ); - this._nativeEmitter.addListener( - 'database_sync_event', - this._handleSyncEvent.bind(this) - ); - } - } - - /** - * - * @param event - * @private - */ - _handleSyncEvent(event) { - if (event.error) { - this._handleErrorEvent(event); - } else { - this._handleValueEvent(event); - } - } - - /** - * Routes native database 'on' events to their js equivalent counterpart. - * If there is no longer any listeners remaining for this event we internally - * call the native unsub method to prevent further events coming through. - * - * @param event - * @private - */ - _handleValueEvent(event) { - // console.log('SyncTree.VALUE >>>', event); - const { key, eventRegistrationKey } = event.registration; - const registration = this.getRegistration(eventRegistrationKey); - - if (!registration) { - // registration previously revoked - // notify native that the registration - // no longer exists so it can remove - // the native listeners - return NativeModules.RNFirebaseDatabase.off(key, eventRegistrationKey); - } - - const { snapshot, previousChildName } = event.data; - - // forward on to users .on(successCallback <-- listener - return SharedEventEmitter.emit( - eventRegistrationKey, - new DataSnapshot(registration.ref, snapshot), - previousChildName - ); - } - - /** - * Routes native database query listener cancellation events to their js counterparts. - * - * @param event - * @private - */ - _handleErrorEvent(event) { - // console.log('SyncTree.ERROR >>>', event); - const { code, message } = event.error; - const { - eventRegistrationKey, - registrationCancellationKey, - } = event.registration; - - const registration = this.getRegistration(registrationCancellationKey); - - if (registration) { - // build a new js error - we additionally attach - // the ref as a property for easier debugging - const error = nativeToJSError(code, message, { ref: registration.ref }); - - // forward on to users .on(successCallback, cancellationCallback <-- listener - SharedEventEmitter.emit(registrationCancellationKey, error); - - // remove the paired event registration - if we received a cancellation - // event then it's guaranteed that they'll be no further value events - this.removeRegistration(eventRegistrationKey); - } - } - - /** - * Returns registration information such as appName, ref, path and registration keys. - * - * @param registration - * @return {null} - */ - getRegistration(registration: string): Registration | null { - return this._reverseLookup[registration] - ? Object.assign({}, this._reverseLookup[registration]) - : null; - } - - /** - * Removes all listeners for the specified registration keys. - * - * @param registrations - * @return {number} - */ - removeListenersForRegistrations(registrations: string | string[]): number { - if (isString(registrations)) { - this.removeRegistration(registrations); - SharedEventEmitter.removeAllListeners(registrations); - return 1; - } - - if (!Array.isArray(registrations)) return 0; - for (let i = 0, len = registrations.length; i < len; i++) { - this.removeRegistration(registrations[i]); - SharedEventEmitter.removeAllListeners(registrations[i]); - } - - return registrations.length; - } - - /** - * Removes a specific listener from the specified registrations. - * - * @param listener - * @param registrations - * @return {Array} array of registrations removed - */ - removeListenerRegistrations(listener: () => any, registrations: string[]) { - if (!Array.isArray(registrations)) return []; - const removed = []; - - for (let i = 0, len = registrations.length; i < len; i++) { - const registration = registrations[i]; - const subscriptions = SharedEventEmitter._subscriber.getSubscriptionsForType( - registration - ); - if (subscriptions) { - for (let j = 0, l = subscriptions.length; j < l; j++) { - const subscription = subscriptions[j]; - // The subscription may have been removed during this event loop. - // its listener matches the listener in method parameters - if (subscription && subscription.listener === listener) { - subscription.remove(); - removed.push(registration); - this.removeRegistration(registration); - } - } - } - } - - return removed; - } - - /** - * Returns an array of all registration keys for the specified path. - * - * @param path - * @return {Array} - */ - getRegistrationsByPath(path: string): string[] { - const out = []; - const eventKeys = Object.keys(this._tree[path] || {}); - - for (let i = 0, len = eventKeys.length; i < len; i++) { - Array.prototype.push.apply( - out, - Object.keys(this._tree[path][eventKeys[i]]) - ); - } - - return out; - } - - /** - * Returns an array of all registration keys for the specified path and eventType. - * - * @param path - * @param eventType - * @return {Array} - */ - getRegistrationsByPathEvent(path: string, eventType: string): string[] { - if (!this._tree[path]) return []; - if (!this._tree[path][eventType]) return []; - - return Object.keys(this._tree[path][eventType]); - } - - /** - * Returns a single registration key for the specified path, eventType, and listener - * - * @param path - * @param eventType - * @param listener - * @return {Array} - */ - getOneByPathEventListener( - path: string, - eventType: string, - listener: Function - ): ?string { - if (!this._tree[path]) return null; - if (!this._tree[path][eventType]) return null; - - const registrationsForPathEvent = Object.entries( - this._tree[path][eventType] - ); - - for (let i = 0; i < registrationsForPathEvent.length; i++) { - const registration = registrationsForPathEvent[i]; - if (registration[1] === listener) return registration[0]; - } - - return null; - } - - /** - * Register a new listener. - * - * @param parameters - * @param listener - * @return {String} - */ - addRegistration(registration: Registration): string { - const { - eventRegistrationKey, - eventType, - listener, - once, - path, - } = registration; - - if (!this._tree[path]) this._tree[path] = {}; - if (!this._tree[path][eventType]) this._tree[path][eventType] = {}; - - this._tree[path][eventType][eventRegistrationKey] = listener; - this._reverseLookup[eventRegistrationKey] = registration; - - if (once) { - SharedEventEmitter.once( - eventRegistrationKey, - this._onOnceRemoveRegistration(eventRegistrationKey, listener) - ); - } else { - SharedEventEmitter.addListener(eventRegistrationKey, listener); - } - - return eventRegistrationKey; - } - - /** - * Remove a registration, if it's not a `once` registration then instructs native - * to also remove the underlying database query listener. - * - * @param registration - * @return {boolean} - */ - removeRegistration(registration: string): boolean { - if (!this._reverseLookup[registration]) return false; - const { path, eventType, once } = this._reverseLookup[registration]; - - if (!this._tree[path]) { - delete this._reverseLookup[registration]; - return false; - } - - if (!this._tree[path][eventType]) { - delete this._reverseLookup[registration]; - return false; - } - - // we don't want `once` events to notify native as they're already - // automatically unsubscribed on native when the first event is sent - const registrationObj = this._reverseLookup[registration]; - if (registrationObj && !once) { - NativeModules.RNFirebaseDatabase.off(registrationObj.key, registration); - } - - delete this._tree[path][eventType][registration]; - delete this._reverseLookup[registration]; - - return !!registrationObj; - } - - /** - * Wraps a `once` listener with a new function that self de-registers. - * - * @param registration - * @param listener - * @return {function(...[*])} - * @private - */ - _onOnceRemoveRegistration(registration, listener) { - return (...args: any[]) => { - this.removeRegistration(registration); - listener(...args); - }; - } -} - -export default new SyncTree(); diff --git a/src/utils/apps.js b/src/utils/apps.js deleted file mode 100644 index d9ed0f88..00000000 --- a/src/utils/apps.js +++ /dev/null @@ -1,235 +0,0 @@ -/** - * @flow - */ -import { NativeModules } from 'react-native'; -import App from '../modules/core/app'; -import INTERNALS from './internals'; -import { isAndroid, isObject, isString } from './'; - -import type { - FirebaseModule, - FirebaseModuleAndStatics, - FirebaseModuleName, - FirebaseNamespace, - FirebaseOptions, - FirebaseStatics, -} from '../types'; - -const FirebaseCoreModule = NativeModules.RNFirebase; - -const APPS: { [string]: App } = {}; -const DEFAULT_APP_NAME = '[DEFAULT]'; -const APP_MODULES: { [string]: { [string]: FirebaseModule } } = {}; -const CUSTOM_URL_OR_REGION_NAMESPACES = { - database: true, - functions: true, - storage: false, // TODO true once multi-bucket support added. - // for flow: - admob: false, - analytics: false, - auth: false, - config: false, - crashlytics: false, - firestore: false, - iid: false, - invites: false, - links: false, - messaging: false, - notifications: false, - perf: false, - utils: false, -}; - -export default { - DEFAULT_APP_NAME, - - app(name?: string): App { - const _name = name ? name.toUpperCase() : DEFAULT_APP_NAME; - const app = APPS[_name]; - if (!app) throw new Error(INTERNALS.STRINGS.ERROR_APP_NOT_INIT(_name)); - return app; - }, - - apps(): Array { - // $FlowExpectedError: Object.values always returns mixed type: https://github.com/facebook/flow/issues/2221 - return Object.values(APPS); - }, - - /** - * - * @param app - * @param namespace - * @param InstanceClass - * @return {function()} - * @private - */ - appModule( - app: App, - namespace: FirebaseNamespace, - InstanceClass: Class - ): () => FirebaseModule { - return (customUrlOrRegion: ?string = null): M => { - if (customUrlOrRegion && !CUSTOM_URL_OR_REGION_NAMESPACES[namespace]) { - throw new Error( - INTERNALS.STRINGS.ERROR_INIT_SERVICE_URL_OR_REGION_UNSUPPORTED( - namespace - ) - ); - } - - const appInstanceIdentifier = `${app.name}${customUrlOrRegion || ''}`; - - if (!APP_MODULES[appInstanceIdentifier]) { - APP_MODULES[appInstanceIdentifier] = {}; - } - - if (!APP_MODULES[appInstanceIdentifier][namespace]) { - APP_MODULES[appInstanceIdentifier][namespace] = new InstanceClass( - app, - customUrlOrRegion - ); - - // only check once on new app namespace instance - if ( - isAndroid && - namespace !== 'utils' && - !INTERNALS.FLAGS.checkedPlayServices - ) { - INTERNALS.FLAGS.checkedPlayServices = true; - app.utils().checkPlayServicesAvailability(); - } - } - - return APP_MODULES[appInstanceIdentifier][namespace]; - }; - }, - - /** - * - * @param name - * @returns {*} - */ - deleteApp(name: string) { - const app = APPS[name]; - if (!app) return; - delete APPS[name]; - }, - - /** - * Web SDK initializeApp - * - * @param options - * @param name - * @return {*} - */ - initializeApp(options: FirebaseOptions, name: string): App { - if (name && !isString(name)) { - throw new Error(INTERNALS.STRINGS.ERROR_INIT_STRING_NAME); - } - - const _name = (name || DEFAULT_APP_NAME).toUpperCase(); - - // return an existing app if found - // TODO in v5 remove deprecation and throw an error - if (APPS[_name]) { - console.warn(INTERNALS.STRINGS.WARN_INITIALIZE_DEPRECATION); - return APPS[_name]; - } - - // only validate if app doesn't already exist - // to allow apps already initialized natively - // to still go through init without erroring (backwards compatibility) - if (!isObject(options)) { - throw new Error(INTERNALS.STRINGS.ERROR_INIT_OBJECT); - } - - if (!options.apiKey) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('apiKey')); - } - - if (!options.appId) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('appId')); - } - - if (!options.databaseURL) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('databaseURL')); - } - - if (!options.messagingSenderId) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('messagingSenderId')); - } - - if (!options.projectId) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('projectId')); - } - - if (!options.storageBucket) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('storageBucket')); - } - - APPS[_name] = new App(_name, options); - - return APPS[_name]; - }, - - /** - * Bootstraps all native app instances that were discovered on boot - */ - initializeNativeApps() { - for (let i = 0, len = FirebaseCoreModule.apps.length; i < len; i++) { - const app = FirebaseCoreModule.apps[i]; - const options = Object.assign({}, app); - delete options.name; - APPS[app.name.toUpperCase()] = new App( - app.name.toUpperCase(), - options, - true - ); - } - }, - - /** - * - * @param namespace - * @param statics - * @param moduleName - * @return {function(App=)} - */ - moduleAndStatics( - namespace: FirebaseNamespace, - statics: S, - moduleName: FirebaseModuleName - ): FirebaseModuleAndStatics { - const getModule = ( - appOrUrlOrRegion?: App | string, - customUrlOrRegion?: string - ): FirebaseModule => { - let _app = appOrUrlOrRegion; - let _customUrlOrRegion: ?string = customUrlOrRegion || null; - - if ( - typeof appOrUrlOrRegion === 'string' && - CUSTOM_URL_OR_REGION_NAMESPACES[namespace] - ) { - _app = null; - _customUrlOrRegion = appOrUrlOrRegion; - } - - // throw an error if it's not a valid app instance - if (_app && !(_app instanceof App)) { - throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace)); - } else if (!_app) { - // default to the 'DEFAULT' app if no arg provided - will throw an error - // if default app not initialized - _app = this.app(DEFAULT_APP_NAME); - } - // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 - const module = _app[namespace]; - return module(_customUrlOrRegion); - }; - - return Object.assign(getModule, statics, { - nativeModuleExists: !!NativeModules[moduleName], - }); - }, -}; diff --git a/src/utils/events.js b/src/utils/events.js deleted file mode 100644 index c1ae0561..00000000 --- a/src/utils/events.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @flow - */ -import { NativeEventEmitter, NativeModules } from 'react-native'; -import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter'; - -import type ModuleBase from './ModuleBase'; -import type { FirebaseModuleConfig, FirebaseModuleName } from '../types'; - -const NATIVE_EMITTERS: { [string]: NativeEventEmitter } = {}; -const NATIVE_SUBSCRIPTIONS: { [string]: boolean } = {}; - -export const SharedEventEmitter = new EventEmitter(); - -export const getAppEventName = ( - module: ModuleBase, - eventName: string -): string => `${module.app.name}-${eventName}`; - -const getNativeEmitter = ( - moduleName: FirebaseModuleName, - module: ModuleBase -): NativeEventEmitter => { - const name = `${module.app.name}-${moduleName}`; - const nativeModule = NativeModules[moduleName]; - - if (!NATIVE_EMITTERS[name]) { - NATIVE_EMITTERS[name] = new NativeEventEmitter(nativeModule); - } - - return NATIVE_EMITTERS[name]; -}; - -/** - * Subscribe to a native event for js side distribution by appName - * React Native events are hard set at compile - cant do dynamic event names - * so we use a single event send it to js and js then internally can prefix it - * and distribute dynamically. - * - * @param moduleName - * @param module - * @param eventName - * @private - */ -const subscribeToNativeModuleEvents = ( - moduleName: FirebaseModuleName, - module: ModuleBase, - eventName: string -): void => { - if (!NATIVE_SUBSCRIPTIONS[eventName]) { - const nativeEmitter = getNativeEmitter(moduleName, module); - nativeEmitter.addListener(eventName, event => { - if (event.appName) { - // native event has an appName property - auto prefix and internally emit - SharedEventEmitter.emit(`${event.appName}-${eventName}`, event); - } else { - // standard event - no need to prefix - SharedEventEmitter.emit(eventName, event); - } - }); - - NATIVE_SUBSCRIPTIONS[eventName] = true; - } -}; - -export const initialiseNativeModuleEventEmitter = ( - module: ModuleBase, - config: FirebaseModuleConfig -): void => { - const { events, moduleName } = config; - - if (events && events.length) { - for (let i = 0, len = events.length; i < len; i++) { - subscribeToNativeModuleEvents(moduleName, module, events[i]); - } - } -}; diff --git a/src/utils/index.js b/src/utils/index.js deleted file mode 100644 index ab7361ab..00000000 --- a/src/utils/index.js +++ /dev/null @@ -1,357 +0,0 @@ -// @flow -import { Platform } from 'react-native'; - -// todo cleanup unused utilities from legacy code - -// modeled after base64 web-safe chars, but ordered by ASCII -const PUSH_CHARS = - '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; -const AUTO_ID_CHARS = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -const { hasOwnProperty } = Object; - -// const DEFAULT_CHUNK_SIZE = 50; -/** - * Checks for property existence by name on the specified object - * @param object - * @param property - * @returns {*} - */ -export function hop(object: Object, property: string): boolean { - return hasOwnProperty.call(object, property); -} - -/** - * Deep get a value from an object. - * @website https://github.com/Salakar/deeps - * @param object - * @param path - * @param joiner - * @returns {*} - */ -export function deepGet(object: any, path: string, joiner?: string = '/'): any { - if (!isObject(object) && !Array.isArray(object)) return undefined; - const keys = path.split(joiner); - - let i = 0; - let tmp = object; - const len = keys.length; - - while (i < len) { - const key = keys[i++]; - if (!tmp || !hasOwnProperty.call(tmp, key)) return undefined; - tmp = tmp[key]; - } - - return tmp; -} - -/** - * Deep check if a key exists. - * @website https://github.com/Salakar/deeps - * @param object - * @param path - * @param joiner - * @returns {*} - */ -export function deepExists( - object: Object, - path: string, - joiner?: string = '/' -): boolean { - const keys = path.split(joiner); - - let i = 0; - let tmp = object; - const len = keys.length; - - while (i < len) { - const key = keys[i++]; - if (!tmp || !hasOwnProperty.call(tmp, key)) return false; - tmp = tmp[key]; - } - - return tmp !== undefined; -} - -/** - * Deep Check if obj1 keys are contained in obj2 - * @param obj1 - * @param obj2 - * @returns {boolean} - */ -export function areObjectKeysContainedInOther( - obj1: Object, - obj2: Object -): boolean { - if (!isObject(obj1) || !isObject(obj2)) { - return false; - } - const keys1 = Object.keys(obj1); - const keys2 = Object.keys(obj2); - if (isArrayContainedInOther(keys1, keys2)) { - return keys1 - .filter(key => isObject(obj1[key])) - .reduce( - (acc, cur) => - acc && areObjectKeysContainedInOther(obj1[cur], obj2[cur]), - true - ); - } - return false; -} - -/** - * Check if arr1 is contained in arr2 - * @param arr1 - * @param arr2 - * @returns {boolean} - */ -export function isArrayContainedInOther( - arr1: Array<*>, - arr2: Array<*> -): boolean { - if (!Array.isArray(arr1) || !Array.isArray(arr2)) { - return false; - } - return arr1.reduce((acc, cur) => acc && arr2.includes(cur), true); -} - -/** - * Simple is object check. - * @param item - * @returns {boolean} - */ -export function isObject(item: mixed): boolean %checks { - return item - ? typeof item === 'object' && !Array.isArray(item) && item !== null - : false; -} - -/** - * Simple is function check - * @param item - * @returns {*|boolean} - */ -export function isFunction(item?: mixed): boolean %checks { - return item ? typeof item === 'function' : false; -} - -/** - * Simple is string check - * @param value - * @return {boolean} - */ -export function isString(value: mixed): boolean %checks { - return typeof value === 'string'; -} - -/** - * Simple is boolean check - * @param value - * @return {boolean} - */ -export function isBoolean(value: mixed): boolean %checks { - return typeof value === 'boolean'; -} - -// platform checks -export const isIOS = Platform.OS === 'ios'; -export const isAndroid = Platform.OS === 'android'; - -/** - * - * @param string - * @returns {*} - */ -export function tryJSONParse(string: string | null): any { - try { - return string && JSON.parse(string); - } catch (jsonError) { - return string; - } -} - -/** - * - * @param data - * @returns {*} - */ -export function tryJSONStringify(data: mixed): string | null { - try { - return JSON.stringify(data); - } catch (jsonError) { - return null; - } -} - -/** - * No operation func - */ -export function noop(): void {} - -/** - * Remove a trailing forward slash from a string - * @param str - * @returns {*} - */ -export function stripTrailingSlash(str: string): string { - if (!isString(str)) return str; - return str.endsWith('/') ? str.slice(0, -1) : str; -} - -/** - * Returns a string typeof that's valid for Firebase usage - * @param value - * @return {*} - */ -export function typeOf(value: any): string { - if (value === null) return 'null'; - if (Array.isArray(value)) return 'array'; - return typeof value; -} - -// timestamp of last push, used to prevent local collisions if you push twice in one ms. -let lastPushTime = 0; - -// we generate 72-bits of randomness which get turned into 12 characters and appended to the -// timestamp to prevent collisions with other clients. We store the last characters we -// generated because in the event of a collision, we'll use those same characters except -// "incremented" by one. -const lastRandChars = []; - -/** - * Generate a firebase id - for use with ref().push(val, cb) - e.g. -KXMr7k2tXUFQqiaZRY4' - * @param serverTimeOffset - pass in server time offset from native side - * @returns {string} - */ -export function generatePushID(serverTimeOffset?: number = 0): string { - const timeStampChars = new Array(8); - let now = new Date().getTime() + serverTimeOffset; - const duplicateTime = now === lastPushTime; - - lastPushTime = now; - - for (let i = 7; i >= 0; i -= 1) { - timeStampChars[i] = PUSH_CHARS.charAt(now % 64); - now = Math.floor(now / 64); - } - - if (now !== 0) - throw new Error('We should have converted the entire timestamp.'); - - let id = timeStampChars.join(''); - - if (!duplicateTime) { - for (let i = 0; i < 12; i += 1) { - lastRandChars[i] = Math.floor(Math.random() * 64); - } - } else { - // if the timestamp hasn't changed since last push, - // use the same random number, but increment it by 1. - let i; - for (i = 11; i >= 0 && lastRandChars[i] === 63; i -= 1) { - lastRandChars[i] = 0; - } - - lastRandChars[i] += 1; - } - - for (let i = 0; i < 12; i++) { - id += PUSH_CHARS.charAt(lastRandChars[i]); - } - - if (id.length !== 20) throw new Error('Length should be 20.'); - - return id; -} - -/** - * Converts a code and message from a native event to a JS Error - * @param code - * @param message - * @param additionalProps - * @returns {Error} - */ -export function nativeToJSError( - code: string, - message: string, - additionalProps?: Object = {} -) { - const error: Object = new Error(message); - error.code = code; - Object.assign(error, additionalProps); - // exclude this function from the stack - const _stackArray = error.stack.split('\n'); - error.stack = _stackArray.splice(1, _stackArray.length).join('\n'); - return error; -} - -/** - * - * @param object - * @return {string} - */ -export function objectToUniqueId(object: Object): string { - if (!isObject(object) || object === null) return JSON.stringify(object); - - const keys = Object.keys(object).sort(); - - let key = '{'; - for (let i = 0; i < keys.length; i++) { - if (i !== 0) key += ','; - key += JSON.stringify(keys[i]); - key += ':'; - key += objectToUniqueId(object[keys[i]]); - } - - key += '}'; - return key; -} - -/** - * Return the existing promise if no callback provided or - * exec the promise and callback if optionalCallback is valid. - * - * @param promise - * @param optionalCallback - * @return {Promise} - */ -export function promiseOrCallback( - promise: Promise<*>, - optionalCallback?: Function -): Promise<*> { - if (!isFunction(optionalCallback)) return promise; - - return promise - .then(result => { - // some of firebase internal tests & methods only check/return one arg - // see https://github.com/firebase/firebase-js-sdk/blob/master/src/utils/promise.ts#L62 - if (optionalCallback && optionalCallback.length === 1) { - optionalCallback(null); - } else if (optionalCallback) { - optionalCallback(null, result); - } - - return Promise.resolve(result); - }) - .catch(error => { - if (optionalCallback) optionalCallback(error); - return Promise.reject(error); - }); -} - -/** - * Generate a firestore auto id for use with collection/document .add() - * @return {string} - */ -export function firestoreAutoId(): string { - let autoId = ''; - - for (let i = 0; i < 20; i++) { - autoId += AUTO_ID_CHARS.charAt( - Math.floor(Math.random() * AUTO_ID_CHARS.length) - ); - } - return autoId; -} diff --git a/src/utils/internals.js b/src/utils/internals.js deleted file mode 100644 index f63395de..00000000 --- a/src/utils/internals.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * @flow - */ -import { Platform } from 'react-native'; - -const NAMESPACE_PODS = { - admob: 'Firebase/AdMob', - analytics: 'Firebase/Analytics', - auth: 'Firebase/Auth', - config: 'Firebase/RemoteConfig', - database: 'Firebase/Database', - links: 'Firebase/DynamicLinks', - messaging: 'Firebase/Messaging', - perf: 'Firebase/Performance', - storage: 'Firebase/Storage', -}; - -const GRADLE_DEPS = { - admob: 'ads', -}; - -const PLAY_SERVICES_CODES = { - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 1: { - code: 'SERVICE_MISSING', - message: 'Google Play services is missing on this device.', - }, - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 2: { - code: 'SERVICE_VERSION_UPDATE_REQUIRED', - message: - 'The installed version of Google Play services on this device is out of date.', - }, - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 3: { - code: 'SERVICE_DISABLED', - message: - 'The installed version of Google Play services has been disabled on this device.', - }, - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 9: { - code: 'SERVICE_INVALID', - message: - 'The version of the Google Play services installed on this device is not authentic.', - }, - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 18: { - code: 'SERVICE_UPDATING', - message: 'Google Play services is currently being updated on this device.', - }, - // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 - 19: { - code: 'SERVICE_MISSING_PERMISSION', - message: - "Google Play service doesn't have one or more required permissions.", - }, -}; - -export default { - // default options - OPTIONS: { - logLevel: 'warn', - errorOnMissingPlayServices: true, - promptOnMissingPlayServices: true, - }, - - FLAGS: { - checkedPlayServices: false, - }, - - STRINGS: { - WARN_INITIALIZE_DEPRECATION: - "Deprecation: Calling 'initializeApp()' for apps that are already initialised natively " + - "is unnecessary, use 'firebase.app()' instead to access the already initialized default app instance.", - - /** - * @return {string} - */ - get ERROR_MISSING_CORE() { - if (Platform.OS === 'ios') { - return ( - 'RNFirebase core module was not found natively on iOS, ensure you have ' + - 'correctly included the RNFirebase pod in your projects `Podfile` and have run `pod install`.' + - '\r\n\r\n See http://invertase.link/ios for the ios setup guide.' - ); - } - - return ( - 'RNFirebase core module was not found natively on Android, ensure you have ' + - 'correctly added the RNFirebase and Firebase gradle dependencies to your `android/app/build.gradle` file.' + - '\r\n\r\n See http://invertase.link/android for the android setup guide.' - ); - }, - - ERROR_INIT_OBJECT: - 'Firebase.initializeApp(options <-- requires a valid configuration object.', - ERROR_INIT_STRING_NAME: - 'Firebase.initializeApp(options, name <-- requires a valid string value.', - - /** - * @return {string} - */ - ERROR_INIT_SERVICE_URL_OR_REGION_UNSUPPORTED(namespace: string) { - return `${namespace} does not support a URL or region as a param, please pass in an app.`; - }, - - /** - * @return {string} - */ - ERROR_MISSING_CB(method: string) { - return `Missing required callback for method ${method}().`; - }, - - /** - * @return {string} - */ - ERROR_MISSING_ARG(type: string, method: string) { - return `Missing required argument of type '${type}' for method '${method}()'.`; - }, - - /** - * @return {string} - */ - ERROR_MISSING_ARG_NAMED(name: string, type: string, method: string) { - return `Missing required argument '${name}' of type '${type}' for method '${method}()'.`; - }, - - /** - * @return {string} - */ - ERROR_ARG_INVALID_VALUE(name: string, expected: string, got: string) { - return `Invalid value for argument '${name}' expected value '${expected}' but got '${got}'.`; - }, - - /** - * @return {string} - */ - ERROR_PROTECTED_PROP(name: string) { - return `Property '${name}' is protected and can not be overridden by extendApp.`; - }, - - /** - * @return {string} - * @param namespace - * @param nativeModule - */ - ERROR_MISSING_MODULE(namespace: string, nativeModule: string) { - const snippet = `firebase.${namespace}()`; - if (Platform.OS === 'ios') { - return ( - `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` + - '\r\n\r\nEnsure you have the required Firebase iOS SDK pod for this module included in your Podfile, in this instance ' + - `confirm you've added "pod '${ - NAMESPACE_PODS[namespace] - }'" to your Podfile` + - '\r\n\r\nSee http://invertase.link/ios for full setup instructions.' - ); - } - - const fbSDKDep = `'com.google.firebase:firebase-${GRADLE_DEPS[ - namespace - ] || namespace}'`; - const rnFirebasePackage = `'io.invertase.firebase.${namespace}.${nativeModule}Package'`; - const newInstance = `'new ${nativeModule}Package()'`; - return ( - `You attempted to use a firebase module that's not installed on your Android project by calling ${snippet}.` + - `\r\n\r\nEnsure you have:\r\n\r\n1) Installed the required Firebase Android SDK dependency ${fbSDKDep} in your 'android/app/build.gradle' ` + - `file.\r\n\r\n2) Imported the ${rnFirebasePackage} module in your 'MainApplication.java' file.\r\n\r\n3) Added the ` + - `${newInstance} line inside of the RN 'getPackages()' method list.` + - '\r\n\r\nSee http://invertase.link/android for full setup instructions.' - ); - }, - - /** - * @return {string} - */ - ERROR_APP_NOT_INIT(appName: string) { - return `The [${appName}] firebase app has not been initialized!`; - }, - - /** - * @param optName - * @return {string} - * @constructor - */ - ERROR_MISSING_OPT(optName: string) { - return `Failed to initialize app. FirebaseOptions missing or invalid '${optName}' property.`; - }, - - /** - * @return {string} - */ - ERROR_NOT_APP(namespace: string) { - return `Invalid App instance passed to firebase.${namespace}(app <--).`; - }, - - /** - * @return {string} - */ - ERROR_UNSUPPORTED_CLASS_METHOD(className: string, method: string) { - return `${className}.${method}() is unsupported by the native Firebase SDKs.`; - }, - - /** - * @return {string} - */ - ERROR_UNSUPPORTED_CLASS_PROPERTY(className: string, property: string) { - return `${className}.${property} is unsupported by the native Firebase SDKs.`; - }, - - /** - * @return {string} - */ - ERROR_UNSUPPORTED_MODULE_METHOD(namespace: string, method: string) { - return `firebase.${namespace}().${method}() is unsupported by the native Firebase SDKs.`; - }, - - /** - * @return {string} - */ - ERROR_PLAY_SERVICES(statusCode: number) { - const knownError = PLAY_SERVICES_CODES[statusCode]; - let start = - 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.'; - - if (statusCode === 2) { - start = - 'Google Play Services is out of date and may cause some firebase services like authentication to hang when used. It is recommended that you update it.'; - } - - // eslint-disable-next-line prefer-template - return ( - `${`${start}\r\n\r\n-------------------------\r\n`}${ - knownError - ? `${knownError.code}: ${knownError.message} (code ${statusCode})` - : `A specific play store availability reason reason was not available (unknown code: ${statusCode})` - }\r\n-------------------------` + - `\r\n\r\n` + - `For more information on how to resolve this issue, configure Play Services checks or for guides on how to validate Play Services on your users devices see the link below:` + - `\r\n\r\nhttp://invertase.link/play-services` - ); - }, - }, -}; diff --git a/src/utils/log.js b/src/utils/log.js deleted file mode 100644 index c94da3dc..00000000 --- a/src/utils/log.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * @flow - */ - -import INTERNALS from './internals'; -import type ModuleBase from './ModuleBase'; - -const NATIVE_LOGGERS: { [string]: Object } = {}; - -const getModuleKey = (module: ModuleBase): string => - `${module.app.name}:${module.namespace}`; - -export const getLogger = (module: ModuleBase) => { - const key = getModuleKey(module); - return NATIVE_LOGGERS[key]; -}; - -export const LEVELS = { - debug: 0, - info: 1, - warn: 2, - error: 3, -}; - -export const initialiseLogger = (module: ModuleBase, logNamespace: string) => { - const key = getModuleKey(module); - if (!NATIVE_LOGGERS[key]) { - const prefix = `🔥 ${logNamespace.toUpperCase()}`; - NATIVE_LOGGERS[key] = { - debug(...args) { - if (__DEV__ && LEVELS.debug >= LEVELS[INTERNALS.OPTIONS.logLevel]) - console.log(...[prefix, ...args]); - }, - info(...args) { - if (__DEV__ && LEVELS.info >= LEVELS[INTERNALS.OPTIONS.logLevel]) - console.log(...[prefix, ...args]); - }, - warn(...args) { - if (__DEV__ && LEVELS.warn >= LEVELS[INTERNALS.OPTIONS.logLevel]) - console.warn(...args); - }, - error(...args) { - console.error(...args); - }, - }; - } -}; diff --git a/src/utils/native.js b/src/utils/native.js deleted file mode 100644 index 8a040a1d..00000000 --- a/src/utils/native.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - * @flow - */ -import { NativeModules } from 'react-native'; -import { initialiseNativeModuleEventEmitter } from './events'; -import INTERNALS from './internals'; - -import type ModuleBase from './ModuleBase'; -import type { FirebaseModuleConfig } from '../types'; - -const NATIVE_MODULES: { [string]: Object } = {}; - -/** - * Prepends all arguments in prependArgs to all native method calls - * @param NativeModule - * @param argToPrepend - */ -const nativeWithArgs = ( - NativeModule: Object, - argToPrepend: Array -): Object => { - const native = {}; - const methods = Object.keys(NativeModule); - - for (let i = 0, len = methods.length; i < len; i++) { - const method = methods[i]; - if (typeof NativeModule[method] === 'function') { - native[method] = (...args) => - NativeModule[method](...[...argToPrepend, ...args]); - } else { - native[method] = NativeModule[method]; - } - } - - return native; -}; - -const nativeModuleKey = (module: ModuleBase): string => - `${module._customUrlOrRegion || module.app.name}:${module.namespace}`; - -export const getNativeModule = (module: ModuleBase): Object => - NATIVE_MODULES[nativeModuleKey(module)]; - -export const initialiseNativeModule = ( - module: ModuleBase, - config: FirebaseModuleConfig, - customUrlOrRegion: ?string -): Object => { - const { - moduleName, - hasMultiAppSupport, - hasCustomUrlSupport, - hasRegionsSupport, - namespace, - } = config; - const nativeModule = NativeModules[moduleName]; - const key = nativeModuleKey(module); - - if (!nativeModule && namespace !== 'utils') { - throw new Error( - INTERNALS.STRINGS.ERROR_MISSING_MODULE(namespace, moduleName) - ); - } - - // used by the modules that extend ModuleBase - // to access their native module counterpart - const argToPrepend = []; - - if (hasMultiAppSupport) { - argToPrepend.push(module.app.name); - } - - if (hasCustomUrlSupport || hasRegionsSupport) { - argToPrepend.push(customUrlOrRegion); - } - - if (argToPrepend.length) { - NATIVE_MODULES[key] = nativeWithArgs(nativeModule, argToPrepend); - } else { - NATIVE_MODULES[key] = nativeModule; - } - - initialiseNativeModuleEventEmitter(module, config); - - return NATIVE_MODULES[key]; -}; diff --git a/tests/.babelrc b/tests/.babelrc index 1534cd81..d3b7a7f5 100644 --- a/tests/.babelrc +++ b/tests/.babelrc @@ -6,7 +6,7 @@ { "instrument": true, "relativePath": false, - "include": ["**/src/**"], + "include": ["**/packages/**"], "useInlineSourceMaps": false } ] diff --git a/tests/.buckconfig b/tests/.buckconfig index 934256cb..3ba6dba2 100755 --- a/tests/.buckconfig +++ b/tests/.buckconfig @@ -1,6 +1,9 @@ - [android] - target = Google Inc.:Google APIs:23 + target = android-28 + +[download] + max_number_of_retries = 3 [maven_repositories] central = https://repo1.maven.org/maven2 + google = https://dl.google.com/dl/android/maven2/ diff --git a/tests/.eslintrc b/tests/.eslintrc deleted file mode 100644 index daf94a0b..00000000 --- a/tests/.eslintrc +++ /dev/null @@ -1,39 +0,0 @@ -{ - "extends": [ - "airbnb", - "prettier", - "prettier/flowtype", - "prettier/react" - ], - "parser": "babel-eslint", - "plugins": [ - "flowtype", - "prettier" - ], - "env": { - "es6": true, - "jasmine": true - }, - "rules": { - "prettier/prettier": ["error", { - "trailingComma": "es5", - "singleQuote": true - }], - - "react/forbid-prop-types": "warn", - "react/jsx-filename-extension": [ - "off", { "extensions": [".js", ".jsx"] } - ], - - "class-methods-use-this": 0, - "no-console": 0, - "no-plusplus": 0, - "no-undef": 0, - "no-underscore-dangle": "off", - "no-use-before-define": 0 - }, - "globals": { - "__DEV__": true, - "window": true - } -} diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100755 index 903d9ad9..00000000 --- a/tests/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# OSX -# -.DS_Store - -# 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/IJ -# -.idea -.gradle -local.properties - -# node.js -# -node_modules/ -npm-debug.log - -# BUCK -buck-out/ -\.buckd/ -android/app/libs -android/keystores/debug.keystore -.vscode \ No newline at end of file diff --git a/tests/android/.editorconfig b/tests/android/.editorconfig index 0f099897..670398e9 100644 --- a/tests/android/.editorconfig +++ b/tests/android/.editorconfig @@ -1,4 +1,4 @@ -# editorconfig.org +# editorconfig root = true [*] diff --git a/tests/android/app/build.gradle b/tests/android/app/build.gradle index 3500290d..0d18a20b 100755 --- a/tests/android/app/build.gradle +++ b/tests/android/app/build.gradle @@ -1,6 +1,6 @@ apply plugin: "com.android.application" -apply plugin: "com.google.firebase.firebase-perf" -apply plugin: 'io.fabric' +//apply plugin: "com.google.firebase.firebase-perf" +//apply plugin: 'io.fabric' import com.android.build.OutputFile @@ -8,17 +8,18 @@ project.ext.react = [ entryFile: "index.js" ] +// up to mono root apply from: "../../node_modules/react-native/react.gradle" def enableSeparateBuildPerCPUArchitecture = false android { - compileSdkVersion 27 + compileSdkVersion 28 defaultConfig { applicationId "com.testing" minSdkVersion 18 - targetSdkVersion 27 + targetSdkVersion 28 versionCode 1 versionName "1.0" ndk { @@ -26,8 +27,8 @@ android { } testBuildType System.getProperty('testBuildType', 'debug') - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" missingDimensionStrategy "minReactNative", "minReactNative46" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } splits { @@ -51,6 +52,10 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" signingConfig signingConfigs.release + matchingFallbacks = ['release'] + } + debug { + matchingFallbacks = ['debug'] } } // applicationVariants are e.g. debug, release @@ -68,6 +73,7 @@ android { } packagingOptions { + exclude 'META-INF/-no-jdk.kotlin_module' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' @@ -81,73 +87,23 @@ dependencies { implementation "com.facebook.react:react-native:+" implementation fileTree(dir: "libs", include: ["*.jar"]) - - /* ---------------------------- * REACT NATIVE FIREBASE * ---------------------------- */ - // Library as defined in settings.gradle - implementation project(path: ':react-native-firebase', configuration: 'default') - // Required dependencies - //noinspection GradleCompatible - implementation "com.google.firebase:firebase-core:16.0.6" - implementation "com.google.android.gms:play-services-base:16.0.1" - - /* ------------------------- - * OPTIONAL FIREBASE SDKS - * ------------------------- */ - - implementation('com.google.firebase:firebase-ads:15.0.1') { - // exclude `customtabs` as the support lib version is out of date - // we manually add it as a dependency below with a custom version - exclude group: 'com.android.support', module: 'customtabs' - } - - // Authentication - implementation "com.google.firebase:firebase-auth:16.1.0" - // Analytics - implementation "com.google.firebase:firebase-analytics:16.0.6" - // Performance Monitoring - implementation "com.google.firebase:firebase-perf:16.2.3" - // Remote Config - implementation "com.google.firebase:firebase-config:16.1.2" - // Cloud Storage - implementation "com.google.firebase:firebase-storage:16.0.5" - // Invites - implementation "com.google.firebase:firebase-invites:16.0.6" - // Dynamic Links - implementation "com.google.firebase:firebase-dynamic-links:16.1.5" - // Real-time Database - implementation "com.google.firebase:firebase-database:16.0.5" - // Cloud Functions - implementation "com.google.firebase:firebase-functions:16.1.3" - // Cloud Firestore - implementation "com.google.firebase:firebase-firestore:17.1.5" - // Cloud Messaging / FCM - implementation "com.google.firebase:firebase-messaging:17.3.4" - // Crashlytics - implementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') { - transitive = true - } - - /* -------------------------------- - * OPTIONAL SUPPORT LIBS - * -------------------------------- */ - - // For Firebase Ads - implementation "com.android.support:customtabs:27.1.1" - - // For React Native Firebase Notifications - implementation 'me.leolin:ShortcutBadger:1.1.21@aar' + // Libraries as defined in settings.gradle + implementation project(path: ':@react-native-firebase/app') + implementation project(path: ':@react-native-firebase/analytics') + implementation project(path: ':@react-native-firebase/functions') /* ------------------------ * TESTING SDKS/LIBRARIES * ------------------------ */ - implementation(project(path: ':jet', configuration: 'default')) { + implementation(project(path: ':jet')) { transitive = false } - androidTestImplementation(project(path: ":detox")) + + androidTestImplementation project(path: ":detox") androidTestImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:rules:1.0.2' diff --git a/tests/android/app/src/main/AndroidManifest.xml b/tests/android/app/src/main/AndroidManifest.xml index 83d29fda..2696910e 100755 --- a/tests/android/app/src/main/AndroidManifest.xml +++ b/tests/android/app/src/main/AndroidManifest.xml @@ -16,18 +16,25 @@ android:name="com.testing.MainApplication" android:allowBackup="false" android:icon="@drawable/ic_launcher" + android:usesCleartextTraffic="true" android:label="@string/app_name" android:launchMode="singleTask" android:theme="@style/AppTheme"> - - - - - + + + + + + + + + + + @@ -37,21 +44,21 @@ - + - - - - - - + + + + + + + + + - - - + + + getPackages() { - return Arrays.asList( + return Arrays.asList( new MainReactPackage(), new JetPackage(), - new RNFirebasePackage(), - new RNFirebaseAdMobPackage(), - new RNFirebaseAnalyticsPackage(), - new RNFirebaseAuthPackage(), - new RNFirebaseRemoteConfigPackage(), - new RNFirebaseCrashlyticsPackage(), - new RNFirebaseDatabasePackage(), - new RNFirebaseFirestorePackage(), - new RNFirebaseFunctionsPackage(), - new RNFirebaseInstanceIdPackage(), - new RNFirebaseInvitesPackage(), -// new RNFirebaseLinksPackage(), - new RNFirebaseMessagingPackage(), - new RNFirebaseNotificationsPackage(), - new RNFirebasePerformancePackage(), - new RNFirebaseStoragePackage() + new ReactNativeFirebaseAppPackage(), + new ReactNativeFirebaseAnalyticsPackage(), + new ReactNativeFirebaseFunctionsPackage() ); } }; @@ -71,14 +45,18 @@ public class MainApplication extends Application implements ReactApplication { @Override public void onCreate() { super.onCreate(); + ReactNativeFirebaseApp.initializeSecondaryApp("secondaryFromNative"); // TODO move to jet - DevInternalSettings settings = (DevInternalSettings) getReactNativeHost().getReactInstanceManager().getDevSupportManager().getDevSettings(); + DevInternalSettings settings = (DevInternalSettings) getReactNativeHost() + .getReactInstanceManager() + .getDevSupportManager() + .getDevSettings(); + if (settings != null) { settings.setBundleDeltasEnabled(false); } - SoLoader.init(this, /* native exopackage */ false); + SoLoader.init(this, false); } - } diff --git a/tests/android/build.gradle b/tests/android/build.gradle index dcaf3205..4215b84f 100755 --- a/tests/android/build.gradle +++ b/tests/android/build.gradle @@ -1,16 +1,19 @@ buildscript { + ext.kotlinVersion = '1.3.11' repositories { + jcenter() google() + mavenCentral() maven { url 'https://maven.fabric.io/public' } - jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.google.gms:google-services:4.0.1' - classpath 'com.google.firebase:firebase-plugins:1.1.5' - classpath 'io.fabric.tools:gradle:1.25.4' + classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.google.gms:google-services:4.2.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" +// classpath 'com.google.firebase:firebase-plugins:1.1.5' +// classpath 'io.fabric.tools:gradle:1.25.4' } } @@ -27,23 +30,27 @@ allprojects { } } } + + println "${project.name} ${projectDir} ${rootDir}" + repositories { - mavenLocal() + jcenter() google() + mavenLocal() maven { url "$rootDir/../node_modules/react-native/android" } - jcenter() } + } subprojects { task listAllDependencies(type: DependencyReportTask) {} ext { - compileSdk = 27 + compileSdk = 28 buildTools = "28.0.3" minSdk = 18 - targetSdk = 26 + targetSdk = 28 } afterEvaluate { project -> @@ -56,12 +63,19 @@ subprojects { minSdkVersion minSdk targetSdkVersion targetSdk } + variantFilter { variant -> + def names = variant.flavors*.name + if (names.contains("minReactNative44")) { + setIgnore(true) + } + } } } } } task wrapper(type: Wrapper) { - gradleVersion = '4.6' + gradleVersion = '4.10.2' distributionUrl = distributionUrl.replace("bin", "all") } + diff --git a/tests/android/gradle/wrapper/gradle-wrapper.jar b/tests/android/gradle/wrapper/gradle-wrapper.jar index b5166dad4d90021f6a0b45268c0755719f1d5cd4..29953ea141f55e3b8fc691d31b5ca8816d89fa87 100644 GIT binary patch literal 56177 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 z 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 diff --git a/tests/android/gradle/wrapper/gradle-wrapper.properties b/tests/android/gradle/wrapper/gradle-wrapper.properties index d8fc816a..d76b502e 100755 --- a/tests/android/gradle/wrapper/gradle-wrapper.properties +++ b/tests/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sat Sep 09 20:32:40 IDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/tests/android/gradlew b/tests/android/gradlew index 91a7e269..cccdd3d5 100755 --- a/tests/android/gradlew +++ b/tests/android/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,47 +6,6 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do fi done SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/tests/android/gradlew.bat b/tests/android/gradlew.bat index 8a0b282a..e95643d6 100755 --- a/tests/android/gradlew.bat +++ b/tests/android/gradlew.bat @@ -1,90 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/tests/android/settings.gradle b/tests/android/settings.gradle index c7fae7ff..b658dfbb 100755 --- a/tests/android/settings.gradle +++ b/tests/android/settings.gradle @@ -1,11 +1,18 @@ -rootProject.name = 'RNFTests' +rootProject.name = '@react-native-firebase/tests' + include ':jet' -project(':jet').projectDir = new File(rootProject.projectDir, '../node_modules/jet/android') +project(':jet').projectDir = new File(rootProject.projectDir, './../node_modules/jet/android') -include ':react-native-firebase' -project(':react-native-firebase').projectDir = new File(rootProject.projectDir, './../../android') +include ':@react-native-firebase/app' +project(':@react-native-firebase/app').projectDir = new File(rootProject.projectDir, './../../packages/app/android') -include ':app' +include ':@react-native-firebase/analytics' +project(':@react-native-firebase/analytics').projectDir = new File(rootProject.projectDir, './../../packages/analytics/android') + +include ':@react-native-firebase/functions' +project(':@react-native-firebase/functions').projectDir = new File(rootProject.projectDir, './../../packages/functions/android') include ':detox' -project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') +project(':detox').projectDir = new File(rootProject.projectDir, './../node_modules/detox/android/detox') + +include ':app' diff --git a/tests/app.js b/tests/app.js index c3c62b5f..c9c636fa 100755 --- a/tests/app.js +++ b/tests/app.js @@ -1,18 +1,25 @@ -/* eslint-disable import/extensions,import/no-unresolved,import/first */ +/* eslint-disable import/extensions,import/no-unresolved,import/first,import/no-extraneous-dependencies */ import React, { Component } from 'react'; import { AppRegistry, + NativeModules, Text, View, Image, StyleSheet, - YellowBox, } from 'react-native'; -YellowBox.ignoreWarnings(['Require cycle:']); - -import firebase from 'react-native-firebase'; import jet from 'jet/platform/react-native'; +import NativeEventEmitter from '@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter'; + +jet.exposeContextProperty('NativeModules', NativeModules); +jet.exposeContextProperty('NativeEventEmitter', NativeEventEmitter); + +import '@react-native-firebase/analytics'; +import '@react-native-firebase/functions'; +import firebase from '@react-native-firebase/app'; + +jet.exposeContextProperty('module', firebase); class Root extends Component { constructor(props) { @@ -22,12 +29,32 @@ class Root extends Component { }; jet.exposeContextProperty('root', this); - jet.exposeContextProperty('module', firebase); } render() { const { currentTest } = this.state; - if (!currentTest) return null; + if (!currentTest) { + return ( + + + + {'No Tests Started'} + + + {'N/A'} + + + {"Ensure you're running the Jet Packager together with the Detox test command."} + + + ); + } const module = (() => { if (currentTest.parent && currentTest.parent.parent) { @@ -110,7 +137,7 @@ const styles = StyleSheet.create({ logo: { height: 120, marginBottom: 16, - width: 120, + width: 135, }, }); diff --git a/tests/e2e/core/core.e2e.js b/tests/e2e/core/core.e2e.js deleted file mode 100644 index 4b6e2240..00000000 --- a/tests/e2e/core/core.e2e.js +++ /dev/null @@ -1,115 +0,0 @@ -describe('Core', () => { - describe('Firebase', () => { - it('it should create js apps for natively initialized apps', () => { - should.equal(firebase.app()._nativeInitialized, true); - return Promise.resolve(); - }); - - it('natively initialized apps should have options available in js', () => { - const platformAppConfig = TestHelpers.core.config(); - should.equal(firebase.app().options.apiKey, platformAppConfig.apiKey); - should.equal(firebase.app().options.appId, platformAppConfig.appId); - should.equal( - firebase.app().options.databaseURL, - platformAppConfig.databaseURL - ); - should.equal( - firebase.app().options.messagingSenderId, - platformAppConfig.messagingSenderId - ); - should.equal( - firebase.app().options.projectId, - platformAppConfig.projectId - ); - should.equal( - firebase.app().options.storageBucket, - platformAppConfig.storageBucket - ); - return Promise.resolve(); - }); - - it('it should resolve onReady for natively initialized apps', () => - firebase.app().onReady()); - - it('it should initialize dynamic apps', () => { - const name = `testscoreapp${global.testRunId}`; - const platformAppConfig = TestHelpers.core.config(); - return firebase - .initializeApp(platformAppConfig, name) - .onReady() - .then(newApp => { - newApp.name.should.equal(name.toUpperCase()); - newApp.toString().should.equal(name.toUpperCase()); - newApp.options.apiKey.should.equal(platformAppConfig.apiKey); - return newApp.delete(); - }); - }); - - it('SDK_VERSION should return a string version', () => { - firebase.SDK_VERSION.should.be.a.String(); - }); - }); - - describe('App', () => { - it('apps should provide an array of apps', () => { - should.equal(!!firebase.apps.length, true); - should.equal(firebase.apps.includes(firebase.app('[DEFAULT]')), true); - return Promise.resolve(); - }); - - it('can be deleted', async () => { - const name = `testscoreapp${global.testRunId}`; - const platformAppConfig = TestHelpers.core.config(); - const newApp = firebase.initializeApp(platformAppConfig, name); - - await newApp.onReady(); - - newApp.name.should.equal(name.toUpperCase()); - newApp.toString().should.equal(name.toUpperCase()); - newApp.options.apiKey.should.equal(platformAppConfig.apiKey); - - await newApp.delete(); - - (() => { - firebase.app(name); - }).should.throw( - `The [${name.toUpperCase()}] firebase app has not been initialized!` - ); - }); - - it('prevents the default app from being deleted', async () => { - firebase - .app() - .delete() - .should.be.rejectedWith( - 'Unable to delete the default native firebase app instance.' - ); - }); - - it('extendApp should error if an object is not supplied', () => { - (() => { - firebase.app().extendApp('string'); - }).should.throw( - "Missing required argument of type 'Object' for method 'extendApp()'." - ); - }); - - it('extendApp should error if a protected property is supplied', () => { - (() => { - firebase.app().extendApp({ - database: {}, - }); - }).should.throw( - "Property 'database' is protected and can not be overridden by extendApp." - ); - }); - - it('extendApp should provide additional functionality', () => { - const extension = {}; - firebase.app().extendApp({ - extension, - }); - firebase.app().extension.should.equal(extension); - }); - }); -}); diff --git a/tests/e2e/firestore/collection/dates.e2e.js b/tests/e2e/firestore/collection/dates.e2e.js deleted file mode 100644 index 774d6d07..00000000 --- a/tests/e2e/firestore/collection/dates.e2e.js +++ /dev/null @@ -1,417 +0,0 @@ -const { TEST_COLLECTION_NAME_DYNAMIC } = TestHelpers.firestore; - -/** - * - * @returns {Array} - */ -function documents() { - const out = [ - { - index: -1, - indexStr: '-1', - // https://github.com/invertase/react-native-firebase/issues/1552 - timestamp: null, - }, - ]; - - for (let i = 0; i < 12; i++) { - const date = new jet.context.window.Date(2017, i, i + 1, i, i * 3, i * 4); - out.push({ - index: i, - indexStr: i.toString(), - timestamp: date, - }); - } - - for (let i = 0; i < 12; i++) { - const date = new jet.context.window.Date(2018, i, i + 1, i, i * 3, i * 4); - out.push({ - index: i + 12, - indexStr: (i + 12).toString(), - timestamp: date, - }); - } - - for (let i = 0; i < 12; i++) { - const date = new jet.context.window.Date( - new Date().getFullYear(), - i, - i + 1, - i, - i * 3, - i * 4 - ); - - out.push({ - index: i + 24, - indexStr: (i + 24).toString(), - timestamp: date, - }); - } - - out.push({ - index: 1337, - indexStr: '1337', - // https://github.com/invertase/react-native-firebase/issues/1552 - timestamp: null, - }); - - return out; -} - -describe('firestore()', () => { - describe('CollectionReference', () => { - before(async () => { - const firestore = firebaseAdmin.firestore(); - const collection = firestore.collection(TEST_COLLECTION_NAME_DYNAMIC); - - const docsToAdd = documents(); - const batch = firestore.batch(); - const docsToDelete = (await collection.get()).docs; - - if (docsToDelete.length) { - for (let i = 0, len = docsToDelete.length; i < len; i++) { - const { ref } = docsToDelete[i]; - batch.delete(ref); - } - } - - for (let i = 0; i < docsToAdd.length; i++) { - batch.set(collection.doc(), docsToAdd[i]); - } - - return batch.commit(); - }); - - describe('where() -> Date Filters', () => { - it('==', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '==', date2017) - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 1); - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - should.equal(timestamp.getTime() === date2017.getTime(), true); - should.equal(i + 4, index); - indexStr.should.equal(`${i + 4}`); - } - }); - - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - - it('>=', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>=', date2017) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - // 3 years (36 months), skipping 4 months, 36 - 4 = 32; - should.equal(snapshot.size, 32); - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should be exactly the same date - if (i === 0) - should.equal(timestamp.getTime() === date2017.getTime(), true); - - should.equal(timestamp.getTime() >= date2017.getTime(), true); - should.equal(i + 4, index); - indexStr.should.equal(`${i + 4}`); - } - }); - - it('<=', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '<=', date2017) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 5); - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate last snapshot date - it should be exactly the same date - if (docs.length - 1 === i) { - should.equal(timestamp.getTime() === date2017.getTime(), true); - } - - should.equal(timestamp.getTime() <= date2017.getTime(), true); - should.equal(i, index); - indexStr.should.equal(`${i}`); - } - }); - - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - - it('>= & <=', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - // index4 - 2018-05-05T03:12:16.000Z - const date2018 = new jet.context.window.Date(2018, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>=', date2017) - .where('timestamp', '<=', date2018) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 13); - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should be exactly the same as date2017 - if (i === 0) - should.equal(timestamp.getTime() === date2017.getTime(), true); - // validate last snapshot date - it should be exactly the same as date2018 - if (i === docs.length - 1) - should.equal(timestamp.getTime() === date2018.getTime(), true); - - should.equal(timestamp.getTime() >= date2017.getTime(), true); - should.equal(timestamp.getTime() <= date2018.getTime(), true); - should.equal(i + 4, index); - indexStr.should.equal(`${i + 4}`); - } - }); - - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - - it('>', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>', date2017) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - // 3 years (36 months), skipping 4 months, 36 - 4 = 32; - should.equal(snapshot.size, 31); // minus one as not including equality on date filter - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should NOT be exactly the same date - if (i === 0) - should.equal(timestamp.getTime() !== date2017.getTime(), true); - - should.equal(timestamp.getTime() > date2017.getTime(), true); - should.equal(i + 5, index); - indexStr.should.equal(`${i + 5}`); - } - }); - - it('<', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '<', date2017) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 4); // minus one as not including equality on date filter - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should NOT be exactly the same date - if (i === 0) - should.equal(timestamp.getTime() !== date2017.getTime(), true); - - should.equal(timestamp.getTime() < date2017.getTime(), true); - should.equal(i, index); - indexStr.should.equal(`${i}`); - } - }); - - it('> & <', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - // index4 - 2018-05-05T03:12:16.000Z - const date2018 = new jet.context.window.Date(2018, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>', date2017) - .where('timestamp', '<', date2018) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 11); // minus two as not including equality on date filters - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should NOT be exactly the same as date2017 - if (i === 0) - should.equal(timestamp.getTime() !== date2017.getTime(), true); - // validate last snapshot date - it should NOT be exactly the same as date2018 - if (i === docs.length - 1) - should.equal(timestamp.getTime() !== date2018.getTime(), true); - - should.equal(timestamp.getTime() > date2017.getTime(), true); - should.equal(timestamp.getTime() < date2018.getTime(), true); - should.equal(i + 5, index); - indexStr.should.equal(`${i + 5}`); - } - }); - - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - // ------------------------------------------------------------ - - it('> & <=', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - // index4 - 2018-05-05T03:12:16.000Z - const date2018 = new jet.context.window.Date(2018, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>', date2017) - .where('timestamp', '<=', date2018) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 12); // minus one as not including equality on date2017 filter - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should NOT be exactly the same as date2017 - if (i === 0) - should.equal(timestamp.getTime() !== date2017.getTime(), true); - // validate last snapshot date - it should be exactly the same as date2018 - if (i === docs.length - 1) - should.equal(timestamp.getTime() === date2018.getTime(), true); - - should.equal(timestamp.getTime() > date2017.getTime(), true); - should.equal(timestamp.getTime() <= date2018.getTime(), true); - should.equal(i + 5, index); - indexStr.should.equal(`${i + 5}`); - } - }); - - it('>= & <', async () => { - // index4 - 2017-05-05T03:12:16.000Z - const date2017 = new jet.context.window.Date(2017, 4, 5, 4, 12, 16); - // index4 - 2018-05-05T03:12:16.000Z - const date2018 = new jet.context.window.Date(2018, 4, 5, 4, 12, 16); - - const snapshot = await firebase - .firestore() - .collection(TEST_COLLECTION_NAME_DYNAMIC) - .where('timestamp', '>=', date2017) - .where('timestamp', '<', date2018) - .orderBy('timestamp') - .get(); - - const { docs } = snapshot; - - should.equal(snapshot.size, 12); // minus one as not including equality on date2018 filters - - for (let i = 0; i < docs.length; i++) { - const { index, indexStr, timestamp } = docs[i].data(); - // validate first snapshot date - it should be exactly the same as date2017 - if (i === 0) - should.equal(timestamp.getTime() === date2017.getTime(), true); - // validate last snapshot date - it should NOT be exactly the same as date2018 - if (i === docs.length - 1) - should.equal(timestamp.getTime() !== date2018.getTime(), true); - - should.equal(timestamp.getTime() >= date2017.getTime(), true); - should.equal(timestamp.getTime() < date2018.getTime(), true); - should.equal(i + 4, index); - indexStr.should.equal(`${i + 4}`); - } - }); - }); - }); -}); diff --git a/tests/e2e/firestore/fieldValue.e2e.js b/tests/e2e/firestore/fieldValue.e2e.js deleted file mode 100644 index b3395000..00000000 --- a/tests/e2e/firestore/fieldValue.e2e.js +++ /dev/null @@ -1,208 +0,0 @@ -const { - DOC_2, - DOC_2_PATH, - testCollectionDoc, - resetTestCollectionDoc, -} = TestHelpers.firestore; - -describe('firestore()', () => { - describe('FieldValue', () => { - beforeEach(async () => { - await resetTestCollectionDoc(DOC_2_PATH, DOC_2); - }); - - describe('delete()', () => { - it('should delete a field', async () => { - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - should.equal(data().title, DOC_2.title); - - await testCollectionDoc(DOC_2_PATH).update({ - title: firebase.firestore.FieldValue.delete(), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - should.equal(dataAfterUpdate().title, undefined); - }); - }); - - describe('serverTimestamp()', () => { - it('should set timestamp', async () => { - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - should.equal(data().creationDate, undefined); - - await testCollectionDoc(DOC_2_PATH).update({ - creationDate: firebase.firestore.FieldValue.serverTimestamp(), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - dataAfterUpdate().creationDate.should.be.instanceof( - jet.context.window.Date - ); - }); - }); - - describe('arrayUnion()', () => { - it('should add new values to array field', async () => { - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - should.equal(data().elements, undefined); - - await testCollectionDoc(DOC_2_PATH).update({ - elements: firebase.firestore.FieldValue.arrayUnion('element 1'), - elements2: firebase.firestore.FieldValue.arrayUnion('element 2'), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - dataAfterUpdate().elements.should.containDeep(['element 1']); - dataAfterUpdate().elements2.should.containDeep(['element 2']); - }); - - it('should adding references & objects', async () => { - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - should.equal(data().elements, undefined); - - await testCollectionDoc(DOC_2_PATH).update({ - elements: firebase.firestore.FieldValue.arrayUnion( - 'element 1', - firebase - .firestore() - .collection('bar') - .doc('foo'), - firebase - .firestore() - .collection('bar') - .doc('baz'), - { foo: 'bar', baz: [1, 2, 3], daz: { f: 'f' } } - ), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - const { elements } = dataAfterUpdate(); - elements.length.should.equal(4); - - for (let i = 0; i < elements.length; i++) { - const element = elements[i]; - if (i === 0) element.should.equal('element 1'); - if (i === 1) { - element.should.be.instanceOf( - jet.require('src/modules/firestore/DocumentReference') - ); - element.id.should.equal('foo'); - } - if (i === 2) { - element.should.be.instanceOf( - jet.require('src/modules/firestore/DocumentReference') - ); - element.id.should.equal('baz'); - } - if (i === 3) { - element.foo.should.equal('bar'); - element.baz[0].should.equal(1); - } - } - }); - }); - - describe('arrayRemove()', () => { - it('should remove value from array', async () => { - await testCollectionDoc(DOC_2_PATH).set({ - elements: ['element 1', 'element 2'], - }); - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - data().elements.should.containDeep(['element 1', 'element 2']); - - await testCollectionDoc(DOC_2_PATH).update({ - elements: firebase.firestore.FieldValue.arrayRemove('element 2'), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - dataAfterUpdate().elements.should.not.containDeep(['element 2']); - }); - - it('should allow removing references & objects', async () => { - await testCollectionDoc(DOC_2_PATH).set({ - elements: firebase.firestore.FieldValue.arrayUnion( - 'element 1', - firebase - .firestore() - .collection('bar') - .doc('foo'), - firebase - .firestore() - .collection('bar') - .doc('baz'), - { foo: 'bar', baz: [1, 2, 3], daz: { f: 'f' } } - ), - }); - - const { data } = await testCollectionDoc(DOC_2_PATH).get(); - const { elements } = data(); - elements.length.should.equal(4); - - for (let i = 0; i < elements.length; i++) { - const element = elements[i]; - if (i === 0) element.should.equal('element 1'); - if (i === 1) { - element.should.be.instanceOf( - jet.require('src/modules/firestore/DocumentReference') - ); - element.id.should.equal('foo'); - } - if (i === 2) { - element.should.be.instanceOf( - jet.require('src/modules/firestore/DocumentReference') - ); - element.id.should.equal('baz'); - } - if (i === 3) { - element.foo.should.equal('bar'); - element.baz[0].should.equal(1); - } - } - - // now remove the last 2 items with arrayRemove - await testCollectionDoc(DOC_2_PATH).update({ - elements: firebase.firestore.FieldValue.arrayRemove( - firebase - .firestore() - .collection('bar') - .doc('baz'), - { foo: 'bar', baz: [1, 2, 3], daz: { f: 'f' } } - ), - }); - - const { data: dataAfterUpdate } = await testCollectionDoc( - DOC_2_PATH - ).get(); - - const { elements: elementsAfterUpdate } = dataAfterUpdate(); - elementsAfterUpdate.length.should.equal(2); - - for (let i = 0; i < elementsAfterUpdate.length; i++) { - const element = elementsAfterUpdate[i]; - if (i === 0) element.should.equal('element 1'); - if (i === 1) { - element.should.be.instanceOf( - jet.require('src/modules/firestore/DocumentReference') - ); - element.id.should.equal('foo'); - } - } - }); - }); - }); -}); diff --git a/tests/e2e/helpers.js b/tests/e2e/helpers.js new file mode 100644 index 00000000..a45078c2 --- /dev/null +++ b/tests/e2e/helpers.js @@ -0,0 +1,144 @@ +const { resolve } = require('path'); +const { existsSync } = require('fs'); +const requireAll = require('require-all'); + +/** + * + * @param packageName + */ +function requirePackageTests(packageName) { + const e2eDir = `./../packages/${packageName}/e2e`; + if (existsSync(e2eDir)) { + console.log(`Loaded tests from ${e2eDir}/*`); + requireAll({ + dirname: resolve(e2eDir), + filter: /(.+e2e)\.js$/, + excludeDirs: /^\.(git|svn)$/, + recursive: true, + }); + } else { + console.log(`No tests directory found for ${e2eDir}/*`); + } +} + +global.sleep = d => new Promise(r => setTimeout(r, d)); + +Object.defineProperty(global, 'firebase', { + get() { + return jet.module; + }, +}); + +Object.defineProperty(global, 'NativeModules', { + get() { + return jet.NativeModules; + }, +}); + +Object.defineProperty(global, 'NativeEventEmitter', { + get() { + return jet.NativeEventEmitter; + }, +}); + +global.isAndroid = process.argv.join('').includes('android.emu'); +global.isIOS = process.argv.join('').includes('ios.emu'); +global.android = { + describe(name, ctx) { + if (isAndroid) { + describe(name, ctx); + } else { + xdescribe('SKIP: ANDROID ONLY - ' + name, ctx); + } + }, + it(name, ctx) { + if (isAndroid) { + it(name, ctx); + } else { + xit('SKIP: ANDROID ONLY - ' + name, ctx); + } + }, +}; +global.ios = { + describe(name, ctx) { + if (isIOS) { + describe(name, ctx); + } else { + xdescribe('SKIP: IOS ONLY - ' + name, ctx); + } + }, + it(name, ctx) { + if (isIOS) { + it(name, ctx); + } else { + xit('SKIP: IOS ONLY - ' + name, ctx); + } + }, +}; + +/** + * Old style deferred promise shim - for niceness + * + * @returns {{resolve: null, reject: null}} + */ +Promise.defer = function defer() { + const deferred = { + resolve: null, + reject: null, + }; + + deferred.promise = new Promise((resolve, reject) => { + deferred.resolve = resolve; + deferred.reject = reject; + }); + + return deferred; +}; + +module.exports.requirePackageTests = requirePackageTests; + +const androidTestConfig = { + // firebase android sdk completely ignores client id + clientId: '305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com', + appId: '1:305229645282:android:af36d4d29a83e04c', + apiKey: 'AIzaSyCzbBYFyX8d6VdSu7T4s10IWYbPc-dguwM', + databaseURL: 'https://rnfirebase-b9ad4.firebaseio.com', + storageBucket: 'rnfirebase-b9ad4.appspot.com', + messagingSenderId: '305229645282', + projectId: 'rnfirebase-b9ad4', +}; + +const iosTestConfig = { + clientId: '305229645282-22imndi01abc2p6esgtu1i1m9mqrd0ib.apps.googleusercontent.com', + androidClientId: androidTestConfig.clientId, + appId: '1:305229645282:ios:af36d4d29a83e04c', + apiKey: 'AIzaSyAcdVLG5dRzA1ck_fa_xd4Z0cY7cga7S5A', + databaseURL: 'https://rnfirebase-b9ad4.firebaseio.com', + storageBucket: 'rnfirebase-b9ad4.appspot.com', + messagingSenderId: '305229645282', + projectId: 'rnfirebase-b9ad4', +}; + +global.randomString = (length, chars) => { + let mask = ''; + if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz'; + if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + if (chars.indexOf('#') > -1) mask += '0123456789'; + if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\'; + let result = ''; + for (let i = length; i > 0; --i) { + result += mask[Math.round(Math.random() * (mask.length - 1))]; + } + return result; +}; + +global.testRunId = randomString(4, 'aA#'); + +global.TestHelpers = { + core: { + config() { + const config = device.getPlatform() === 'ios' ? iosTestConfig : androidTestConfig; + return { ...config }; + }, + }, +}; diff --git a/tests/e2e/init.js b/tests/e2e/init.js index db31e723..c1e0089e 100755 --- a/tests/e2e/init.js +++ b/tests/e2e/init.js @@ -1,11 +1,28 @@ const detox = require('detox'); -const config = require('../package.json').detox; +const { requirePackageTests } = require('./helpers'); +const { detox: config } = require('../package.json'); + +const PACKAGES = [ + 'app', + 'analytics', + 'functions', + // 'auth', + // 'config', + // 'crashlytics', + // 'firestore', + // 'fiam', + // 'links', + // 'messaging', + // 'storage', +]; + +for (let i = 0; i < PACKAGES.length; i++) { + requirePackageTests(PACKAGES[i]); +} before(async () => { await detox.init(config); - // needs to be called before any usage of firestore - // await firebase.firestore().settings({ persistence: true }); - // await firebase.firestore().settings({ persistence: false }); + await firebase.initializeApp(TestHelpers.core.config()); }); beforeEach(async function beforeEach() { @@ -35,8 +52,10 @@ beforeEach(async function beforeEach() { after(async () => { console.log('Cleaning up...'); - await TestHelpers.firestore.cleanup(); + // await TestHelpers.firestore.cleanup(); console.log('Firestore cleaned up...'); // await detox.cleanup(); // TODO hangs - most likely jet internals interfering console.log('Detox cleaned up...'); + + await device.terminateApp(); }); diff --git a/tests/e2e/messaging/messaging.e2e.js b/tests/e2e/messaging/messaging.e2e.js deleted file mode 100644 index 80b22a9b..00000000 --- a/tests/e2e/messaging/messaging.e2e.js +++ /dev/null @@ -1,140 +0,0 @@ -describe('messaging()', () => { - describe('requestPermission()', () => { - it('returns fcm token', async () => { - if (device.getPlatform() === 'android') { - await firebase.messaging().requestPermission(); - } - }); - }); - - describe('hasPermission()', () => { - it('returns fcm token', async () => { - const bool = await firebase.messaging().hasPermission(); - bool.should.be.Boolean(); - if (device.getPlatform() === 'android') { - should.equal(bool, true); - } else { - should.equal(bool, false); - } - }); - }); - - describe('RemoteMessage', () => { - it('builds a remote message', async () => { - const message = new firebase.messaging.RemoteMessage(); - message.messageId.should.be.a.String(); // default - message.setMessageId('123'); - message.messageId.should.equal('123'); - - message.setData({ foo: 'bar' }); - message.data.should.be.a.Object(); - - should.equal(message.ttl, 3600); // default - message.setTtl(666); - should.equal(message.ttl, 666); - - should.equal(message.to, undefined); - message.setTo('some-topic'); - - message.build(); - }); - }); - - describe('sendMessage()', () => { - it('sends a message', async () => { - const message = new firebase.messaging.RemoteMessage(); - message.setData({ foo: 'bar' }); - message.setMessageType('data'); - message.setTo( - `${firebase.app().options.messagingSenderId}@gcm.googleapis.com` - ); - await firebase.messaging().sendMessage(message); - // TODO test with new firebase admin testing api - // const { promise, resolve, reject } = Promise.defer(); - // const unsubscribe = firebase.messaging().onMessage(msg => { - // resolve(); - // }); - // await promise; - // unsubscribe(); - }); - }); - - describe('subscribeToTopic()', () => { - it('subscribe without error', async () => { - await firebase.messaging().subscribeToTopic('foo-bar-baz'); - // TODO test subscription with new firebase testing api - }); - }); - - describe('unsubscribeFromTopic()', () => { - it('unsubscribe without error', async () => { - await firebase.messaging().unsubscribeFromTopic('foo-bar-baz'); - // TODO test unsub with new firebase testing api - }); - }); - - describe('getToken()', () => { - it('returns fcm token', async () => { - const token = await firebase.messaging().getToken(); - token.should.be.a.String(); - }); - }); - - describe('onTokenRefresh()', () => { - it('triggers when token changes', async () => { - let refreshedToken = null; - let unsubscribe = null; - - const tokenBefore = await firebase.messaging().getToken(); - tokenBefore.should.be.a.String(); - - const { promise, resolve, reject } = Promise.defer(); - unsubscribe = firebase.messaging().onTokenRefresh(newToken => { - unsubscribe(); - - try { - newToken.should.be.a.String(); - tokenBefore.should.not.equal(newToken); - } catch (e) { - return reject(e); - } - - refreshedToken = newToken; - return resolve(); - }); - - await firebase.messaging().deleteToken(); - await sleep(250); - await firebase.iid().delete(); - await sleep(250); - await firebase.iid().get(); - await sleep(250); - - const tokenAfter = await firebase.messaging().getToken(); - tokenAfter.should.be.a.String(); - tokenBefore.should.not.equal(tokenAfter); - - // TODO ios triggers twice, on initial token and new - if (device.getPlatform() === 'android') { - tokenAfter.should.equal(refreshedToken); - } - - await promise; - - await sleep(500); - }); - }); - - describe('deleteToken()', () => { - it('deletes the current fcm token', async () => { - const tokenBefore = await firebase.messaging().getToken(); - tokenBefore.should.be.a.String(); - await firebase.messaging().deleteToken(); - - const tokenAfter = await firebase.messaging().getToken(); - tokenAfter.should.be.a.String(); - tokenBefore.should.not.equal(tokenAfter); - await sleep(500); - }); - }); -}); diff --git a/tests/e2e/mocha.ci.opts b/tests/e2e/mocha.ci.opts deleted file mode 100755 index 37982268..00000000 --- a/tests/e2e/mocha.ci.opts +++ /dev/null @@ -1,9 +0,0 @@ ---recursive ---timeout 120000 ---reporter xunit ---reporter-options output=~/reports/ios-tests.xml. ---slow 1200 ---bail ---exit ---require jet/platform/node ---require ./helpers diff --git a/tests/e2e/mocha.opts b/tests/e2e/mocha.opts index 0e9980c9..11341883 100755 --- a/tests/e2e/mocha.opts +++ b/tests/e2e/mocha.opts @@ -1,9 +1,8 @@ --recursive ---timeout 120000 +--timeout 240000 --reporter spec --slow 1000 ---retries 3 +--retries 0 --bail --exit --require jet/platform/node ---require ./helpers diff --git a/tests/e2e/analytics/analytics.e2e.js b/tests/e2e_copy/analytics/analytics.e2e.js similarity index 100% rename from tests/e2e/analytics/analytics.e2e.js rename to tests/e2e_copy/analytics/analytics.e2e.js diff --git a/tests/e2e/auth/auth.e2e.js b/tests/e2e_copy/auth/auth.e2e.js similarity index 100% rename from tests/e2e/auth/auth.e2e.js rename to tests/e2e_copy/auth/auth.e2e.js diff --git a/tests/e2e/auth/emailLink.e2e.js b/tests/e2e_copy/auth/emailLink.e2e.js similarity index 100% rename from tests/e2e/auth/emailLink.e2e.js rename to tests/e2e_copy/auth/emailLink.e2e.js diff --git a/tests/e2e/auth/phone.e2e.js b/tests/e2e_copy/auth/phone.e2e.js similarity index 100% rename from tests/e2e/auth/phone.e2e.js rename to tests/e2e_copy/auth/phone.e2e.js diff --git a/tests/e2e/auth/provider.e2e.js b/tests/e2e_copy/auth/provider.e2e.js similarity index 100% rename from tests/e2e/auth/provider.e2e.js rename to tests/e2e_copy/auth/provider.e2e.js diff --git a/tests/e2e/auth/rnReload.e2e.js b/tests/e2e_copy/auth/rnReload.e2e.js similarity index 100% rename from tests/e2e/auth/rnReload.e2e.js rename to tests/e2e_copy/auth/rnReload.e2e.js diff --git a/tests/e2e/auth/user.e2e.js b/tests/e2e_copy/auth/user.e2e.js similarity index 100% rename from tests/e2e/auth/user.e2e.js rename to tests/e2e_copy/auth/user.e2e.js diff --git a/tests/e2e/config/config.e2e.js b/tests/e2e_copy/config/config.e2e.js similarity index 100% rename from tests/e2e/config/config.e2e.js rename to tests/e2e_copy/config/config.e2e.js diff --git a/tests/e2e/crashlytics/crashlytics.e2e.js b/tests/e2e_copy/crashlytics/crashlytics.e2e.js similarity index 100% rename from tests/e2e/crashlytics/crashlytics.e2e.js rename to tests/e2e_copy/crashlytics/crashlytics.e2e.js diff --git a/tests/e2e/database/issueSpecific.e2e.js b/tests/e2e_copy/database/issueSpecific.e2e.js similarity index 100% rename from tests/e2e/database/issueSpecific.e2e.js rename to tests/e2e_copy/database/issueSpecific.e2e.js diff --git a/tests/e2e/database/ref/child.e2e.js b/tests/e2e_copy/database/ref/child.e2e.js similarity index 100% rename from tests/e2e/database/ref/child.e2e.js rename to tests/e2e_copy/database/ref/child.e2e.js diff --git a/tests/e2e/database/ref/factory.e2e.js b/tests/e2e_copy/database/ref/factory.e2e.js similarity index 100% rename from tests/e2e/database/ref/factory.e2e.js rename to tests/e2e_copy/database/ref/factory.e2e.js diff --git a/tests/e2e/database/ref/isEqual.e2e.js b/tests/e2e_copy/database/ref/isEqual.e2e.js similarity index 100% rename from tests/e2e/database/ref/isEqual.e2e.js rename to tests/e2e_copy/database/ref/isEqual.e2e.js diff --git a/tests/e2e/database/ref/key.e2e.js b/tests/e2e_copy/database/ref/key.e2e.js similarity index 100% rename from tests/e2e/database/ref/key.e2e.js rename to tests/e2e_copy/database/ref/key.e2e.js diff --git a/tests/e2e/database/ref/on.e2e.js b/tests/e2e_copy/database/ref/on.e2e.js similarity index 100% rename from tests/e2e/database/ref/on.e2e.js rename to tests/e2e_copy/database/ref/on.e2e.js diff --git a/tests/e2e/database/ref/once.e2e.js b/tests/e2e_copy/database/ref/once.e2e.js similarity index 100% rename from tests/e2e/database/ref/once.e2e.js rename to tests/e2e_copy/database/ref/once.e2e.js diff --git a/tests/e2e/database/ref/parent.e2e.js b/tests/e2e_copy/database/ref/parent.e2e.js similarity index 100% rename from tests/e2e/database/ref/parent.e2e.js rename to tests/e2e_copy/database/ref/parent.e2e.js diff --git a/tests/e2e/database/ref/priority.e2e.js b/tests/e2e_copy/database/ref/priority.e2e.js similarity index 100% rename from tests/e2e/database/ref/priority.e2e.js rename to tests/e2e_copy/database/ref/priority.e2e.js diff --git a/tests/e2e/database/ref/push.e2e.js b/tests/e2e_copy/database/ref/push.e2e.js similarity index 100% rename from tests/e2e/database/ref/push.e2e.js rename to tests/e2e_copy/database/ref/push.e2e.js diff --git a/tests/e2e/database/ref/query.e2e.js b/tests/e2e_copy/database/ref/query.e2e.js similarity index 100% rename from tests/e2e/database/ref/query.e2e.js rename to tests/e2e_copy/database/ref/query.e2e.js diff --git a/tests/e2e/database/ref/set.e2e.js b/tests/e2e_copy/database/ref/set.e2e.js similarity index 100% rename from tests/e2e/database/ref/set.e2e.js rename to tests/e2e_copy/database/ref/set.e2e.js diff --git a/tests/e2e/database/ref/transactions.e2e.js b/tests/e2e_copy/database/ref/transactions.e2e.js similarity index 100% rename from tests/e2e/database/ref/transactions.e2e.js rename to tests/e2e_copy/database/ref/transactions.e2e.js diff --git a/tests/e2e/database/rnReload.e2e.js b/tests/e2e_copy/database/rnReload.e2e.js similarity index 100% rename from tests/e2e/database/rnReload.e2e.js rename to tests/e2e_copy/database/rnReload.e2e.js diff --git a/tests/e2e/database/snapshot.e2e.js b/tests/e2e_copy/database/snapshot.e2e.js similarity index 100% rename from tests/e2e/database/snapshot.e2e.js rename to tests/e2e_copy/database/snapshot.e2e.js diff --git a/tests/e2e/firestore/batch.e2e.js b/tests/e2e_copy/firestore/batch.e2e.js similarity index 100% rename from tests/e2e/firestore/batch.e2e.js rename to tests/e2e_copy/firestore/batch.e2e.js diff --git a/tests/e2e/firestore/blob.e2e.js b/tests/e2e_copy/firestore/blob.e2e.js similarity index 100% rename from tests/e2e/firestore/blob.e2e.js rename to tests/e2e_copy/firestore/blob.e2e.js diff --git a/tests/e2e/firestore/collection/cursors.e2e.js b/tests/e2e_copy/firestore/collection/cursors.e2e.js similarity index 100% rename from tests/e2e/firestore/collection/cursors.e2e.js rename to tests/e2e_copy/firestore/collection/cursors.e2e.js diff --git a/tests/e2e/firestore/collection/limit.e2e.js b/tests/e2e_copy/firestore/collection/limit.e2e.js similarity index 100% rename from tests/e2e/firestore/collection/limit.e2e.js rename to tests/e2e_copy/firestore/collection/limit.e2e.js diff --git a/tests/e2e/firestore/collection/snapshot.e2e.js b/tests/e2e_copy/firestore/collection/snapshot.e2e.js similarity index 100% rename from tests/e2e/firestore/collection/snapshot.e2e.js rename to tests/e2e_copy/firestore/collection/snapshot.e2e.js diff --git a/tests/e2e/firestore/collection/where.e2e.js b/tests/e2e_copy/firestore/collection/where.e2e.js similarity index 100% rename from tests/e2e/firestore/collection/where.e2e.js rename to tests/e2e_copy/firestore/collection/where.e2e.js diff --git a/tests/e2e/firestore/collectionReference.e2e.js b/tests/e2e_copy/firestore/collectionReference.e2e.js similarity index 100% rename from tests/e2e/firestore/collectionReference.e2e.js rename to tests/e2e_copy/firestore/collectionReference.e2e.js diff --git a/tests/e2e/firestore/documentReference.e2e.js b/tests/e2e_copy/firestore/documentReference.e2e.js similarity index 100% rename from tests/e2e/firestore/documentReference.e2e.js rename to tests/e2e_copy/firestore/documentReference.e2e.js diff --git a/tests/e2e/firestore/documentSnapshot.e2e.js b/tests/e2e_copy/firestore/documentSnapshot.e2e.js similarity index 100% rename from tests/e2e/firestore/documentSnapshot.e2e.js rename to tests/e2e_copy/firestore/documentSnapshot.e2e.js diff --git a/tests/e2e/firestore/fieldPath.e2e.js b/tests/e2e_copy/firestore/fieldPath.e2e.js similarity index 100% rename from tests/e2e/firestore/fieldPath.e2e.js rename to tests/e2e_copy/firestore/fieldPath.e2e.js diff --git a/tests/e2e_copy/firestore/fieldValue.e2e.js b/tests/e2e_copy/firestore/fieldValue.e2e.js new file mode 100644 index 00000000..f4fe988e --- /dev/null +++ b/tests/e2e_copy/firestore/fieldValue.e2e.js @@ -0,0 +1,87 @@ +const { + DOC_2, + DOC_2_PATH, + testCollectionDoc, + resetTestCollectionDoc, +} = TestHelpers.firestore; + +describe('firestore()', () => { + describe('FieldValue', () => { + beforeEach(async () => { + await resetTestCollectionDoc(DOC_2_PATH, DOC_2); + }); + + describe('delete()', () => { + it('should delete a field', async () => { + const { data } = await testCollectionDoc(DOC_2_PATH).get(); + should.equal(data().title, DOC_2.title); + + await testCollectionDoc(DOC_2_PATH).update({ + title: firebase.firestore.FieldValue.delete(), + }); + + const { data: dataAfterUpdate } = await testCollectionDoc( + DOC_2_PATH + ).get(); + + should.equal(dataAfterUpdate().title, undefined); + }); + }); + + describe('serverTimestamp()', () => { + it('should set timestamp', async () => { + const { data } = await testCollectionDoc(DOC_2_PATH).get(); + should.equal(data().creationDate, undefined); + + await testCollectionDoc(DOC_2_PATH).update({ + creationDate: firebase.firestore.FieldValue.serverTimestamp(), + }); + + const { data: dataAfterUpdate } = await testCollectionDoc( + DOC_2_PATH + ).get(); + + dataAfterUpdate().creationDate.should.be.instanceof( + jet.context.window.Date + ); + }); + }); + describe('arrayUnion()', () => { + it('should add new values to array field', async () => { + const { data } = await testCollectionDoc(DOC_2_PATH).get(); + should.equal(data().elements, undefined); + + await testCollectionDoc(DOC_2_PATH).update({ + elements: firebase.firestore.FieldValue.arrayUnion('element 1'), + elements2: firebase.firestore.FieldValue.arrayUnion('element 2'), + }); + + const { data: dataAfterUpdate } = await testCollectionDoc( + DOC_2_PATH + ).get(); + + dataAfterUpdate().elements.should.containDeep(['element 1']); + dataAfterUpdate().elements2.should.containDeep(['element 2']); + }); + }); + describe('arrayRemove()', () => { + it('should remove value from array', async () => { + await testCollectionDoc(DOC_2_PATH).set({ + elements: ['element 1', 'element 2'], + }); + const { data } = await testCollectionDoc(DOC_2_PATH).get(); + data().elements.should.containDeep(['element 1', 'element 2']); + + await testCollectionDoc(DOC_2_PATH).update({ + elements: firebase.firestore.FieldValue.arrayRemove('element 2'), + }); + + const { data: dataAfterUpdate } = await testCollectionDoc( + DOC_2_PATH + ).get(); + + dataAfterUpdate().elements.should.not.containDeep(['element 2']); + }); + }); + }); +}); diff --git a/tests/e2e/firestore/firestore.e2e.js b/tests/e2e_copy/firestore/firestore.e2e.js similarity index 100% rename from tests/e2e/firestore/firestore.e2e.js rename to tests/e2e_copy/firestore/firestore.e2e.js diff --git a/tests/e2e/firestore/path.e2e.js b/tests/e2e_copy/firestore/path.e2e.js similarity index 97% rename from tests/e2e/firestore/path.e2e.js rename to tests/e2e_copy/firestore/path.e2e.js index c25a36d1..b5c8ce6d 100644 --- a/tests/e2e/firestore/path.e2e.js +++ b/tests/e2e_copy/firestore/path.e2e.js @@ -8,11 +8,11 @@ describe('firestore()', () => { path.id.should.be.equal('documentId'); }); - it('returns empty string if no path', async () => { + it('returns null if no path', async () => { const Path = jet.require('src/modules/firestore/Path'); const path = Path.fromName(''); - should.equal(path.id, ''); + should.equal(path.id, null); }); }); diff --git a/tests/e2e/firestore/transactions.e2e.js b/tests/e2e_copy/firestore/transactions.e2e.js similarity index 100% rename from tests/e2e/firestore/transactions.e2e.js rename to tests/e2e_copy/firestore/transactions.e2e.js diff --git a/tests/e2e/functions/functions.e2e.js b/tests/e2e_copy/functions/functions.e2e.js similarity index 100% rename from tests/e2e/functions/functions.e2e.js rename to tests/e2e_copy/functions/functions.e2e.js diff --git a/tests/e2e/iid/iid.e2e.js b/tests/e2e_copy/iid/iid.e2e.js similarity index 100% rename from tests/e2e/iid/iid.e2e.js rename to tests/e2e_copy/iid/iid.e2e.js diff --git a/tests/e2e/notifications/ios.e2e.js b/tests/e2e_copy/notifications/ios.e2e.js similarity index 100% rename from tests/e2e/notifications/ios.e2e.js rename to tests/e2e_copy/notifications/ios.e2e.js diff --git a/tests/e2e/perf/httpMetric.e2e.js b/tests/e2e_copy/perf/httpMetric.e2e.js similarity index 100% rename from tests/e2e/perf/httpMetric.e2e.js rename to tests/e2e_copy/perf/httpMetric.e2e.js diff --git a/tests/e2e/perf/perf.e2e.js b/tests/e2e_copy/perf/perf.e2e.js similarity index 100% rename from tests/e2e/perf/perf.e2e.js rename to tests/e2e_copy/perf/perf.e2e.js diff --git a/tests/e2e/perf/trace.e2e.js b/tests/e2e_copy/perf/trace.e2e.js similarity index 100% rename from tests/e2e/perf/trace.e2e.js rename to tests/e2e_copy/perf/trace.e2e.js diff --git a/tests/e2e/storage/storage.e2e.js b/tests/e2e_copy/storage/storage.e2e.js similarity index 100% rename from tests/e2e/storage/storage.e2e.js rename to tests/e2e_copy/storage/storage.e2e.js diff --git a/tests/flow-typed/firebase.js b/tests/flow-typed/firebase.js index 10b53f5e..cdcbe8d3 100644 --- a/tests/flow-typed/firebase.js +++ b/tests/flow-typed/firebase.js @@ -1,5 +1,5 @@ /* eslint-disable no-unused-vars */ -import type Firebase from '../../src/types'; +import type { ReactNativeFirebaseNamespace } from '@react-native-firebase/app-types/index.js.flow'; -declare var global: { firebase: Firebase }; -declare var firebase: Firebase; +declare var global: { firebase: ReactNativeFirebaseNamespace }; +declare var firebase: ReactNativeFirebaseNamespace; diff --git a/tests/helpers/index.js b/tests/helpers/index.js index 60b0a947..92bf8b28 100644 --- a/tests/helpers/index.js +++ b/tests/helpers/index.js @@ -116,7 +116,7 @@ const iosTestConfig = { global.TestHelpers = { functions: { - data: require('@invertase/tests-firebase-functions').TEST_DATA, + data: require('./../functions/test-data'), }, firestore: require('./firestore'), database: require('./database'), diff --git a/tests/index.android.js b/tests/index.android.js old mode 100755 new mode 100644 diff --git a/tests/ios/Podfile b/tests/ios/Podfile index cc755380..e2074ea8 100644 --- a/tests/ios/Podfile +++ b/tests/ios/Podfile @@ -6,10 +6,10 @@ install! 'cocoapods', :deterministic_uuids => false # platform :ios, '8.0' target 'testing' do - platform :ios, '9.0' + platform :ios, '10.0' # Uncomment this line if you're using Swift or would like to use dynamic frameworks # use_frameworks! - rnfb_version = package["version"] + react_native_path = "../node_modules/react-native" pod 'React', :path => "#{react_native_path}", :subspecs => [ 'Core', @@ -17,8 +17,8 @@ target 'testing' do 'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43 'RCTText', 'RCTNetwork', + 'RCTImage', 'RCTWebSocket', # Needed for debugging - 'RCTAnimation', # Needed for FlatList and animations running on native UI thread ] pod "yoga", :path => "#{react_native_path}/ReactCommon/yoga" @@ -27,32 +27,37 @@ target 'testing' do pod 'DoubleConversion', :podspec => "#{react_native_path}/third-party-podspecs/DoubleConversion.podspec" pod 'glog', :podspec => "#{react_native_path}/third-party-podspecs/glog.podspec" pod 'Folly', :podspec => "#{react_native_path}/third-party-podspecs/Folly.podspec" - pod 'RNFirebase', :path => '../../ios/RNFirebase.podspec', :version => "~> #{rnfb_version}" + + pod 'Jet', :path => '../node_modules/jet/ios/Jet.podspec' + + rnfb_version = "0.0.1" # package["version"] + pod 'RNFBApp', :path => '../../packages/app/ios/RNFBApp.podspec', :version => "~> #{rnfb_version}" + pod 'RNFBAnalytics', :path => '../../packages/analytics/ios/RNFBAnalytics.podspec', :version => "~> #{rnfb_version}" + pod 'RNFBFunctions', :path => '../../packages/functions/ios/RNFBFunctions.podspec', :version => "~> #{rnfb_version}" # Pods for ReactNativeFirebaseDemo - pod 'Firebase/Core', '~> 5.15.0' - pod 'Firebase/AdMob', '~> 5.15.0' - pod 'Firebase/Auth', '~> 5.15.0' - pod 'Firebase/Database', '~> 5.15.0' - pod 'Firebase/Functions', '~> 5.15.0' - pod 'Firebase/DynamicLinks', '~> 5.15.0' - pod 'Firebase/Firestore', '~> 5.15.0' - pod 'Firebase/Invites', '~> 5.15.0' - pod 'Firebase/Messaging', '~> 5.15.0' - pod 'Firebase/RemoteConfig', '~> 5.15.0' - pod 'Firebase/Storage', '~> 5.15.0' - pod 'Firebase/Performance', '~> 5.15.0' - pod 'Fabric', '~> 1.7.11' - pod 'Crashlytics', '~> 3.10.7' + # pod 'Firebase/Core', '~> 5.15.0' + # pod 'Firebase/AdMob', '~> 5.15.0' + # pod 'Firebase/Auth', '~> 5.15.0' + # pod 'Firebase/Database', '~> 5.15.0' + # pod 'Firebase/Functions', '~> 5.15.0' + # pod 'Firebase/DynamicLinks', '~> 5.15.0' + # pod 'Firebase/Firestore', '~> 5.15.0' + # pod 'Firebase/Invites', '~> 5.15.0' + # pod 'Firebase/Messaging', '~> 5.15.0' + # pod 'Firebase/RemoteConfig', '~> 5.15.0' + # pod 'Firebase/Storage', '~> 5.15.0' + # pod 'Firebase/Performance', '~> 5.15.0' + # pod 'Fabric', '~> 1.7.11' + # pod 'Crashlytics', '~> 3.10.7' +end - post_install do |installer| - installer.pods_project.targets.each do |target| - if target.name == 'yoga' - target.build_configurations.each do |config| - config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'NO' - config.build_settings['GCC_WARN_64_TO_32_BIT_CONVERSION'] = 'NO' - end - end +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = "YES" + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = "NO" + config.build_settings['GCC_WARN_64_TO_32_BIT_CONVERSION'] = "NO" end end end diff --git a/tests/ios/Podfile.lock b/tests/ios/Podfile.lock index adec550f..6b92c43f 100644 --- a/tests/ios/Podfile.lock +++ b/tests/ios/Podfile.lock @@ -1,56 +1,14 @@ PODS: - boost-for-react-native (1.63.0) - - BoringSSL (10.0.6): - - BoringSSL/Implementation (= 10.0.6) - - BoringSSL/Interface (= 10.0.6) - - BoringSSL/Implementation (10.0.6): - - BoringSSL/Interface (= 10.0.6) - - BoringSSL/Interface (10.0.6) - - Crashlytics (3.10.9): - - Fabric (~> 1.7.13) - DoubleConversion (1.1.6) - - Fabric (1.7.13) - - Firebase/AdMob (5.15.0): - - Firebase/Core - - Google-Mobile-Ads-SDK (~> 7.37) - - Firebase/Auth (5.15.0): - - Firebase/CoreOnly - - FirebaseAuth (= 5.2.0) - Firebase/Core (5.15.0): - Firebase/CoreOnly - FirebaseAnalytics (= 5.4.0) - Firebase/CoreOnly (5.15.0): - FirebaseCore (= 5.1.10) - - Firebase/Database (5.15.0): - - Firebase/CoreOnly - - FirebaseDatabase (= 5.0.4) - - Firebase/DynamicLinks (5.15.0): - - Firebase/CoreOnly - - FirebaseDynamicLinks (= 3.3.0) - - Firebase/Firestore (5.15.0): - - Firebase/CoreOnly - - FirebaseFirestore (= 0.16.1) - Firebase/Functions (5.15.0): - Firebase/CoreOnly - FirebaseFunctions (= 2.1.2) - - Firebase/Invites (5.15.0): - - Firebase/CoreOnly - - FirebaseInvites (= 3.0.1) - - Firebase/Messaging (5.15.0): - - Firebase/CoreOnly - - FirebaseMessaging (= 3.2.2) - - Firebase/Performance (5.15.0): - - Firebase/Core - - FirebasePerformance (= 2.2.2) - - Firebase/RemoteConfig (5.15.0): - - Firebase/Core - - FirebaseRemoteConfig (= 3.1.0) - - Firebase/Storage (5.15.0): - - Firebase/CoreOnly - - FirebaseStorage (= 3.0.3) - - FirebaseABTesting (2.0.0): - - FirebaseCore (~> 5.0) - - Protobuf (~> 3.5) - FirebaseAnalytics (5.4.0): - FirebaseCore (~> 5.1) - FirebaseInstanceID (~> 3.3) @@ -60,38 +18,9 @@ PODS: - GoogleUtilities/Network (~> 5.2) - "GoogleUtilities/NSData+zlib (~> 5.2)" - nanopb (~> 0.3) - - FirebaseAnalyticsInterop (1.1.0) - - FirebaseAuth (5.2.0): - - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - GoogleUtilities/Environment (~> 5.2) - - GTMSessionFetcher/Core (~> 1.1) - FirebaseAuthInterop (1.0.0) - FirebaseCore (5.1.10): - GoogleUtilities/Logger (~> 5.2) - - FirebaseDatabase (5.0.4): - - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - leveldb-library (~> 1.18) - - FirebaseDynamicLinks (3.3.0): - - FirebaseAnalytics (~> 5.1) - - FirebaseAnalyticsInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - FirebaseFirestore (0.16.1): - - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - FirebaseFirestore/abseil-cpp (= 0.16.1) - - "gRPC-C++ (= 0.0.5)" - - leveldb-library (~> 1.20) - - nanopb (~> 0.3.8) - - Protobuf (~> 3.1) - - FirebaseFirestore/abseil-cpp (0.16.1): - - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - "gRPC-C++ (= 0.0.5)" - - leveldb-library (~> 1.20) - - nanopb (~> 0.3.8) - - Protobuf (~> 3.1) - FirebaseFunctions (2.1.2): - FirebaseAuthInterop (~> 1.0) - FirebaseCore (~> 5.1) @@ -100,245 +29,121 @@ PODS: - FirebaseCore (~> 5.1) - GoogleUtilities/Environment (~> 5.3) - GoogleUtilities/UserDefaults (~> 5.3) - - FirebaseInvites (3.0.1): - - FirebaseAnalytics (~> 5.1) - - FirebaseDynamicLinks (~> 3.0) - - GoogleAPIClientForREST (~> 1.0) - - GoogleSignIn (~> 4.2) - - GoogleToolboxForMac/Logger (~> 2.1) - - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" - - "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)" - - GoogleToolboxForMac/StringEncoding (~> 2.1) - - GoogleToolboxForMac/URLBuilder (~> 2.1) - - GTMOAuth2 (~> 1.0) - - GTMSessionFetcher/Core (~> 1.1) - - GTMSessionFetcher/Full (~> 1.1) - - Protobuf (~> 3.5) - - FirebaseMessaging (3.2.2): - - FirebaseAnalyticsInterop (~> 1.1) - - FirebaseCore (~> 5.1) - - FirebaseInstanceID (~> 3.0) - - GoogleUtilities/Environment (~> 5.2) - - GoogleUtilities/Reachability (~> 5.2) - - Protobuf (~> 3.1) - - FirebasePerformance (2.2.2): - - FirebaseAnalytics (~> 5.4) - - FirebaseInstanceID (~> 3.3) - - FirebaseRemoteConfig (~> 3.1) - - GoogleToolboxForMac/Logger (~> 2.1) - - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - - GoogleUtilities/ISASwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GTMSessionFetcher/Core (~> 1.1) - - Protobuf (~> 3.5) - - FirebaseRemoteConfig (3.1.0): - - FirebaseABTesting (~> 2.0) - - FirebaseAnalytics (~> 5.3) - - FirebaseCore (~> 5.1) - - FirebaseInstanceID (~> 3.3) - - GoogleUtilities/Environment (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - Protobuf (~> 3.5) - - FirebaseStorage (3.0.3): - - FirebaseAuthInterop (~> 1.0) - - FirebaseCore (~> 5.1) - - GTMSessionFetcher/Core (~> 1.1) - Folly (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog - glog (0.3.5) - - Google-Mobile-Ads-SDK (7.37.0) - - GoogleAPIClientForREST (1.3.7): - - GoogleAPIClientForREST/Core (= 1.3.7) - - GTMSessionFetcher (>= 1.1.7) - - GoogleAPIClientForREST/Core (1.3.7): - - GTMSessionFetcher (>= 1.1.7) - GoogleAppMeasurement (5.4.0): - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - GoogleUtilities/MethodSwizzler (~> 5.2) - GoogleUtilities/Network (~> 5.2) - "GoogleUtilities/NSData+zlib (~> 5.2)" - nanopb (~> 0.3) - - GoogleSignIn (4.4.0): - - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" - - "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)" - - GTMSessionFetcher/Core (~> 1.1) - - GoogleToolboxForMac/Core (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - GoogleToolboxForMac/DebugUtils (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - GoogleToolboxForMac/Defines (2.2.0) - - GoogleToolboxForMac/Logger (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSData+zlib (2.2.0)": - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSDictionary+URLArguments (2.2.0)": - - GoogleToolboxForMac/DebugUtils (= 2.2.0) - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSString+URLArguments (= 2.2.0)" - - "GoogleToolboxForMac/NSString+URLArguments (2.2.0)" - - GoogleToolboxForMac/StringEncoding (2.2.0): - - GoogleToolboxForMac/Defines (= 2.2.0) - - GoogleToolboxForMac/URLBuilder (2.2.0): - - GoogleToolboxForMac/Core (= 2.2.0) - - GoogleToolboxForMac/Defines (= 2.2.0) - - "GoogleToolboxForMac/NSDictionary+URLArguments (= 2.2.0)" - - "GoogleToolboxForMac/NSString+URLArguments (= 2.2.0)" - - GoogleUtilities/AppDelegateSwizzler (5.3.6): + - GoogleUtilities/AppDelegateSwizzler (5.3.7): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (5.3.6) - - GoogleUtilities/ISASwizzler (5.3.6) - - GoogleUtilities/Logger (5.3.6): + - GoogleUtilities/Environment (5.3.7) + - GoogleUtilities/Logger (5.3.7): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (5.3.6): + - GoogleUtilities/MethodSwizzler (5.3.7): - GoogleUtilities/Logger - - GoogleUtilities/Network (5.3.6): + - GoogleUtilities/Network (5.3.7): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (5.3.6)" - - GoogleUtilities/Reachability (5.3.6): + - "GoogleUtilities/NSData+zlib (5.3.7)" + - GoogleUtilities/Reachability (5.3.7): - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (5.3.6): + - GoogleUtilities/UserDefaults (5.3.7): - GoogleUtilities/Logger - - "gRPC-C++ (0.0.5)": - - "gRPC-C++/Implementation (= 0.0.5)" - - "gRPC-C++/Interface (= 0.0.5)" - - "gRPC-C++/Implementation (0.0.5)": - - "gRPC-C++/Interface (= 0.0.5)" - - gRPC-Core (= 1.14.0) - - nanopb (~> 0.3) - - "gRPC-C++/Interface (0.0.5)" - - gRPC-Core (1.14.0): - - gRPC-Core/Implementation (= 1.14.0) - - gRPC-Core/Interface (= 1.14.0) - - gRPC-Core/Implementation (1.14.0): - - BoringSSL (~> 10.0) - - gRPC-Core/Interface (= 1.14.0) - - nanopb (~> 0.3) - - gRPC-Core/Interface (1.14.0) - - GTMOAuth2 (1.1.6): - - GTMSessionFetcher (~> 1.1) - - GTMSessionFetcher (1.2.1): - - GTMSessionFetcher/Full (= 1.2.1) - GTMSessionFetcher/Core (1.2.1) - - GTMSessionFetcher/Full (1.2.1): - - GTMSessionFetcher/Core (= 1.2.1) - - leveldb-library (1.20) + - Jet (0.2.1): + - React - nanopb (0.3.901): - nanopb/decode (= 0.3.901) - nanopb/encode (= 0.3.901) - nanopb/decode (0.3.901) - nanopb/encode (0.3.901) - - Protobuf (3.6.1) - - React (0.58.0-rc.1): - - React/Core (= 0.58.0-rc.1) - - React/Core (0.58.0-rc.1): - - yoga (= 0.58.0-rc.1.React) - - React/CxxBridge (0.58.0-rc.1): + - React (0.58.1): + - React/Core (= 0.58.1) + - React/Core (0.58.1): + - yoga (= 0.58.1.React) + - React/CxxBridge (0.58.1): - Folly (= 2018.10.22.00) - React/Core - React/cxxreact - React/jsiexecutor - - React/cxxreact (0.58.0-rc.1): + - React/cxxreact (0.58.1): - boost-for-react-native (= 1.63.0) - Folly (= 2018.10.22.00) - React/jsinspector - - React/DevSupport (0.58.0-rc.1): + - React/DevSupport (0.58.1): - React/Core - React/RCTWebSocket - - React/fishhook (0.58.0-rc.1) - - React/jsi (0.58.0-rc.1): + - React/fishhook (0.58.1) + - React/jsi (0.58.1): - Folly (= 2018.10.22.00) - - React/jsiexecutor (0.58.0-rc.1): + - React/jsiexecutor (0.58.1): - Folly (= 2018.10.22.00) - React/cxxreact - React/jsi - - React/jsinspector (0.58.0-rc.1) - - React/RCTAnimation (0.58.0-rc.1): + - React/jsinspector (0.58.1) + - React/RCTBlob (0.58.1): - React/Core - - React/RCTBlob (0.58.0-rc.1): + - React/RCTImage (0.58.1): - React/Core - - React/RCTNetwork (0.58.0-rc.1): + - React/RCTNetwork + - React/RCTNetwork (0.58.1): - React/Core - - React/RCTText (0.58.0-rc.1): + - React/RCTText (0.58.1): - React/Core - - React/RCTWebSocket (0.58.0-rc.1): + - React/RCTWebSocket (0.58.1): - React/Core - React/fishhook - React/RCTBlob - - RNFirebase (5.2.1): - - Firebase/Core + - RNFBAnalytics (6.0.0-alpha.1): + - Firebase/Core (~> 5.15.0) - React - - yoga (0.58.0-rc.1.React) + - RNFBApp (6.0.0-alpha.1): + - Firebase/Core (~> 5.15.0) + - React + - RNFBFunctions (6.0.0-alpha.1): + - Firebase/Functions (~> 5.15.0) + - React + - yoga (0.58.1.React) DEPENDENCIES: - - Crashlytics (~> 3.10.7) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - Fabric (~> 1.7.11) - - Firebase/AdMob (~> 5.15.0) - - Firebase/Auth (~> 5.15.0) - - Firebase/Core (~> 5.15.0) - - Firebase/Database (~> 5.15.0) - - Firebase/DynamicLinks (~> 5.15.0) - - Firebase/Firestore (~> 5.15.0) - - Firebase/Functions (~> 5.15.0) - - Firebase/Invites (~> 5.15.0) - - Firebase/Messaging (~> 5.15.0) - - Firebase/Performance (~> 5.15.0) - - Firebase/RemoteConfig (~> 5.15.0) - - Firebase/Storage (~> 5.15.0) - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - Jet (from `../node_modules/jet/ios/Jet.podspec`) - React/Core (from `../node_modules/react-native`) - React/CxxBridge (from `../node_modules/react-native`) - React/DevSupport (from `../node_modules/react-native`) - - React/RCTAnimation (from `../node_modules/react-native`) + - React/RCTImage (from `../node_modules/react-native`) - React/RCTNetwork (from `../node_modules/react-native`) - React/RCTText (from `../node_modules/react-native`) - React/RCTWebSocket (from `../node_modules/react-native`) - - RNFirebase (from `../../ios/RNFirebase.podspec`) + - RNFBAnalytics (from `../../packages/analytics/ios/RNFBAnalytics.podspec`) + - RNFBApp (from `../../packages/app/ios/RNFBApp.podspec`) + - RNFBFunctions (from `../../packages/functions/ios/RNFBFunctions.podspec`) - yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: https://github.com/cocoapods/specs.git: - boost-for-react-native - - BoringSSL - - Crashlytics - - Fabric - Firebase - - FirebaseABTesting - FirebaseAnalytics - - FirebaseAnalyticsInterop - - FirebaseAuth - FirebaseAuthInterop - FirebaseCore - - FirebaseDatabase - - FirebaseDynamicLinks - - FirebaseFirestore - FirebaseFunctions - FirebaseInstanceID - - FirebaseInvites - - FirebaseMessaging - - FirebasePerformance - - FirebaseRemoteConfig - - FirebaseStorage - - Google-Mobile-Ads-SDK - - GoogleAPIClientForREST - GoogleAppMeasurement - - GoogleSignIn - - GoogleToolboxForMac - GoogleUtilities - - "gRPC-C++" - - gRPC-Core - - GTMOAuth2 - GTMSessionFetcher - - leveldb-library - nanopb - - Protobuf EXTERNAL SOURCES: DoubleConversion: @@ -347,56 +152,44 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + Jet: + :path: "../node_modules/jet/ios/Jet.podspec" React: :path: "../node_modules/react-native" - RNFirebase: - :path: "../../ios/RNFirebase.podspec" - :version: "~> 5.2.1" + RNFBAnalytics: + :path: "../../packages/analytics/ios/RNFBAnalytics.podspec" + :version: "~> 0.0.1" + RNFBApp: + :path: "../../packages/app/ios/RNFBApp.podspec" + :version: "~> 0.0.1" + RNFBFunctions: + :path: "../../packages/functions/ios/RNFBFunctions.podspec" + :version: "~> 0.0.1" yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c - BoringSSL: e10f92a27043805c01071fe815a5cd98ae8212e7 - Crashlytics: 55e24fc23989680285a21cb1146578d9d18e432c DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd - Fabric: 25d0963b691fc97be566392243ff0ecef5a68338 Firebase: 8bb9268bff82374f2cbaaabb143e725743c316ae - FirebaseABTesting: 1f50b8d50f5e3469eea54e7463a7b7fe221d1f5e FirebaseAnalytics: c06f9d70577d79074214700a71fd5d39de5550fb - FirebaseAnalyticsInterop: e5f21be9af6548372e2f0815834ff909bff395a2 - FirebaseAuth: 02e969ff430e156d99d4cb842d77b806b71ad7bb FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc FirebaseCore: 35747502d9e8c6ee217385ad04446c7c2aaf9c5c - FirebaseDatabase: 0621689f77528d62b47e1c06ca737c4c19275d1a - FirebaseDynamicLinks: c713da5f75c324f38fb2d57164bbc1c461aa6739 - FirebaseFirestore: 58043a1c2d2c91efdaa8d8f385cdbaa2ce750cfe FirebaseFunctions: e37c7d4d2dec63972ca4642afeb8dae8ff8ab52e FirebaseInstanceID: e2fa4cb35ef5558c200f7f0ad8a53e212215f93e - FirebaseInvites: da663c2436b88c2f56d13f38ea71e9055dc4c53d - FirebaseMessaging: b412996f6a09337d232bb3a6676ce4d1f353d024 - FirebasePerformance: 6f77b930f982a54ad487d3de5523ce641db9dcc9 - FirebaseRemoteConfig: 7e11c65f0769c09bff6947997c209515058c5318 - FirebaseStorage: 3d22c041370593e639fba013d1eb698a8dae2881 Folly: de497beb10f102453a1afa9edbf8cf8a251890de glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d - Google-Mobile-Ads-SDK: d028682d7450749a1955679da050eaf70d997b3e - GoogleAPIClientForREST: 825503f12cb5824601cf526cf06d81a1cea4afd9 GoogleAppMeasurement: 98b71f5e04142793729a5ef23e5b96651ff4b70f - GoogleSignIn: 7ff245e1a7b26d379099d3243a562f5747e23d39 - GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d - GoogleUtilities: 95996bea7c7d9b8fb811b7507669a4a8762f80c7 - "gRPC-C++": 19eec1ffd34de29453f5fab5b4697ad0f240ad51 - gRPC-Core: f4836515817c0eb479aeeb9cc27c91c4ba62a9f6 - GTMOAuth2: e8b6512c896235149df975c41d9a36c868ab7fba + GoogleUtilities: 111a012f4c3a29c9e7c954c082fafd6ee3c999c0 GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca - leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 + Jet: 5748d9e6ccc47b646859282fc25d1b063540e981 nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - Protobuf: 1eb9700044745f00181c136ef21b8ff3ad5a0fd5 React: 9b873b38b92ed8012d7cdf3b965477095ed364c4 - RNFirebase: 57f6c2adb24355b4e6211e028a8e97e473432245 + RNFBAnalytics: ca21f3fa12a77a9aa251dee9b82ceed29108f7e0 + RNFBApp: ce2acae9bc6112364743a22c5020886ab66d75d2 + RNFBFunctions: 2b2247e7222349b9b277baa12ed1b82bff4bf1dd yoga: 0885622311729a02c2bc02dca97167787a51488b -PODFILE CHECKSUM: ca7c42b26dc276713d66e348e596bdfc80d11147 +PODFILE CHECKSUM: 52d32e66cb03c3fdecd1c115a0d87fbc6afef291 COCOAPODS: 1.5.3 diff --git a/tests/ios/testing.xcodeproj/project.pbxproj b/tests/ios/testing.xcodeproj/project.pbxproj index 93661461..0797a875 100644 --- a/tests/ios/testing.xcodeproj/project.pbxproj +++ b/tests/ios/testing.xcodeproj/project.pbxproj @@ -3,286 +3,18 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 1492F08F5C89A4584B268327 /* libPods-testing.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FA6DCFB9C6221BE4EF74A8 /* libPods-testing.a */; }; 271CB185206AFCD300EBADF4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 271CB184206AFCD300EBADF4 /* GoogleService-Info.plist */; }; - 46EE18632047465300FAAB0E /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46EE18602047463E00FAAB0E /* libRCTAnimation.a */; }; - 5A11192C255B4F608BFBD79F /* libJet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AA941BEDD3364F60AC158950 /* libJet.a */; }; - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - AF4FD9113A25433387C08427 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C209A3AD2122409BBE1C6A58 /* libRCTActionSheet.a */; }; + 3323F06104C7189BEC46D8B5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3323FFA47718EA67C36AD776 /* Images.xcassets */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTActionSheet; - }; - 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTGeolocation; - }; - 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5115D1A9E6B3D00147676; - remoteInfo = RCTImage; - }; - 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B511DB1A9E6C8500147676; - remoteInfo = RCTNetwork; - }; - 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; - remoteInfo = RCTVibration; - }; - 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTSettings; - }; - 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3C86DF461ADF2C930047B81A; - remoteInfo = RCTWebSocket; - }; - 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; - remoteInfo = React; - }; - 392FDE1D1E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A283A1D9B042B00D4039D; - remoteInfo = "RCTImage-tvOS"; - }; - 392FDE211E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28471D9B043800D4039D; - remoteInfo = "RCTLinking-tvOS"; - }; - 392FDE251E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28541D9B044C00D4039D; - remoteInfo = "RCTNetwork-tvOS"; - }; - 392FDE291E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28611D9B046600D4039D; - remoteInfo = "RCTSettings-tvOS"; - }; - 392FDE2D1E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A287B1D9B048500D4039D; - remoteInfo = "RCTText-tvOS"; - }; - 392FDE321E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28881D9B049200D4039D; - remoteInfo = "RCTWebSocket-tvOS"; - }; - 392FDE3C1E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28131D9B038B00D4039D; - remoteInfo = "React-tvOS"; - }; - 392FDE3E1E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C059A1DE3340900C268FA; - remoteInfo = yoga; - }; - 392FDE401E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C06751DE3340C00C268FA; - remoteInfo = "yoga-tvOS"; - }; - 392FDE421E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4; - remoteInfo = cxxreact; - }; - 392FDE441E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4; - remoteInfo = "cxxreact-tvOS"; - }; - 392FDE461E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4; - remoteInfo = jschelpers; - }; - 392FDE481E2E5F680058768A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4; - remoteInfo = "jschelpers-tvOS"; - }; - 46EE1805204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; - remoteInfo = fishhook; - }; - 46EE1807204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; - remoteInfo = "fishhook-tvOS"; - }; - 46EE1819204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BDC1FC498900052F4D5; - remoteInfo = jsinspector; - }; - 46EE181B204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5; - remoteInfo = "jsinspector-tvOS"; - }; - 46EE181D204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; - remoteInfo = "third-party"; - }; - 46EE181F204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; - remoteInfo = "third-party-tvOS"; - }; - 46EE1821204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7E881E25C6D100323FB7; - remoteInfo = "double-conversion"; - }; - 46EE1823204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D621EBD27B9005632C8; - remoteInfo = "double-conversion-tvOS"; - }; - 46EE1825204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9936F3131F5F2E4B0010BF04; - remoteInfo = privatedata; - }; - 46EE1827204743A500FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04; - remoteInfo = "privatedata-tvOS"; - }; - 46EE185F2047463E00FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 46EE185A2047463E00FAAB0E /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTAnimation; - }; - 46EE18612047463E00FAAB0E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 46EE185A2047463E00FAAB0E /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28201D9B03D100D4039D; - remoteInfo = "RCTAnimation-tvOS"; - }; - 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTLinking; - }; - 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5119B1A9E6C1200147676; - remoteInfo = RCTText; - }; - 8E5D64EB21259B31009E4783 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A04EE4A34A2C40819812AF63 /* Jet.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = Jet; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXCopyFilesBuildPhase section */ CC0F353E1D461097008BB94F /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -297,36 +29,21 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* testingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testingTests.m; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* testing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testing.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = testing/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = testing/AppDelegate.m; sourceTree = ""; }; 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = testing/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = testing/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testing/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 27034D93212869A1004B697E /* testing.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = testing.entitlements; path = testing/testing.entitlements; sourceTree = ""; }; 271CB184206AFCD300EBADF4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 271CB2D6206B12E600EBADF4 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; }; 30F8459A53F04DD0B22777D1 /* testing.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; path = testing.xcodeproj; sourceTree = ""; }; - 46EE185A2047463E00FAAB0E /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; + 3323FFA47718EA67C36AD776 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = testing/Images.xcassets; sourceTree = ""; }; 4C4B32475FBBBAC16708CB5B /* Pods-testing.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testing.debug.xcconfig"; path = "Pods/Target Support Files/Pods-testing/Pods-testing.debug.xcconfig"; sourceTree = ""; }; 78B0E372306B6EFE53BFA0C5 /* Pods-testing.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testing.release.xcconfig"; path = "Pods/Target Support Files/Pods-testing/Pods-testing.release.xcconfig"; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; - A04EE4A34A2C40819812AF63 /* Jet.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = Jet.xcodeproj; path = ../node_modules/jet/ios/Jet.xcodeproj; sourceTree = ""; }; - AA941BEDD3364F60AC158950 /* libJet.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libJet.a; sourceTree = ""; }; B0FA6DCFB9C6221BE4EF74A8 /* libPods-testing.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testing.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - C209A3AD2122409BBE1C6A58 /* libRCTActionSheet.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTActionSheet.a; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -334,19 +51,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 46EE18632047465300FAAB0E /* libRCTAnimation.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, - 5A11192C255B4F608BFBD79F /* libJet.a in Frameworks */, - AF4FD9113A25433387C08427 /* libRCTActionSheet.a in Frameworks */, 1492F08F5C89A4584B268327 /* libPods-testing.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -354,48 +58,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 00C302A81ABCB8CE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302B61ABCB90400DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302BC1ABCB91800DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, - 392FDE1E1E2E5F680058768A /* libRCTImage-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302D41ABCB9D200DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, - 392FDE261E2E5F680058768A /* libRCTNetwork-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302E01ABCB9EE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, - ); - name = Products; - sourceTree = ""; - }; 00E356EF1AD99517003FC87E /* testingTests */ = { isa = PBXGroup; children = ( @@ -413,26 +75,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 139105B71AF99BAD00B5F7CC /* Products */ = { - isa = PBXGroup; - children = ( - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, - 392FDE2A1E2E5F680058768A /* libRCTSettings-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 139FDEE71B06529A00C62182 /* Products */ = { - isa = PBXGroup; - children = ( - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, - 392FDE331E2E5F680058768A /* libRCTWebSocket-tvOS.a */, - 46EE1806204743A500FAAB0E /* libfishhook.a */, - 46EE1808204743A500FAAB0E /* libfishhook-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 13B07FAE1A68108700A75B9A /* testing */ = { isa = PBXGroup; children = ( @@ -440,7 +82,6 @@ 271CB184206AFCD300EBADF4 /* GoogleService-Info.plist */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FB01A68108700A75B9A /* AppDelegate.m */, - 13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 13B07FB71A68108700A75B9A /* main.m */, @@ -448,38 +89,6 @@ name = testing; sourceTree = ""; }; - 146834001AC3E56700842450 /* Products */ = { - isa = PBXGroup; - children = ( - 146834041AC3E56700842450 /* libReact.a */, - 392FDE3D1E2E5F680058768A /* libReact.a */, - 392FDE3F1E2E5F680058768A /* libyoga.a */, - 392FDE411E2E5F680058768A /* libyoga.a */, - 392FDE431E2E5F680058768A /* libcxxreact.a */, - 392FDE451E2E5F680058768A /* libcxxreact.a */, - 392FDE471E2E5F680058768A /* libjschelpers.a */, - 392FDE491E2E5F680058768A /* libjschelpers.a */, - 46EE181A204743A500FAAB0E /* libjsinspector.a */, - 46EE181C204743A500FAAB0E /* libjsinspector-tvOS.a */, - 46EE181E204743A500FAAB0E /* libthird-party.a */, - 46EE1820204743A500FAAB0E /* libthird-party.a */, - 46EE1822204743A500FAAB0E /* libdouble-conversion.a */, - 46EE1824204743A500FAAB0E /* libdouble-conversion.a */, - 46EE1826204743A500FAAB0E /* libprivatedata.a */, - 46EE1828204743A500FAAB0E /* libprivatedata-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 271CB231206B024300EBADF4 /* Recovered References */ = { - isa = PBXGroup; - children = ( - AA941BEDD3364F60AC158950 /* libJet.a */, - C209A3AD2122409BBE1C6A58 /* libRCTActionSheet.a */, - ); - name = "Recovered References"; - sourceTree = ""; - }; 271CB34F206B13E700EBADF4 /* Products */ = { isa = PBXGroup; children = ( @@ -487,53 +96,15 @@ name = Products; sourceTree = ""; }; - 46EE185B2047463E00FAAB0E /* Products */ = { - isa = PBXGroup; - children = ( - 46EE18602047463E00FAAB0E /* libRCTAnimation.a */, - 46EE18622047463E00FAAB0E /* libRCTAnimation.a */, - ); - name = Products; - sourceTree = ""; - }; - 78C398B11ACF4ADC00677621 /* Products */ = { - isa = PBXGroup; - children = ( - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, - 392FDE221E2E5F680058768A /* libRCTLinking-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 46EE185A2047463E00FAAB0E /* RCTAnimation.xcodeproj */, - 146833FF1AC3E56700842450 /* React.xcodeproj */, - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 30F8459A53F04DD0B22777D1 /* testing.xcodeproj */, - A04EE4A34A2C40819812AF63 /* Jet.xcodeproj */, + 3323FFA47718EA67C36AD776 /* Images.xcassets */, ); name = Libraries; sourceTree = ""; }; - 832341B11AAA6A8300B99B32 /* Products */ = { - isa = PBXGroup; - children = ( - 832341B51AAA6A8300B99B32 /* libRCTText.a */, - 392FDE2E1E2E5F680058768A /* libRCTText-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( @@ -542,7 +113,6 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* testingTests */, 83CBBA001A601CBA00E9B192 /* Products */, - 271CB231206B024300EBADF4 /* Recovered References */, 84C75B71A6561F1B777DF935 /* Pods */, ); indentWidth = 2; @@ -566,18 +136,9 @@ name = Pods; sourceTree = ""; }; - 8E5D64C521259B30009E4783 /* Products */ = { - isa = PBXGroup; - children = ( - 8E5D64EC21259B31009E4783 /* libJet.a */, - ); - name = Products; - sourceTree = ""; - }; CCFA7DE41D11D22600E15EDF /* Frameworks */ = { isa = PBXGroup; children = ( - 271CB2D6206B12E600EBADF4 /* libRNFirebase.a */, B0FA6DCFB9C6221BE4EF74A8 /* libPods-testing.a */, ); name = Frameworks; @@ -597,7 +158,6 @@ 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, CC0F353E1D461097008BB94F /* Embed Frameworks */, 7D57265F10EEF7CD92D7973F /* Copy Detox Framework */, - CC8D61273332DE7812CFF010 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -633,7 +193,7 @@ }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testing" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -644,54 +204,6 @@ productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; projectReferences = ( - { - ProductGroup = 8E5D64C521259B30009E4783 /* Products */; - ProjectRef = A04EE4A34A2C40819812AF63 /* Jet.xcodeproj */; - }, - { - ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; - ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - }, - { - ProductGroup = 46EE185B2047463E00FAAB0E /* Products */; - ProjectRef = 46EE185A2047463E00FAAB0E /* RCTAnimation.xcodeproj */; - }, - { - ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; - ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - }, - { - ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; - ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - }, - { - ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; - ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - }, - { - ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; - ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - }, - { - ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; - ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - }, - { - ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; - ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - }, - { - ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; - ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - }, - { - ProductGroup = 139FDEE71B06529A00C62182 /* Products */; - ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - }, - { - ProductGroup = 146834001AC3E56700842450 /* Products */; - ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; - }, { ProductGroup = 271CB34F206B13E700EBADF4 /* Products */; ProjectRef = 30F8459A53F04DD0B22777D1 /* testing.xcodeproj */; @@ -704,269 +216,14 @@ }; /* End PBXProject section */ -/* Begin PBXReferenceProxy section */ - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTActionSheet.a; - remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTGeolocation.a; - remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTImage.a; - remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTNetwork.a; - remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTVibration.a; - remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTSettings.a; - remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTWebSocket.a; - remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 146834041AC3E56700842450 /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE1E1E2E5F680058768A /* libRCTImage-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTImage-tvOS.a"; - remoteRef = 392FDE1D1E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE221E2E5F680058768A /* libRCTLinking-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTLinking-tvOS.a"; - remoteRef = 392FDE211E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE261E2E5F680058768A /* libRCTNetwork-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTNetwork-tvOS.a"; - remoteRef = 392FDE251E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE2A1E2E5F680058768A /* libRCTSettings-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTSettings-tvOS.a"; - remoteRef = 392FDE291E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE2E1E2E5F680058768A /* libRCTText-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTText-tvOS.a"; - remoteRef = 392FDE2D1E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE331E2E5F680058768A /* libRCTWebSocket-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTWebSocket-tvOS.a"; - remoteRef = 392FDE321E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE3D1E2E5F680058768A /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 392FDE3C1E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE3F1E2E5F680058768A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 392FDE3E1E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE411E2E5F680058768A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 392FDE401E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE431E2E5F680058768A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 392FDE421E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE451E2E5F680058768A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 392FDE441E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE471E2E5F680058768A /* libjschelpers.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjschelpers.a; - remoteRef = 392FDE461E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 392FDE491E2E5F680058768A /* libjschelpers.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjschelpers.a; - remoteRef = 392FDE481E2E5F680058768A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1806204743A500FAAB0E /* libfishhook.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfishhook.a; - remoteRef = 46EE1805204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1808204743A500FAAB0E /* libfishhook-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libfishhook-tvOS.a"; - remoteRef = 46EE1807204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE181A204743A500FAAB0E /* libjsinspector.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjsinspector.a; - remoteRef = 46EE1819204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE181C204743A500FAAB0E /* libjsinspector-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libjsinspector-tvOS.a"; - remoteRef = 46EE181B204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE181E204743A500FAAB0E /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 46EE181D204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1820204743A500FAAB0E /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 46EE181F204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1822204743A500FAAB0E /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 46EE1821204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1824204743A500FAAB0E /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 46EE1823204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1826204743A500FAAB0E /* libprivatedata.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libprivatedata.a; - remoteRef = 46EE1825204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE1828204743A500FAAB0E /* libprivatedata-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libprivatedata-tvOS.a"; - remoteRef = 46EE1827204743A500FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE18602047463E00FAAB0E /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 46EE185F2047463E00FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 46EE18622047463E00FAAB0E /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 46EE18612047463E00FAAB0E /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTLinking.a; - remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTText.a; - remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8E5D64EC21259B31009E4783 /* libJet.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libJet.a; - remoteRef = 8E5D64EB21259B31009E4783 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - /* Begin PBXResourcesBuildPhase section */ 13B07F8E1A680F5B00A75B9A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 271CB185206AFCD300EBADF4 /* GoogleService-Info.plist in Resources */, + 3323F06104C7189BEC46D8B5 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1019,32 +276,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - CC8D61273332DE7812CFF010 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-testing/Pods-testing-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestore/gRPCCertificates-Firestore.bundle", - "${PODS_ROOT}/FirebaseInvites/Resources/GINInviteResources.bundle", - "${PODS_ROOT}/FirebaseInvites/Resources/GPPACLPickerResources.bundle", - "${PODS_ROOT}/GTMOAuth2/Source/Touch/GTMOAuth2ViewTouch.xib", - "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates-Firestore.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GINInviteResources.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GPPACLPickerResources.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMOAuth2ViewTouch.nib", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-testing/Pods-testing-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1084,10 +315,14 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-firebase/Firebase.framework/Headers/**", "$(SRCROOT)/../node_modules/bridge/ios", + "$(SRCROOT)/../../node_modules/react-native/React/**", ); INFOPLIST_FILE = testing/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.testing; @@ -1107,10 +342,14 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-firebase/Firebase.framework/Headers/**", "$(SRCROOT)/../node_modules/bridge/ios", + "$(SRCROOT)/../../node_modules/react-native/React/**", ); INFOPLIST_FILE = testing/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.testing; @@ -1158,7 +397,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; @@ -1198,7 +437,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ""; SDKROOT = iphoneos; diff --git a/tests/ios/testing.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tests/ios/testing.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/tests/ios/testing.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/tests/ios/testing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tests/ios/testing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/tests/ios/testing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/tests/ios/testing.xcodeproj/xcshareddata/xcschemes/testing Release.xcscheme b/tests/ios/testing.xcodeproj/xcshareddata/xcschemes/testing Release.xcscheme index ca97e114..00990228 100644 --- a/tests/ios/testing.xcodeproj/xcshareddata/xcschemes/testing Release.xcscheme +++ b/tests/ios/testing.xcodeproj/xcshareddata/xcschemes/testing Release.xcscheme @@ -54,7 +54,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + diff --git a/tests/ios/testing.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tests/ios/testing.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/tests/ios/testing.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/tests/ios/testing.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/tests/ios/testing.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/tests/ios/testing.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/ios/testing/AppDelegate.m b/tests/ios/testing/AppDelegate.m index ec2e3077..e24e46bd 100755 --- a/tests/ios/testing/AppDelegate.m +++ b/tests/ios/testing/AppDelegate.m @@ -2,45 +2,44 @@ #import #import -#import -#import -@import Firebase; -@import GoogleSignIn; +#import + +//#import +//#import +//@import GoogleSignIn; @implementation AppDelegate + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [FIRApp configureWithName:@"secondaryFromNative" options:[FIROptions defaultOptions]]; +// [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID; -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - [FIRApp configure]; - [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID; - - NSURL *jsCodeLocation; - jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; - - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation - moduleName:@"testing" - initialProperties:nil - launchOptions:launchOptions]; - - rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; -} + NSURL *jsCodeLocation; + jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; -- (BOOL)application:(UIApplication *)application -continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(void (^)(NSArray *))restorationHandler { - return [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; -} + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation + moduleName:@"testing" + initialProperties:nil + launchOptions:launchOptions]; -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo -fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { - [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; -} + rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; + + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + UIViewController *rootViewController = [UIViewController new]; + rootViewController.view = rootView; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; + return YES; + } +// +//- (BOOL)application:(UIApplication *)application +//continueUserActivity:(NSUserActivity *)userActivity +// restorationHandler:(void (^)(NSArray *))restorationHandler { +// return [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; +//} +// +//- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +//fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { +// [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +//} @end diff --git a/tests/metro.config.js b/tests/metro.config.js index 9eadea09..bdd8a02c 100755 --- a/tests/metro.config.js +++ b/tests/metro.config.js @@ -1,29 +1,42 @@ +/* eslint-disable import/no-extraneous-dependencies */ const { resolve, join } = require('path'); const { createBlacklist } = require('metro'); const { mergeConfig } = require('metro-config'); const { DEFAULT } = require('react-native/local-cli/util/Config'); -// https://github.com/facebook/react-native/blob/master/local-cli/core/Constants.js -// https://github.com/facebook/react-native/blob/master/local-cli/util/Config.js const config = { + projectRoot: __dirname, resolver: { + resolverMainFields: ['testsMain', 'browser', 'main'], blackListRE: createBlacklist([ - new RegExp(`^${escape(resolve(__dirname, '..', 'node_modules'))}\\/.*$`), + new RegExp(`^${escape(resolve(__dirname, '..', 'docs'))}\\/.*$`), + new RegExp(`^${escape(resolve(__dirname, '..', 'tests/android'))}\\/.*$`), + new RegExp(`^${escape(resolve(__dirname, '..', 'tests/ios'))}\\/.*$`), + new RegExp(`^${escape(resolve(__dirname, '..', 'tests/e2e'))}\\/.*$`), + new RegExp(`^${escape(resolve(__dirname, '..', 'tests/functions'))}\\/.*$`), ]), extraNodeModules: new Proxy( {}, { get: (target, name) => { - if (name === 'react-native-firebase') { - return join(__dirname, `../src`); + if (name.startsWith('@react-native-firebase')) { + const packageName = name.replace('@react-native-firebase/', ''); + return join(__dirname, `../packages/${packageName}`); } return join(__dirname, `node_modules/${name}`); }, - } + }, ), platforms: ['android', 'ios'], }, - watchFolders: [resolve(__dirname, '../src')], + watchFolders: [ + resolve(__dirname, '.'), + resolve(__dirname, '../packages/app'), + resolve(__dirname, '../packages/common'), + resolve(__dirname, '../packages/app-types'), + resolve(__dirname, '../packages/analytics'), + resolve(__dirname, '../packages/functions'), + ], }; module.exports = mergeConfig(DEFAULT, config); diff --git a/tests/package.json b/tests/package.json index da10398a..7361e46c 100755 --- a/tests/package.json +++ b/tests/package.json @@ -1,54 +1,32 @@ { "name": "react-native-firebase-tests", - "version": "0.0.1", + "version": "6.0.0-alpha.1", "private": true, "scripts": { - "packager-chrome": "react-native start --platforms ios,android", - "packager-jet": "REACT_DEBUGGER='echo nope' react-native start", - "packager-jet-reset-cache": "REACT_DEBUGGER='echo nope' react-native start --reset-cache", - "build-ios": "detox build --configuration ios.sim.debug", - "build-ios-release": "detox build --configuration ios.sim.release", - "build-android": "detox build --configuration android.emu.debug", - "test-android": "detox test --configuration android.emu.debug", - "test-android-reuse": "detox test --configuration android.emu.debug --reuse", - "test-android-cover": "nyc detox test --configuration android.emu.debug", - "test-android-cover-reuse": "nyc detox test --configuration android.emu.debug --reuse", - "test-ios": "detox test --configuration ios.sim.debug --loglevel warn", - "test-ios-reuse": "detox test --configuration ios.sim.debug --reuse --loglevel warn", - "test-ios-cover": "nyc detox test --configuration ios.sim.debug", - "test-ios-cover-reuse": "nyc detox test --configuration ios.sim.debug --reuse --loglevel warn", - "ios:pod:install": "cd ios && rm -rf ReactNativeFirebaseDemo.xcworkspace && pod install && cd .." + "build:clean": "rimraf dist && rimraf android/build && rimraf ios/build", + "prepare": "patch-package" }, "dependencies": { - "detox": "^9.0.4", - "fbjs": "^0.8.16", - "firebase-admin": "^5.12.0", - "jet": "^0.2.0", - "jsonwebtoken": "^8.2.1", + "@react-native-firebase/analytics": "^6.0.0-alpha.1", + "@react-native-firebase/app": "^6.0.0-alpha.1", + "@react-native-firebase/app-types": "^6.0.0-alpha.1", + "@react-native-firebase/functions": "^6.0.0-alpha.1", + "detox": "9.1.2", + "jet": "^0.2.1", "mocha": "^5.2.0", "prop-types": "^15.6.1", - "react": "16.6.3", - "react-native": "0.58.0-rc.1", - "should": "^13.2.1", + "react": "^16.6.3", + "react-dom": "^16.6.3", + "react-native": "^0.58.1", + "require-all": "3.0.0", + "should": "^13.2.3", "should-sinon": "0.0.6", - "sinon": "^6.2.0", - "@invertase/tests-firebase-functions": "^0.0.1" + "sinon": "^6.2.0" }, "devDependencies": { - "@babel/plugin-transform-runtime": "^7.0.0", - "@babel/runtime": "^7.0.0", - "babel-eslint": "^9.0.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-plugin-module-resolver": "^3.1.1", - "eslint": "^5.5.0", - "eslint-config-airbnb": "^17.0.0", - "eslint-plugin-flowtype": "^2.46.3", - "eslint-plugin-import": "^2.11.0", - "eslint-plugin-jsx-a11y": "^6.0.3", - "eslint-plugin-react": "^7.7.0", - "flow-bin": "^0.78.0", + "babel-plugin-istanbul": "^5.1.1", "nyc": "^13.1.0", - "rimraf": "^2.6.2" + "patch-package": "^5.1.2" }, "nyc": { "check-coverage": false, @@ -57,17 +35,11 @@ "functions": 95, "branches": 95, "include": [ - "src/**" + "packages/**" ], "exclude": [ "node_modules", - "src/modules/admob**", - "src/modules/auth/phone**", - "src/modules/notifications**", - "src/utils**", - "src/modules/utils**", - "src/types**", - "**/types.js" + "**/common/lib/**" ], "cwd": "..", "all": true, @@ -75,6 +47,7 @@ "instrument": false, "reporter": [ "lcov", + "html", "text-summary" ] }, @@ -85,7 +58,7 @@ "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/testing.app", - "build": "xcodebuild -workspace ios/testing.xcworkspace -scheme testing -parallelizeTargets -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build -UseModernBuildSystem=NO -quiet", + "build": "xcodebuild -workspace ios/testing.xcworkspace -scheme testing -parallelizeTargets -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build -UseModernBuildSystem=YES -quiet | xcpretty -k", "type": "ios.simulator", "name": "iPhone X", "logLevel": "error" @@ -98,7 +71,7 @@ }, "ios.sim.release": { "binaryPath": "ios/build/Build/Products/Release-iphonesimulator/testing.app", - "build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/testing.xcworkspace -scheme testing -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -UseModernBuildSystem=NO -quiet", + "build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/testing.xcworkspace -scheme testing -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet", "type": "ios.simulator", "name": "iPhone X" }, diff --git a/tests/patches/detox+9.1.2.patch b/tests/patches/detox+9.1.2.patch new file mode 100644 index 00000000..c446175f --- /dev/null +++ b/tests/patches/detox+9.1.2.patch @@ -0,0 +1,33 @@ +patch-package +--- a/node_modules/detox/android/detox/build.gradle ++++ b/node_modules/detox/android/detox/build.gradle +@@ -19,10 +19,6 @@ + + productFlavors { + flavorDimensions "minReactNative" +- minReactNative44 { +- dimension "minReactNative" +- +- } + minReactNative46 { + dimension "minReactNative" + } +@@ -64,9 +60,6 @@ + } + + dependencies { +- minReactNative44Implementation 'com.squareup.okhttp3:okhttp:3.4.1' +- minReactNative44Implementation 'com.squareup.okhttp3:okhttp-ws:3.4.1' +- + minReactNative46Implementation 'com.squareup.okhttp3:okhttp:3.6.0' + minReactNative46Implementation 'com.squareup.okio:okio:1.13.0' + +@@ -75,7 +68,7 @@ + }) + implementation 'com.android.support.test:runner:1.0.2' + implementation 'com.android.support.test:rules:1.0.2' +- compileOnly "com.facebook.react:react-native:+" ++ api "com.facebook.react:react-native:+" + + implementation 'org.apache.commons:commons-lang3:3.4' + implementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3' diff --git a/tests/type-test.js.flow b/tests/type-test.js.flow new file mode 100644 index 00000000..77394bdd --- /dev/null +++ b/tests/type-test.js.flow @@ -0,0 +1,13 @@ +import firebase from 'react-native-firebase'; +import analytics from '@react-native-firebase/analytics'; +import functions, { firebase as foo } from '@react-native-firebase/functions'; + +firebase.app; + +analytics.SDK_VERSION; +functions.SDK_VERSION; +const httpsCallable = firebase.functions(firebase.app()).httpsCallable('foo'); + +httpsCallable({ foo: 1 }).then(result => { + result.data; +}); diff --git a/tests/type-test.ts b/tests/type-test.ts new file mode 100644 index 00000000..3412e6cf --- /dev/null +++ b/tests/type-test.ts @@ -0,0 +1,25 @@ +import firebase from 'react-native-firebase'; +import analytics, { Analytics } from '@react-native-firebase/analytics'; +import functions, { + firebase as boopy, + Functions, + HttpsErrorCode, +} from '@react-native-firebase/functions'; + +firebase.app; +boopy.apps[0].options.projectId; +analytics.SDK_VERSION; +functions.SDK_VERSION; +const httpsCallable = firebase.functions(firebase.app()).httpsCallable('foo'); +functions; + +httpsCallable({ foo: 1 }) + .then(result => { + result.data; + }) + .catch((error: Functions.HttpsError) => { + const foo = {} as Analytics.Module; + error.details; + foo.logEvent('shoopy', {}); + HttpsErrorCode.NOT_FOUND; + }); diff --git a/tests/yarn.lock b/tests/yarn.lock deleted file mode 100644 index 208ede99..00000000 --- a/tests/yarn.lock +++ /dev/null @@ -1,7261 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" - integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" - "@babel/helpers" "^7.1.5" - "@babel/parser" "^7.1.6" - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.1.6" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.10" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.0.0", "@babel/generator@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" - integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== - dependencies: - "@babel/types" "^7.1.6" - jsesc "^2.5.1" - lodash "^4.17.10" - source-map "^0.5.0" - trim-right "^1.0.1" - -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-builder-react-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb" - integrity sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw== - dependencies: - "@babel/types" "^7.0.0" - esutils "^2.0.0" - -"@babel/helper-call-delegate@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" - integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ== - dependencies: - "@babel/helper-hoist-variables" "^7.0.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-define-map@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" - integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.0.0" - lodash "^4.17.10" - -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== - dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== - dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-hoist-variables@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" - integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-member-expression-to-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" - integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-module-imports@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-module-transforms@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" - integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - lodash "^4.17.10" - -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== - -"@babel/helper-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" - integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== - dependencies: - lodash "^4.17.10" - -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" - integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== - dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-wrap-function@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" - integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helpers@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" - integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== - dependencies: - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.5" - "@babel/types" "^7.1.5" - -"@babel/highlight@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" - integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" - integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== - -"@babel/plugin-external-helpers@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0.tgz#61ee7ba5dba27d7cad72a13d46bec23c060b762e" - integrity sha512-tZKTMdhZvTy0KCEX5EGQQm1RHr7jUa36q/yax1baEA0yZapVYmu10yW7LTqijITgSq416gPVjrcexiA6y4pJlA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-proposal-class-properties@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4" - integrity sha512-/PCJWN+CKt5v1xcGn4vnuu13QDoV+P7NcICP44BoonAJoPSGwVkgrXihFIQGiEjjPlUDBIw1cM7wYFLARS2/hw== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - -"@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.0.0.tgz#a057bbfd4649facfe39f33a537e18554bdd2b5da" - integrity sha512-cWhkx6SyjZ4caFOanoPmDNgQCuYYTmou4QXy886JsyLTw/vhWQbop2gLKsWyyswrJkKTB7fSNxVYbP/oEsoySA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.0.0.tgz#b72ec31adf612d062dc0348316246127a451e45f" - integrity sha512-QIN3UFo1ul4ruAsjIqK43PeXedo1qY74zeGrODJl1KfCGeMc6qJC4rb5Ylml/smzxibqsDeVZGH+TmWHCldRQQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" - -"@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.0.0.tgz#3d344d4152253379b8758e7d041148e8787c4a9d" - integrity sha512-7x8HLa71OzNiofbQUVakS0Kmg++6a+cXNfS7QKHbbv03SuSaumJyaWsfNgw+T7aqrJlqurYpZqrkPgXu0iZK0w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" - -"@babel/plugin-syntax-class-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" - integrity sha512-cR12g0Qzn4sgkjrbrzWy2GE7m9vMl/sFkqZ3gIpAQdrvPDnLM8180i+ANDFIXfjHo9aqp0ccJlQ0QNZcFUbf9w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0.tgz#6dfb7d8b6c3be14ce952962f658f3b7eb54c33ee" - integrity sha512-Gt9xNyRrCHCiyX/ZxDGOcBnlJl0I3IWicpZRC4CdC0P5a/I07Ya2OAMEBU+J7GmRFVmIetqEYRko6QYRuKOESw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-export-default-from@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.0.0.tgz#084b639bce3d42f3c5bf3f68ccb42220bb2d729d" - integrity sha512-HNnjg/fFFbnuLAqr/Ocp1Y3GB4AjmXcu1xxn3ql3bS2kGrB/qi+Povshb8i3hOkE5jNozzh8r/0/lq1w8oOWbQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17" - integrity sha512-zGcuZWiWWDa5qTZ6iAnpG0fnX/GOu49pGR5PFvkQ9GmKNaSphXQnlNXh/LG20sqWtNrx/eB6krzfEzcwvUyeFA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" - integrity sha512-PdmL2AoPsCLWxhIr3kG2+F9v4WH06Q3z+NoGVpQgnUNGcagXHq5sB3OXxkSahKq9TLdNMN/AJzFYSOo8UKDMHg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.0.0.tgz#b60931d5a15da82625fff6657c39419969598743" - integrity sha512-oAJmMsAvTSIk9y0sZdU2S/nY44PEUuHN7EzNDMgbuR4e/OwyfR9lSmoBJBZ2lslFZIqhksrTt4i+av7uKfNYDw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-chaining@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.0.0.tgz#1e6ecba124310b5d3a8fc1e00d50b1c4c2e05e68" - integrity sha512-QXedQsZf8yua1nNrXSePT0TsGSQH9A1iK08m9dhCMdZeJaaxYcQfXdgHWVV6Cp7WE/afPVvSKIsAHK5wP+yxDA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-typescript@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.1.5.tgz#956a1f43dec8a9d6b36221f5c865335555fdcb98" - integrity sha512-VqK5DFcS6/T8mT5CcJv1BwZLYFxkHiGZmP7Hs87F53lSToE/qfL7TpPrqFSaKyZi9w7Z/b/tmOGZZDupcJjFvw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" - integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.10" - -"@babel/plugin-transform-classes@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.1.0" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" - integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.1.6.tgz#4b7be62604d39e63cfe23b1d00d63e9fb7e763ba" - integrity sha512-0tyFAAjJmnRlr8MVJV39ASn1hv+PbdVP71hf7aAseqLfQ0o9QXk9htbMbq7/ZYXnUIp6gDw0lUUP0+PQMbbtmg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - -"@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-function-name@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== - dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - -"@babel/plugin-transform-object-assign@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0.tgz#fca6d7500d9675c42868b8f3882979201b9a5ad8" - integrity sha512-Dag8mxx7/03oj8F8PkNso8GEMhwGfeT0TL6KfMsa9Brjx4IpwZVl3WBvEmYks8BMhPmrvM5NQ/tjaMbwEj5ijA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-object-super@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" - integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - -"@babel/plugin-transform-parameters@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== - dependencies: - "@babel/helper-call-delegate" "^7.1.0" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-property-literals@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0.tgz#93759e6c023782e52c2da3b75eca60d4f10533ee" - integrity sha512-BX8xKuQTO0HzINxT6j/GiCwoJB0AOMs0HmLbEnAvcte8U8rSkNa/eSCAY+l1OA4JnCVq2jw2p6U8QQryy2fTPg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0.tgz#28e00584f9598c0dd279f6280eee213fa0121c3c" - integrity sha512-OSeEpFJEH5dw/TtxTg4nijl4nHBbhqbKL94Xo/Y17WKIf2qJWeIk/QeXACF19lG1vMezkxqruwnTjVizaW7u7w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.1.6.tgz#e6188e7d2a2dcd2796d45a87f8b0a8c906f57d1a" - integrity sha512-iU/IUlPEYDRwuqLwqVobzPAZkBOQoZ9xRTBmj6ANuk5g/Egn/zdNGnXlSoKeNmKoYVeIRxx5GZhWmMhLik8dag== - dependencies: - "@babel/helper-builder-react-jsx" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - -"@babel/plugin-transform-regenerator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" - integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== - dependencies: - regenerator-transform "^0.13.3" - -"@babel/plugin-transform-runtime@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.1.0.tgz#9f76920d42551bb577e2dc594df229b5f7624b63" - integrity sha512-WFLMgzu5DLQEah0lKTJzYb14vd6UiES7PTnXcvrPZ1VrwFeJ+mTbvr65fFAsXYMt2bIoOoC0jk76zY1S7HZjUg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - resolve "^1.8.1" - semver "^5.5.1" - -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-typescript@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.1.0.tgz#81e7b4be90e7317cbd04bf1163ebf06b2adee60b" - integrity sha512-TOTtVeT+fekAesiCHnPz+PSkYSdOSLyLn42DI45nxg6iCdlQY6LIj/tYqpMB0y+YicoTUiYiXqF8rG6SKfhw6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.0.0" - -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - regexpu-core "^4.1.3" - -"@babel/register@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" - integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g== - dependencies: - core-js "^2.5.7" - find-cache-dir "^1.0.0" - home-or-tmp "^3.0.0" - lodash "^4.17.10" - mkdirp "^0.5.1" - pirates "^4.0.0" - source-map-support "^0.5.9" - -"@babel/runtime@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" - integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== - dependencies: - regenerator-runtime "^0.12.0" - -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.1.2" - "@babel/types" "^7.1.2" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" - integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.1.6" - "@babel/types" "^7.1.6" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.10" - -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" - integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== - dependencies: - esutils "^2.0.2" - lodash "^4.17.10" - to-fast-properties "^2.0.0" - -"@firebase/app-types@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.3.2.tgz#a92dc544290e2893bd8c02a81e684dae3d8e7c85" - integrity sha512-ZD8lTgW07NGgo75bTyBJA8Lt9+NweNzot7lrsBtIvfciwUzaFJLsv2EShqjBeuhF7RpG6YFucJ6m67w5buCtzw== - -"@firebase/app@^0.3.1": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.3.5.tgz#7011ab5a16604d6c1b2964d513b88c61a0a5387c" - integrity sha512-DaAlb74yzwXbkFXvfsUVFeurSETPJAvKNtVpAKlS6RThyD+Y+ci1/8JVw4INm2hihbj/edxlAUelg9eoOZNCKA== - dependencies: - "@firebase/app-types" "0.3.2" - "@firebase/util" "0.2.3" - dom-storage "2.1.0" - tslib "1.9.0" - xmlhttprequest "1.8.0" - -"@firebase/database-types@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.3.2.tgz#70611a64dd460e0e253c7427f860d56a1afd86fe" - integrity sha512-9ZYdvYQ6r3aaHJarhUM5Hf6lQWu3ZJme+RR0o8qfBb9L04TL3uNjt+AJFku1ysVPntTn+9GqJjiIB2/OC3JtwA== - -"@firebase/database@^0.3.1": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.3.7.tgz#7cc9a83b2adff06137157e37d7f27545166afe74" - integrity sha512-BB5L3PqwQVJUdS1WY+sq3eun5n5oimFWolXYl6pyACJwqL2qnPp0cnjK6kOqTsRPPMayZZmfUI38RBDwXaUJhQ== - dependencies: - "@firebase/database-types" "0.3.2" - "@firebase/logger" "0.1.2" - "@firebase/util" "0.2.3" - faye-websocket "0.11.1" - tslib "1.9.0" - -"@firebase/logger@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.1.2.tgz#b8f11c855ce20db792cac583da0b8b8b01418f3a" - integrity sha512-4NHGRIbZChg9vDUxynzYrw14G/U/71v0pea+jXPicrpflL0N0PSCULXGGSTmzn9fqZ5W5djEwVLBCVwKndXG8w== - -"@firebase/util@0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@firebase/util/-/util-0.2.3.tgz#ad5513cb35eeecabae5169e439d4e200f0d180ae" - integrity sha512-ngAG4qYpcnnshUKbBlEiR9+j37U7dTrTVJlS4v7ahW1ROuyLT9xj6cWyHQANzcTR2yKLmEv3yfwoZwedz7V0oQ== - dependencies: - tslib "1.9.0" - -"@google-cloud/common@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.17.0.tgz#8ef558750db481fc10a13757a49479ab9a1c8c07" - integrity sha512-HRZLSU762E6HaKoGfJGa8W95yRjb9rY7LePhjaHK9ILAnFacMuUGVamDbTHu1csZomm1g3tZTtXfX/aAhtie/Q== - dependencies: - array-uniq "^1.0.3" - arrify "^1.0.1" - concat-stream "^1.6.0" - create-error-class "^3.0.2" - duplexify "^3.5.0" - ent "^2.2.0" - extend "^3.0.1" - google-auto-auth "^0.10.0" - is "^3.2.0" - log-driver "1.2.7" - methmeth "^1.1.0" - modelo "^4.2.0" - request "^2.79.0" - retry-request "^3.0.0" - split-array-stream "^1.0.0" - stream-events "^1.0.1" - string-format-obj "^1.1.0" - through2 "^2.0.3" - -"@google-cloud/common@^0.20.3": - version "0.20.3" - resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.20.3.tgz#639fb9ed07b0e20bdcfa84ebb0838b8cb2068e3b" - integrity sha512-jt8/R4EqDTQccv5WA9AEaS65llM5+mlxsuWu57G5Os8HTIpgPbcsOVMUeIvmTrBuPUYSoRIMW8d/pvv/95n0+g== - dependencies: - "@types/duplexify" "^3.5.0" - "@types/request" "^2.47.0" - arrify "^1.0.1" - axios "^0.18.0" - duplexify "^3.6.0" - ent "^2.2.0" - extend "^3.0.1" - google-auth-library "^1.6.0" - is "^3.2.1" - pify "^3.0.0" - request "^2.87.0" - retry-request "^4.0.0" - split-array-stream "^2.0.0" - stream-events "^1.0.4" - through2 "^2.0.3" - -"@google-cloud/firestore@^0.15.4": - version "0.15.4" - resolved "https://registry.yarnpkg.com/@google-cloud/firestore/-/firestore-0.15.4.tgz#5a23cc7d0c516d0e019e0a8554749b518a0f6723" - integrity sha512-/13TRfZK0oD4DXNuFkfKvITrHTuk0ZOOvbwBg58EunJPoraxJ2ZgboQSSUnI4CdeHZSmmr42z/1BFMEm4Su00Q== - dependencies: - "@google-cloud/common" "^0.20.3" - bun "^0.0.12" - deep-equal "^1.0.1" - extend "^3.0.1" - functional-red-black-tree "^1.0.1" - google-gax "^0.17.1" - google-proto-files "^0.16.1" - is "^3.2.1" - lodash.merge "^4.6.1" - pkg-up "^2.0.0" - through2 "^2.0.3" - -"@google-cloud/storage@^1.6.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-1.7.0.tgz#07bff573d92d5c294db6a04af246688875a8f74b" - integrity sha512-QaAxzCkbhspwajoaEnT0GcnQcpjPRcBrHYuQsXtD05BtOJgVnHCLXSsfUiRdU0nVpK+Thp7+sTkQ0fvk5PanKg== - dependencies: - "@google-cloud/common" "^0.17.0" - arrify "^1.0.0" - async "^2.0.1" - compressible "^2.0.12" - concat-stream "^1.5.0" - create-error-class "^3.0.2" - duplexify "^3.5.0" - extend "^3.0.0" - gcs-resumable-upload "^0.10.2" - hash-stream-validation "^0.2.1" - is "^3.0.1" - mime "^2.2.0" - mime-types "^2.0.8" - once "^1.3.1" - pumpify "^1.5.1" - request "^2.85.0" - safe-buffer "^5.1.1" - snakeize "^0.1.0" - stream-events "^1.0.1" - through2 "^2.0.0" - xdg-basedir "^3.0.0" - -"@invertase/tests-firebase-functions@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@invertase/tests-firebase-functions/-/tests-firebase-functions-0.0.1.tgz#13286db7243ef2b68385730366fad7e9d7e4916d" - integrity sha512-1Ej1mZZFE2b3mHXlwTlsSTPJKdU3XIeX1q/m10zoPt9C07Fl8d05yKOuGoovdJQHREUI9FKSX+JYeRB0FczxsQ== - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= - -"@sinonjs/commons@^1.0.2": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849" - integrity sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA== - dependencies: - type-detect "4.0.8" - -"@sinonjs/formatio@3.0.0", "@sinonjs/formatio@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.0.0.tgz#9d282d81030a03a03fa0c5ce31fd8786a4da311a" - integrity sha512-vdjoYLDptCgvtJs57ULshak3iJe4NW3sJ3g36xVDGff5AE8P30S6A093EIEPjdi2noGhfuNOEkbxt3J3awFW1w== - dependencies: - "@sinonjs/samsam" "2.1.0" - -"@sinonjs/samsam@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.0.tgz#b8b8f5b819605bd63601a6ede459156880f38ea3" - integrity sha512-5x2kFgJYupaF1ns/RmharQ90lQkd2ELS8A9X0ymkAAdemYHGtI2KiUHG8nX2WU0T1qgnOU5YMqnBM2V7NUanNw== - dependencies: - array-from "^2.1.1" - -"@sinonjs/samsam@^2.1.2": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.3.tgz#62cf2a9b624edc795134135fe37fc2ae8ea36be3" - integrity sha512-8zNeBkSKhU9a5cRNbpCKau2WWPfan+Q2zDlcXvXyhn9EsMqgYs4qzo0XHNVlXC6ABQL8fT6nV+zzo5RTHJzyXw== - -"@types/caseless@*": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a" - integrity sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A== - -"@types/duplexify@^3.5.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@types/duplexify/-/duplexify-3.6.0.tgz#dfc82b64bd3a2168f5bd26444af165bf0237dcd8" - integrity sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A== - dependencies: - "@types/node" "*" - -"@types/form-data@*": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" - integrity sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ== - dependencies: - "@types/node" "*" - -"@types/google-cloud__storage@^1.1.7": - version "1.7.2" - resolved "https://registry.yarnpkg.com/@types/google-cloud__storage/-/google-cloud__storage-1.7.2.tgz#28593a90c861299609344e30c9ee5a8895948901" - integrity sha512-RaQJ7+Ht20MRYJu7mgKBpbVNZIPneztKIl/DUKacRC6A8mXRsJfgDdPA7indHmJGIgm+hzUTj44+A3RyuuYZhg== - dependencies: - "@types/node" "*" - "@types/request" "*" - -"@types/long@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" - integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== - -"@types/node@*", "@types/node@^10.1.0": - version "10.12.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.11.tgz#715c476c99a5f6898a1ae61caf9825e43c03912e" - integrity sha512-3iIOhNiPGTdcUNVCv9e5G7GotfvJJe2pc9w2UgDXlUwnxSZ3RgcUocIU+xYm+rTU54jIKih998QE4dMOyMN1NQ== - -"@types/node@^8.0.53": - version "8.10.38" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.38.tgz#e05c201a668492e534b48102aca0294898f449f6" - integrity sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A== - -"@types/request@*", "@types/request@^2.47.0": - version "2.48.1" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.1.tgz#e402d691aa6670fbbff1957b15f1270230ab42fa" - integrity sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg== - dependencies: - "@types/caseless" "*" - "@types/form-data" "*" - "@types/node" "*" - "@types/tough-cookie" "*" - -"@types/tough-cookie@*": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.4.tgz#821878b81bfab971b93a265a561d54ea61f9059f" - integrity sha512-Set5ZdrAaKI/qHdFlVMgm/GsAv/wkXhSTuZFkJ+JI7HK+wIkIlOaUXSXieIvJ0+OvGIqtREFoE+NHJtEq0gtEw== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -absolute-path@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" - integrity sha1-p4di+9rftSl76ZsV01p4Wy8JW/c= - -accepts@~1.3.3, accepts@~1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= - dependencies: - mime-types "~2.1.18" - negotiator "0.6.1" - -acorn-es7-plugin@^1.0.12: - version "1.1.7" - resolved "https://registry.yarnpkg.com/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz#f2ee1f3228a90eead1245f9ab1922eb2e71d336b" - integrity sha1-8u4fMiipDurRJF+asZIusucdM2s= - -acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== - -acorn@^5.0.0: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== - -acorn@^6.0.2: - version "6.0.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" - integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== - -ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" - integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== - dependencies: - ansi-wrap "^0.1.0" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" - -ansi-escapes@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== - -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -ansi@^0.3.0, ansi@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" - integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -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" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - 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" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -aria-query@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" - integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= - dependencies: - ast-types-flow "0.0.7" - commander "^2.11.0" - -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= - -array-from@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" - integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= - -array-includes@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" - integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.7.0" - -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1, array-uniq@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -art@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2" - integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ== - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -ascli@~1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" - integrity sha1-vPpZdKYvGOgcq660lzKrSoj5Brw= - dependencies: - colour "~0.7.1" - optjs "~3.2.2" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -ast-types-flow@0.0.7, ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== - -async@^2.0.1, async@^2.3.0, async@^2.4.0, async@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== - dependencies: - lodash "^4.17.10" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== - -axios@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102" - integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI= - dependencies: - follow-redirects "^1.3.0" - is-buffer "^1.1.5" - -axobject-query@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" - integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== - dependencies: - ast-types-flow "0.0.7" - -babel-eslint@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" - integrity sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-scope "3.7.1" - eslint-visitor-keys "^1.0.0" - -babel-plugin-istanbul@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz#6892f529eff65a3e2d33d87dc5888ffa2ecd4a30" - integrity sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw== - dependencies: - find-up "^3.0.0" - istanbul-lib-instrument "^3.0.0" - test-exclude "^5.0.0" - -babel-plugin-module-resolver@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.1.1.tgz#881cf67e3d4b8400d5eaaefc1be44d2dc1fe404f" - integrity sha512-1Q77Al4ydp6nYApJ7sQ2fmgz30WuQgJZegIYuyOdbdpxenB/bSezQ3hDPsumIXGlUS4vUIv+EwFjzzXZNWtARw== - dependencies: - find-babel-config "^1.1.0" - glob "^7.1.2" - pkg-up "^2.0.0" - reselect "^3.0.1" - resolve "^1.4.0" - -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== - -babel-preset-fbjs@^3.0.0, babel-preset-fbjs@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.1.0.tgz#6d1438207369d96384d09257b01602dd0dda6608" - integrity sha512-j+B9xZsnqWFxHaqt3B8aFYftSgrcgbO5NF3mTtHYd6R442NJW2aBk3k+XvxXwIia98UuZxCg8psZY79bXbhwew== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.1.2.tgz#d6400cac1c4c660976d90d07a04351d89395f5e8" - integrity sha1-1kAMrBxMZgl22Q0HoENR2JOV9eg= - -base64-js@^1.1.2, base64-js@^1.2.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - 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" - -basic-auth@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" - integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== - dependencies: - safe-buffer "5.1.2" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -big-integer@^1.6.7: - version "1.6.36" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" - integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== - -bluebird@3.5.x: - version "3.5.3" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" - integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== - -bplist-creator@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" - integrity sha1-N98VNgkoJLh8QvlXsBNEEXNyrkU= - dependencies: - stream-buffers "~2.2.0" - -bplist-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" - integrity sha1-1g1dzCDLptx+HymbNdPh+V2vuuY= - dependencies: - big-integer "^1.6.7" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - 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-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" - integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= - dependencies: - node-int64 "^0.4.0" - -buffer-crc32@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -bun@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/bun/-/bun-0.0.12.tgz#d54fae69f895557f275423bc14b404030b20a5fc" - integrity sha512-Toms18J9DqnT+IfWkwxVTB2EaBprHvjlMWrTIsfX4xbu3ZBqVBwrERU0em1IgtRe04wT+wJxMlKHZok24hrcSQ== - dependencies: - readable-stream "~1.0.32" - -bunyan-debug-stream@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-1.1.1.tgz#4740a00b7d5c2d9d1b714925ab0802516040813e" - integrity sha512-jJbQ1gXUL6vMmZVdbaTFK1v1sGa7axLrSQQwkB6HU9HCPTzsw2HsKcPHm1vgXZlEck/4IvEuRwg/9+083YelCg== - dependencies: - colors "^1.0.3" - exception-formatter "^1.0.4" - -bunyan@^1.8.12: - version "1.8.12" - resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" - integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c= - optionalDependencies: - dtrace-provider "~0.8" - moment "^2.10.6" - mv "~2" - safe-json-stringify "~1" - -bytebuffer@~5: - version "5.0.1" - resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" - integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= - dependencies: - long "~3" - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - 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" - -caching-transform@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-2.0.0.tgz#e1292bd92d35b6e8b1ed7075726724b3bd64eea0" - integrity sha512-tTfemGmFWe7KZ3KN6VsSgQZbd9Bgo7A40wlp4PTsJJvFu4YAnEC5YnfdiKq6Vh2i9XJLnA9n8OXD46orVpnPMw== - dependencies: - make-dir "^1.0.0" - md5-hex "^2.0.0" - package-hash "^2.0.0" - write-file-atomic "^2.0.0" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -call-signature@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" - integrity sha1-qEq8glpV70yysCi9dOIFpluaSZY= - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= - dependencies: - callsites "^0.2.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -camelcase@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -capture-exit@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" - integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= - dependencies: - rsvp "^3.3.3" - -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - 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.0.0, chalk@^2.1.0, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -child-process-promise@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" - integrity sha1-RzChHvYQ+tRQuPIjx50x172tgHQ= - dependencies: - cross-spawn "^4.0.2" - node-version "^1.0.0" - promise-polyfill "^6.0.1" - -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== - -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -cliui@^3.0.3, cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -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" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -colors@^1.0.3: - version "1.3.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" - integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ== - -colour@~0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" - integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" - integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== - dependencies: - delayed-stream "~1.0.0" - -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - -commander@^2.11.0, commander@^2.15.1, commander@^2.9.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== - -commander@~2.17.1: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= - -compressible@^2.0.12, compressible@~2.0.14: - version "2.0.15" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212" - integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw== - dependencies: - mime-db ">= 1.36.0 < 2" - -compression@^1.7.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" - integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.14" - debug "2.6.9" - on-headers "~1.0.1" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0, concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -configstore@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -connect@^3.6.5: - version "3.6.6" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" - integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= - dependencies: - debug "2.6.9" - finalhandler "1.1.0" - parseurl "~1.3.2" - utils-merge "1.0.1" - -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" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - -convert-source-map@^1.1.0, convert-source-map@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== - dependencies: - safe-buffer "~5.1.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= - -core-js@^2.0.0, core-js@^2.2.2, core-js@^2.4.1, core-js@^2.5.7: - version "2.5.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== - -core-util-is@1.0.2, 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" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.5: - version "5.0.7" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" - integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.9.0" - parse-json "^4.0.0" - -create-error-class@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= - dependencies: - capture-stack-trace "^1.0.0" - -create-react-class@^15.6.3: - version "15.6.3" - resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" - integrity sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg== - dependencies: - fbjs "^0.8.9" - loose-envify "^1.3.1" - object-assign "^4.1.1" - -cross-spawn@^4, cross-spawn@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.0.1, cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - -damerau-levenshtein@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" - integrity sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8= - -debug@2.6.9, 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" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.1.0, debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -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" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -define-properties@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - 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" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - 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" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -denodeify@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" - integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -detox@^9.0.1, detox@^9.0.4: - version "9.1.2" - resolved "https://registry.yarnpkg.com/detox/-/detox-9.1.2.tgz#f71b9dafcf006ef9a4a456528726b38a107205cf" - integrity sha512-pVyyDHPekYxzQK+sComeYXau5oNG1ZyMGjhEB8ecSbg5EaK1MhIyaLDxri4eDXVnOgLizFP9gqHZSgPcpdITRg== - dependencies: - bunyan "^1.8.12" - bunyan-debug-stream "^1.1.0" - child-process-promise "^2.2.0" - commander "^2.15.1" - fs-extra "^4.0.2" - get-port "^2.1.0" - ini "^1.3.4" - lodash "^4.17.5" - minimist "^1.2.0" - proper-lockfile "^3.0.2" - sanitize-filename "^1.6.1" - shell-utils "^1.0.9" - tail "^1.2.3" - telnet-client "0.15.3" - tempfile "^2.0.0" - ws "^1.1.1" - -diff-match-patch@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1" - integrity sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg== - -diff@3.5.0, diff@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -dir-glob@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== - dependencies: - arrify "^1.0.1" - path-type "^3.0.0" - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -dom-storage@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/dom-storage/-/dom-storage-2.1.0.tgz#00fb868bc9201357ea243c7bcfd3304c1e34ea39" - integrity sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q== - -dom-walk@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" - integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= - -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== - dependencies: - is-obj "^1.0.0" - -dtrace-provider@~0.8: - version "0.8.7" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" - integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= - dependencies: - nan "^2.10.0" - -duplexify@^3.5.0, duplexify@^3.6.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" - integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ecdsa-sig-formatter@1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz#1c595000f04a8897dfb85000892a0f4c33af86c3" - integrity sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM= - dependencies: - safe-buffer "^5.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -emoji-regex@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" - integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ== - -empower-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-1.2.0.tgz#ce3fb2484d5187fa29c23fba8344b0b2fdf5601c" - integrity sha512-g6+K6Geyc1o6FdXs9HwrXleCFan7d66G5xSCfSF7x1mJDCes6t0om9lFQG3zOrzh3Bkb/45N0cZ5Gqsf7YrzGQ== - dependencies: - call-signature "0.0.2" - core-js "^2.0.0" - -empower@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/empower/-/empower-1.3.1.tgz#768979cbbb36d71d8f5edaab663deacb9dab916c" - integrity sha512-uB6/ViBaawOO/uujFADTK3SqdYlxYNn+N4usK9MRKZ4Hbn/1QSy8k2PezxCA2/+JGbF8vd/eOfghZ90oOSDZCA== - dependencies: - core-js "^2.0.0" - empower-core "^1.2.0" - -encodeurl@~1.0.1, encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - -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" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== - dependencies: - once "^1.4.0" - -ent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= - -envinfo@^5.7.0: - version "5.12.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" - integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== - -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" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d" - integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw== - dependencies: - stackframe "^1.0.4" - -errorhandler@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.0.tgz#eaba64ca5d542a311ac945f582defc336165d9f4" - integrity sha1-6rpkyl1UKjEayUX1gt78M2Fl2fQ= - dependencies: - accepts "~1.3.3" - escape-html "~1.0.3" - -es-abstract@^1.6.1, es-abstract@^1.7.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - -es-to-primitive@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -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" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-airbnb-base@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c" - integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw== - dependencies: - eslint-restricted-globals "^0.1.1" - object.assign "^4.1.0" - object.entries "^1.0.4" - -eslint-config-airbnb@^17.0.0: - version "17.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz#3964ed4bc198240315ff52030bf8636f42bc4732" - integrity sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw== - dependencies: - eslint-config-airbnb-base "^13.1.0" - object.assign "^4.1.0" - object.entries "^1.0.4" - -eslint-import-resolver-node@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== - dependencies: - debug "^2.6.9" - resolve "^1.5.0" - -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= - dependencies: - debug "^2.6.8" - pkg-dir "^1.0.0" - -eslint-plugin-flowtype@^2.46.3: - version "2.50.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" - integrity sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ== - dependencies: - lodash "^4.17.10" - -eslint-plugin-import@^2.11.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== - dependencies: - contains-path "^0.1.0" - debug "^2.6.8" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" - read-pkg-up "^2.0.0" - resolve "^1.6.0" - -eslint-plugin-jsx-a11y@^6.0.3: - version "6.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88" - integrity sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw== - dependencies: - aria-query "^3.0.0" - array-includes "^3.0.3" - ast-types-flow "^0.0.7" - axobject-query "^2.0.1" - damerau-levenshtein "^1.0.4" - emoji-regex "^6.5.1" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - -eslint-plugin-react@^7.7.0: - version "7.11.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" - integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw== - dependencies: - array-includes "^3.0.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - prop-types "^15.6.2" - -eslint-restricted-globals@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" - integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= - -eslint-scope@3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== - -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== - -eslint@^5.5.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" - integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^2.1.0" - eslint-scope "^4.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^4.0.0" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - imurmurhash "^0.1.4" - inquirer "^6.1.0" - is-resolvable "^1.1.0" - js-yaml "^3.12.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.5" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - regexpp "^2.0.1" - require-uncached "^1.0.3" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.0.2" - text-table "^0.2.0" - -espree@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== - dependencies: - acorn "^6.0.2" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -espurify@^1.6.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" - integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== - dependencies: - core-js "^2.0.0" - -esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= - -esutils@^2.0.0, esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -event-target-shim@^1.0.5: - version "1.1.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491" - integrity sha1-qG5e5r2qFgVEddp5fM3fDFVphJE= - -eventemitter3@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== - -exception-formatter@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/exception-formatter/-/exception-formatter-1.0.7.tgz#3291616b86fceabefa97aee6a4708032c6e3b96d" - integrity sha512-zV45vEsjytJrwfGq6X9qd1Ll56cW4NC2mhCO6lqwMk4ZpA1fZ6C3UiaQM/X7if+7wZFmCgss3ahp9B/uVFuLRw== - dependencies: - colors "^1.0.3" - -exec-sh@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" - integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== - dependencies: - merge "^1.2.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - 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" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.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@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - 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" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= - dependencies: - kind-of "^1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - 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" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@^3.0.1, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^2.0.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - -external-editor@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - 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" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-glob@^2.0.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" - integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -faye-websocket@0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" - integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= - dependencies: - websocket-driver ">=0.5.1" - -fb-watchman@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" - integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= - dependencies: - bser "^2.0.0" - -fbjs-css-vars@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.1.tgz#836d876e887d702f45610f5ebd2fbeef649527fc" - integrity sha512-IM+v/C40MNZWqsLErc32e0TyIk/NhkkQZL0QmjBh6zi1eXv0/GeVKmKmueQX7nn9SXQBQbTUcB8zuexIF3/88w== - -fbjs-scripts@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.0.1.tgz#7d8d09d76e83308bf3b1fc7b4c9c6fd081c5ef64" - integrity sha512-x8bfX7k0z5B24Ue0YqjZq/2QxxaKZUNbkGdX//zbQDElMJFqBRrvRi8O3qds7UNNzs78jYqIYCS32Sk/wu5UJg== - dependencies: - "@babel/core" "^7.0.0" - ansi-colors "^1.0.1" - babel-preset-fbjs "^3.0.0" - core-js "^2.4.1" - cross-spawn "^5.1.0" - fancy-log "^1.3.2" - object-assign "^4.0.1" - plugin-error "^0.1.2" - semver "^5.1.0" - through2 "^2.0.0" - -fbjs@^0.8.16, fbjs@^0.8.9: - version "0.8.17" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" - integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - -fbjs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" - integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA== - dependencies: - core-js "^2.4.1" - fbjs-css-vars "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" - integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= - dependencies: - debug "2.6.9" - encodeurl "~1.0.1" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.3.1" - unpipe "~1.0.0" - -find-babel-config@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355" - integrity sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U= - dependencies: - json5 "^0.5.1" - path-exists "^3.0.0" - -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= - dependencies: - commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" - -find-cache-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" - integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== - dependencies: - commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^3.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -firebase-admin@^5.12.0: - version "5.13.1" - resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-5.13.1.tgz#79cfa2ce20c90061ae09176e33b7767c1eb02f96" - integrity sha1-ec+iziDJAGGuCRduM7d2fB6wL5Y= - dependencies: - "@firebase/app" "^0.3.1" - "@firebase/database" "^0.3.1" - "@google-cloud/firestore" "^0.15.4" - "@google-cloud/storage" "^1.6.0" - "@types/google-cloud__storage" "^1.1.7" - "@types/node" "^8.0.53" - jsonwebtoken "8.1.0" - node-forge "0.7.4" - -flat-cache@^1.2.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" - integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== - dependencies: - circular-json "^0.3.1" - graceful-fs "^4.1.2" - rimraf "~2.6.2" - write "^0.2.1" - -flow-bin@^0.78.0: - version "0.78.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.78.0.tgz#df9fe7f9c9a2dfaff39083949fe2d831b41627b7" - integrity sha512-LV55tE+ItkC9HQAbEK+VxpBe54Ryp/dj4q9KmqDIfhV7mtP+hbvc/1AUf/AaWFIve3eURO0cxoGN4ZQQ3o2HTg== - -follow-redirects@^1.3.0: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= - dependencies: - for-in "^1.0.1" - -foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-extra@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - -fs-extra@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - -function-bind@^1.1.0, function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gauge@~1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" - integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= - dependencies: - ansi "^0.3.0" - has-unicode "^2.0.0" - lodash.pad "^4.1.0" - lodash.padend "^4.1.0" - lodash.padstart "^4.1.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - 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" - -gcp-metadata@^0.6.1, gcp-metadata@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-0.6.3.tgz#4550c08859c528b370459bd77a7187ea0bdbc4ab" - integrity sha512-MSmczZctbz91AxCvqp9GHBoZOSbJKAICV7Ow/AIWSJZRrRchUd5NL1b2P4OfP+4m490BEUPhhARfpHdqCxuCvg== - dependencies: - axios "^0.18.0" - extend "^3.0.1" - retry-axios "0.3.2" - -gcs-resumable-upload@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/gcs-resumable-upload/-/gcs-resumable-upload-0.10.2.tgz#7f29b3ee23dcec4170367c0711418249c660545f" - integrity sha1-fymz7iPc7EFwNnwHEUGCScZgVF8= - dependencies: - configstore "^3.1.2" - google-auto-auth "^0.10.0" - pumpify "^1.4.0" - request "^2.85.0" - stream-events "^1.0.3" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-port@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-2.1.0.tgz#8783f9dcebd1eea495a334e1a6a251e78887ab1a" - integrity sha1-h4P53OvR7qSVozThpqJR54iHqxo= - dependencies: - pinkie-promise "^2.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" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -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" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - 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" - -glob@^6.0.1: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - 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" - -global@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" - integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= - dependencies: - min-document "^2.19.0" - process "~0.5.1" - -globals@^11.1.0, globals@^11.7.0: - version "11.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== - -globby@^8.0.0, globby@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" - integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - fast-glob "^2.0.2" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -google-auth-library@^1.3.1, google-auth-library@^1.6.0, google-auth-library@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.6.1.tgz#9c73d831ad720c0c3048ab89d0ffdec714d07dd2" - integrity sha512-jYiWC8NA9n9OtQM7ANn0Tk464do9yhKEtaJ72pKcaBiEwn4LwcGYIYOfwtfsSm3aur/ed3tlSxbmg24IAT6gAg== - dependencies: - axios "^0.18.0" - gcp-metadata "^0.6.3" - gtoken "^2.3.0" - jws "^3.1.5" - lodash.isstring "^4.0.1" - lru-cache "^4.1.3" - retry-axios "^0.3.2" - -google-auto-auth@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/google-auto-auth/-/google-auto-auth-0.10.1.tgz#68834a6f3da59a6cb27fce56f76e3d99ee49d0a2" - integrity sha512-iIqSbY7Ypd32mnHGbYctp80vZzXoDlvI9gEfvtl3kmyy5HzOcrZCIGCBdSlIzRsg7nHpQiHE3Zl6Ycur6TSodQ== - dependencies: - async "^2.3.0" - gcp-metadata "^0.6.1" - google-auth-library "^1.3.1" - request "^2.79.0" - -google-gax@^0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-0.17.1.tgz#825ead4ab68f1cb3a702ed0a6c64d7ac9b882747" - integrity sha512-fAKvFx++SRr6bGWamWuVOkJzJnQqMgpJkhaB2oEwfFJ91rbFgEmIPRmZZ/MeIVVFUOuHUVyZ8nwjm5peyTZJ6g== - dependencies: - duplexify "^3.6.0" - extend "^3.0.1" - globby "^8.0.1" - google-auth-library "^1.6.1" - google-proto-files "^0.16.0" - grpc "^1.12.2" - is-stream-ended "^0.1.4" - lodash "^4.17.10" - protobufjs "^6.8.6" - retry-request "^4.0.0" - through2 "^2.0.3" - -google-p12-pem@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-1.0.2.tgz#c8a3843504012283a0dbffc7430b7c753ecd4b07" - integrity sha512-+EuKr4CLlGsnXx4XIJIVkcKYrsa2xkAmCvxRhX2HsazJzUBAJ35wARGeApHUn4nNfPD03Vl057FskNr20VaCyg== - dependencies: - node-forge "^0.7.4" - pify "^3.0.0" - -google-proto-files@^0.16.0, google-proto-files@^0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/google-proto-files/-/google-proto-files-0.16.1.tgz#e422e4c0cfd65c481b63f3c0e0cca03ba9cd97ce" - integrity sha512-ykdhaYDiU/jlyrkzZDPemraKwVIgLT31XMHVNSJW//R9VED56hqSDRMx1Jlxbf0O4iDZnBWQ0JQLHbM2r5+wuA== - dependencies: - globby "^8.0.0" - power-assert "^1.4.4" - protobufjs "^6.8.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -grpc@^1.12.2: - version "1.16.1" - resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.16.1.tgz#533316f38cea68111ef577728c3f4e8e9e554543" - integrity sha512-7uHN1Nd3UqfvwgQ6f5U3+EZb/0iuHJ9mbPH+ydaTkszJsUi3nwdz6DuSh0eJwYVXXn6Gojv2khiQAadMongGKg== - dependencies: - lodash "^4.17.5" - nan "^2.0.0" - node-pre-gyp "^0.12.0" - protobufjs "^5.0.3" - -gtoken@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-2.3.0.tgz#4e0ffc16432d7041a1b3dbc1d97aac17a5dc964a" - integrity sha512-Jc9/8mV630cZE9FC5tIlJCZNdUjwunvlwOtCz6IDlaiB4Sz68ki29a1+q97sWTnTYroiuF9B135rod9zrQdHLw== - dependencies: - axios "^0.18.0" - google-p12-pem "^1.0.0" - jws "^3.1.4" - mime "^2.2.0" - pify "^3.0.0" - -handlebars@^4.0.11: - version "4.0.12" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" - integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== - dependencies: - async "^2.5.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - 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" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - 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" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.1, has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-stream-validation@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hash-stream-validation/-/hash-stream-validation-0.2.1.tgz#ecc9b997b218be5bb31298628bb807869b73dcd1" - integrity sha1-7Mm5l7IYvluzEphii7gHhptz3NE= - dependencies: - through2 "^2.0.0" - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - -home-or-tmp@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" - integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs= - -hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.4.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" - integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - 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" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -image-size@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" - integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.3, 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" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -inquirer@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" - integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.17.10" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^5.0.0" - through "^2.3.6" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - 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" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -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" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - 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" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.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" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -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" - integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= - dependencies: - builtin-modules "^1.0.0" - -is-callable@^1.1.3, is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== - -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" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - 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" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - 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" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - -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" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - -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" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -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" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - 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" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - 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" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= - dependencies: - is-extglob "^2.1.1" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - 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" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -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" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= - dependencies: - has "^1.0.1" - -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - -is-stream-ended@^0.1.0, is-stream-ended@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-stream-ended/-/is-stream-ended-0.1.4.tgz#f50224e95e06bce0e356d440a4827cd35b267eda" - integrity sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw== - -is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== - dependencies: - has-symbols "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is@^3.0.1, is@^3.2.0, is@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" - integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - 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" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" - integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== - -istanbul-lib-coverage@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" - integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== - -istanbul-lib-hook@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" - integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== - dependencies: - append-transform "^1.0.0" - -istanbul-lib-instrument@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" - integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== - dependencies: - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.1" - semver "^5.5.0" - -istanbul-lib-report@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" - integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== - dependencies: - istanbul-lib-coverage "^2.0.1" - make-dir "^1.3.0" - supports-color "^5.4.0" - -istanbul-lib-source-maps@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" - integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^2.0.1" - make-dir "^1.3.0" - rimraf "^2.6.2" - source-map "^0.6.1" - -istanbul-reports@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" - integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== - dependencies: - handlebars "^4.0.11" - -jest-haste-map@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" - integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - invariant "^2.2.4" - jest-serializer "^24.0.0-alpha.6" - jest-worker "^24.0.0-alpha.6" - micromatch "^2.3.11" - sane "^3.0.0" - -jest-serializer@24.0.0-alpha.6, jest-serializer@^24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" - integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== - -jest-worker@24.0.0-alpha.6, jest-worker@^24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" - integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== - dependencies: - merge-stream "^1.0.1" - -jet@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/jet/-/jet-0.2.0.tgz#84b7efc4fccd7da74c33447db7264d6942051e1d" - integrity sha512-2x+lRRTdRJLuM7w4ybVVGejTn9K5Wl3Gertm09soPePABMcwYSQu2bKi2Xpoi3Cjg8bDgc17UXAvQO92rbC7Dw== - dependencies: - chalk "^2.4.1" - error-stack-parser "^2.0.2" - istanbul-lib-coverage "^1.2.0" - should "^13.2.1" - should-sinon "0.0.6" - sinon "^6.1.4" - source-map "^0.7.3" - tinyqueue "^1.2.3" - ws "^6.0.0" - optionalDependencies: - detox "^9.0.1" - mocha "^5.2.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.12.0, js-yaml@^3.9.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -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" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== - dependencies: - minimist "^1.2.0" - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsonwebtoken@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz#c6397cd2e5fd583d65c007a83dc7bb78e6982b83" - integrity sha1-xjl80uX9WD1lwAeoPce7eOaYK4M= - dependencies: - jws "^3.1.4" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.0.0" - xtend "^4.0.1" - -jsonwebtoken@^8.2.1: - version "8.4.0" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" - integrity sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg== - dependencies: - jws "^3.1.5" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jsx-ast-utils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" - integrity sha1-6AGxs5mF4g//yHtA43SAgOLcrH8= - dependencies: - array-includes "^3.0.3" - -just-extend@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-3.0.0.tgz#cee004031eaabf6406da03a7b84e4fe9d78ef288" - integrity sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ== - -jwa@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.6.tgz#87240e76c9808dbde18783cf2264ef4929ee50e6" - integrity sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.10" - safe-buffer "^5.0.1" - -jws@^3.1.4, jws@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.5.tgz#80d12d05b293d1e841e7cb8b4e69e561adcf834f" - integrity sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ== - dependencies: - jwa "^1.1.5" - safe-buffer "^5.0.1" - -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= - -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" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - 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" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - 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" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -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" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -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" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - 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" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - 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" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= - -lodash.merge@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" - integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ== - -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= - -lodash.pad@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" - integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= - -lodash.padend@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= - -lodash.padstart@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" - integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= - -lodash.throttle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= - -lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== - -log-driver@1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" - integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== - -lolex@^2.3.2, lolex@^2.7.5: - version "2.7.5" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" - integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@~3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^4.0.1, lru-cache@^4.1.3: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^1.0.0, make-dir@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= - -md5-hex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" - integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -merge-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= - dependencies: - readable-stream "^2.0.1" - -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== - -merge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - -methmeth@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/methmeth/-/methmeth-1.1.0.tgz#e80a26618e52f5c4222861bb748510bd10e29089" - integrity sha1-6AomYY5S9cQiKGG7dIUQvRDikIk= - -metro-babel-register@^0.49.1: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.49.2.tgz#746c73311135bd6c2af4d83c2cc6c5cbcf0e8a65" - integrity sha512-xx+SNwJ3Dl4MmSNn1RpUGc7b5pyTxXdpqpE7Fuk499rZffypVI1uhKOjKt2lwQhlyD03sXuvB/m3RdEg3mivWg== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - -metro-babel7-plugin-react-transform@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.49.2.tgz#d4c43faa6f2b91cc1b244a36a5d708ae8d39dbb2" - integrity sha512-LpJT8UvqF/tvVqEwiLUTMjRPhEGdI8e2dr3424XaRANba3j0nqmrbKdJQsPE8TrcqMWR4RHmfsXk0ti5QrEvJg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - -metro-cache@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.49.2.tgz#355dd3dba9fbd805a7ca6f55646216d35ca98225" - integrity sha512-GFeK4bPQn/U9bbRlVPhu2dYMe/b/GsNOFPEResOxr0kQreHV81rs6Jzcr4pU+9HY7vFiEQ1oggnsLUmANuRyPQ== - dependencies: - jest-serializer "24.0.0-alpha.6" - metro-core "0.49.2" - mkdirp "^0.5.1" - rimraf "^2.5.4" - -metro-config@0.49.2, metro-config@^0.49.1: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.49.2.tgz#d9dd0cc32fdb9731b4685b0019c98874a6e4443b" - integrity sha512-olh50qIMWd+Mj47TQeFnIW9NIquMpfq2g2NT5k+rwI38Xfk+KBnV4BamxtzZuViH7eQI06+Cdyu4NvcZffBXGg== - dependencies: - cosmiconfig "^5.0.5" - metro "0.49.2" - metro-cache "0.49.2" - metro-core "0.49.2" - pretty-format "24.0.0-alpha.6" - -metro-core@0.49.2, metro-core@^0.49.1: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.49.2.tgz#e3d7f9f02454863fc047bd75c2e37d5544c72d1a" - integrity sha512-kqhvNPOUTUWOqfm4nFF8l0zWMp2BKO1BUx5KY7osFnVTUpDkuq9Iy433FqEFVhA2jUISrmnd0CTIPcDQyFNllQ== - dependencies: - jest-haste-map "24.0.0-alpha.6" - lodash.throttle "^4.1.1" - metro-resolver "0.49.2" - wordwrap "^1.0.0" - -metro-memory-fs@^0.49.1: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.49.2.tgz#af3128b8a60d02d4aed427558b42c8d210a5543c" - integrity sha512-bt7ve7iud5gU4Duo9MVMqohJ0nBxILHmQxFhDXOvJnttiDuIfQQUK84pVlo8maNkFbN8uxEJPLBjpD1DC1IOxA== - -metro-minify-uglify@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.49.2.tgz#f3b8615cb0e9afd714e4952842bcb9f4d71b4822" - integrity sha512-LfnR5N2784pnHe5ShioNkLHyUA1unDU6iLivehX2Waxno1oIP3xKYl/u/VTDET4L8AvLwa5HFACE2hbiWjGQ2Q== - dependencies: - uglify-es "^3.1.9" - -metro-react-native-babel-preset@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.49.2.tgz#8d53610e044e0c9a53a03d307e1c51f9e8577abc" - integrity sha512-N0+4ramShYCHSAVEPUNWIZuKZskWj8/RDSoinhadHpdpHORMbMxLkexSOVHLluB+XFQ+DENLEx5oVPYwOlENBA== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.49.2" - react-transform-hmr "^1.0.4" - -metro-resolver@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.49.2.tgz#b7580d7a24fdf96170a9d4099a66b29a18e6e5f8" - integrity sha512-Si9/A+jNQmVWlLSi6fXSG1tDEanYu99PMz/cAvM+aZy1yX9RyqfJzHzWVdr4lrNh+4DKCgDea94B9BjezqNYyw== - dependencies: - absolute-path "^0.0.0" - -metro-source-map@0.49.2: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.49.2.tgz#0f9e3d0286fc9549652c99b56b7aa2aec12372e7" - integrity sha512-gUQ9wq8iR05QeMqRbAJ+L961LVfoNKLBXSeEzHxoDNSwZ7jFYLMKn0ofLlfMy0S1javZGisS51l5OScLt83naQ== - dependencies: - source-map "^0.5.6" - -metro@0.49.2, metro@^0.49.1: - version "0.49.2" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.49.2.tgz#0fd615d9f451893a0816721b46e94dcf49dda0f6" - integrity sha512-GSNMigeQq+QQ++qwEnWx0hjtYCZIvogn4JuqpKqOyVqNbg+aIheJPvxfDzjF9OXM5WHuNsTfGLW8n5kbUmQJSg== - dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.0.1" - buffer-crc32 "^0.2.13" - chalk "^1.1.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" - jest-haste-map "24.0.0-alpha.6" - jest-worker "24.0.0-alpha.6" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-cache "0.49.2" - metro-config "0.49.2" - metro-core "0.49.2" - metro-minify-uglify "0.49.2" - metro-react-native-babel-preset "0.49.2" - metro-resolver "0.49.2" - metro-source-map "0.49.2" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - react-transform-hmr "^1.0.4" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" - source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.0" - xpipe "^1.0.5" - yargs "^9.0.0" - -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - 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-db@>= 1.36.0 < 2", mime-db@~1.37.0: - version "1.37.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" - integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== - -mime-db@~1.23.0: - version "1.23.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" - integrity sha1-oxtAcK2uon1zLqMzdApk0OyaZlk= - -mime-types@2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c" - integrity sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw= - dependencies: - mime-db "~1.23.0" - -mime-types@^2.0.8, mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19: - version "2.1.21" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" - integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== - dependencies: - mime-db "~1.37.0" - -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" - integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== - -mime@^1.3.4: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" - integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - 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" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.1, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== - 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" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - -modelo@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/modelo/-/modelo-4.2.3.tgz#b278588a4db87fc1e5107ae3a277c0876f38d894" - integrity sha512-9DITV2YEMcw7XojdfvGl3gDD8J9QjZTJ7ZOUuSAkP+F3T6rDbzMJuPktxptsdHYEvZcmXrCD3LMOhdSAEq6zKA== - -moment@^2.10.6: - version "2.22.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" - integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= - -morgan@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" - integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== - dependencies: - basic-auth "~2.0.0" - debug "2.6.9" - depd "~1.1.2" - on-finished "~2.3.0" - on-headers "~1.0.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.0.0, ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -mv@~2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" - integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= - dependencies: - mkdirp "~0.5.1" - ncp "~2.0.0" - rimraf "~2.4.0" - -nan@^2.0.0, nan@^2.10.0, nan@^2.9.2: - version "2.11.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - 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-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" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -ncp@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" - integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= - -needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nise@^1.4.5: - version "1.4.6" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.6.tgz#76cc3915925056ae6c405dd8ad5d12bde570c19f" - integrity sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A== - dependencies: - "@sinonjs/formatio" "3.0.0" - just-extend "^3.0.0" - lolex "^2.3.2" - path-to-regexp "^1.7.0" - text-encoding "^0.6.4" - -node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-fetch@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" - integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== - -node-forge@0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.4.tgz#8e6e9f563a1e32213aa7508cded22aa791dbf986" - integrity sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA== - -node-forge@^0.7.4: - version "0.7.6" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" - integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^5.2.1: - version "5.3.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01" - integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q== - dependencies: - growly "^1.3.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - 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" - -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - 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" - -node-version@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" - integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - 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" - integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== - 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@^2.0.1, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== - -npm-packlist@^1.1.6: - version "1.1.12" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== - 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" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -nullthrows@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.0.tgz#832bb19ef7fedab989f81675c846e2858a3917a2" - integrity sha512-YoigDq49JRqVCUlb4XlwZirXQiNCoXdwoyfklXJAEYHN+XKHWgDkrcWxNgxEtP7N+XF9Akp7Lr6wLq8HZxLttw== - -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" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -nyc@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" - integrity sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg== - dependencies: - archy "^1.0.0" - arrify "^1.0.1" - caching-transform "^2.0.0" - convert-source-map "^1.6.0" - debug-log "^1.0.1" - find-cache-dir "^2.0.0" - find-up "^3.0.0" - foreground-child "^1.5.6" - glob "^7.1.3" - istanbul-lib-coverage "^2.0.1" - istanbul-lib-hook "^2.0.1" - istanbul-lib-instrument "^3.0.0" - istanbul-lib-report "^2.0.2" - istanbul-lib-source-maps "^2.0.1" - istanbul-reports "^2.0.1" - make-dir "^1.3.0" - merge-source-map "^1.1.0" - resolve-from "^4.0.0" - rimraf "^2.6.2" - signal-exit "^3.0.2" - spawn-wrap "^1.4.2" - test-exclude "^5.0.0" - uuid "^3.3.2" - yargs "11.1.0" - yargs-parser "^9.0.2" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-keys@^1.0.0, object-keys@^1.0.11, object-keys@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" - integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.entries@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" - integrity sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.6.1" - function-bind "^1.1.0" - has "^1.0.1" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" - integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -opn@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" - integrity sha1-ttmec5n3jWXDuq/+8fsojpuFJDo= - dependencies: - object-assign "^4.0.1" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= - -optjs@~3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" - integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4= - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== - dependencies: - p-try "^2.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" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.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" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" - integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== - -package-hash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" - integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= - dependencies: - graceful-fs "^4.1.11" - lodash.flattendeep "^4.4.0" - md5-hex "^2.0.0" - release-zalgo "^1.0.0" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - 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" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-node-version@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.0.tgz#33d9aa8920dcc3c0d33658ec18ce237009a56d53" - integrity sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg== - -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= - dependencies: - isarray "0.0.1" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - 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" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pegjs@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" - integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" - integrity sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -plist@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" - integrity sha1-CjLKlIGxw2TpLhjcVch23p0B2os= - dependencies: - base64-js "1.1.2" - xmlbuilder "8.2.2" - xmldom "0.1.x" - -plist@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" - integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== - dependencies: - base64-js "^1.2.3" - xmlbuilder "^9.0.7" - xmldom "0.1.x" - -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - -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" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -power-assert-context-formatter@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-context-formatter/-/power-assert-context-formatter-1.2.0.tgz#8fbe72692288ec5a7203cdf215c8b838a6061d2a" - integrity sha512-HLNEW8Bin+BFCpk/zbyKwkEu9W8/zThIStxGo7weYcFkKgMuGCHUJhvJeBGXDZf0Qm2xis4pbnnciGZiX0EpSg== - dependencies: - core-js "^2.0.0" - power-assert-context-traversal "^1.2.0" - -power-assert-context-reducer-ast@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-context-reducer-ast/-/power-assert-context-reducer-ast-1.2.0.tgz#c7ca1c9e39a6fb717f7ac5fe9e76e192bf525df3" - integrity sha512-EgOxmZ/Lb7tw4EwSKX7ZnfC0P/qRZFEG28dx/690qvhmOJ6hgThYFm5TUWANDLK5NiNKlPBi5WekVGd2+5wPrw== - dependencies: - acorn "^5.0.0" - acorn-es7-plugin "^1.0.12" - core-js "^2.0.0" - espurify "^1.6.0" - estraverse "^4.2.0" - -power-assert-context-traversal@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-context-traversal/-/power-assert-context-traversal-1.2.0.tgz#f6e71454baf640de5c1c9c270349f5c9ab0b2e94" - integrity sha512-NFoHU6g2umNajiP2l4qb0BRWD773Aw9uWdWYH9EQsVwIZnog5bd2YYLFCVvaxWpwNzWeEfZIon2xtyc63026pQ== - dependencies: - core-js "^2.0.0" - estraverse "^4.1.0" - -power-assert-formatter@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/power-assert-formatter/-/power-assert-formatter-1.4.1.tgz#5dc125ed50a3dfb1dda26c19347f3bf58ec2884a" - integrity sha1-XcEl7VCj37HdomwZNH879Y7CiEo= - dependencies: - core-js "^2.0.0" - power-assert-context-formatter "^1.0.7" - power-assert-context-reducer-ast "^1.0.7" - power-assert-renderer-assertion "^1.0.7" - power-assert-renderer-comparison "^1.0.7" - power-assert-renderer-diagram "^1.0.7" - power-assert-renderer-file "^1.0.7" - -power-assert-renderer-assertion@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.2.0.tgz#3db6ffcda106b37bc1e06432ad0d748a682b147a" - integrity sha512-3F7Q1ZLmV2ZCQv7aV7NJLNK9G7QsostrhOU7U0RhEQS/0vhEqrRg2jEJl1jtUL4ZyL2dXUlaaqrmPv5r9kRvIg== - dependencies: - power-assert-renderer-base "^1.1.1" - power-assert-util-string-width "^1.2.0" - -power-assert-renderer-base@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/power-assert-renderer-base/-/power-assert-renderer-base-1.1.1.tgz#96a650c6fd05ee1bc1f66b54ad61442c8b3f63eb" - integrity sha1-lqZQxv0F7hvB9mtUrWFELIs/Y+s= - -power-assert-renderer-comparison@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-renderer-comparison/-/power-assert-renderer-comparison-1.2.0.tgz#e4f88113225a69be8aa586ead05aef99462c0495" - integrity sha512-7c3RKPDBKK4E3JqdPtYRE9cM8AyX4LC4yfTvvTYyx8zSqmT5kJnXwzR0yWQLOavACllZfwrAGQzFiXPc5sWa+g== - dependencies: - core-js "^2.0.0" - diff-match-patch "^1.0.0" - power-assert-renderer-base "^1.1.1" - stringifier "^1.3.0" - type-name "^2.0.1" - -power-assert-renderer-diagram@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.2.0.tgz#37f66e8542e5677c5b58e6d72b01c0d9a30e2219" - integrity sha512-JZ6PC+DJPQqfU6dwSmpcoD7gNnb/5U77bU5KgNwPPa+i1Pxiz6UuDeM3EUBlhZ1HvH9tMjI60anqVyi5l2oNdg== - dependencies: - core-js "^2.0.0" - power-assert-renderer-base "^1.1.1" - power-assert-util-string-width "^1.2.0" - stringifier "^1.3.0" - -power-assert-renderer-file@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-renderer-file/-/power-assert-renderer-file-1.2.0.tgz#3f4bebd9e1455d75cf2ac541e7bb515a87d4ce4b" - integrity sha512-/oaVrRbeOtGoyyd7e4IdLP/jIIUFJdqJtsYzP9/88R39CMnfF/S/rUc8ZQalENfUfQ/wQHu+XZYRMaCEZmEesg== - dependencies: - power-assert-renderer-base "^1.1.1" - -power-assert-util-string-width@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/power-assert-util-string-width/-/power-assert-util-string-width-1.2.0.tgz#6e06d5e3581bb876c5d377c53109fffa95bd91a0" - integrity sha512-lX90G0igAW0iyORTILZ/QjZWsa1MZ6VVY3L0K86e2eKun3S4LKPH4xZIl8fdeMYLfOjkaszbNSzf1uugLeAm2A== - dependencies: - eastasianwidth "^0.2.0" - -power-assert@^1.4.4: - version "1.6.1" - resolved "https://registry.yarnpkg.com/power-assert/-/power-assert-1.6.1.tgz#b28cbc02ae808afd1431d0cd5093a39ac5a5b1fe" - integrity sha512-VWkkZV6Y+W8qLX/PtJu2Ur2jDPIs0a5vbP0TpKeybNcIXmT4vcKoVkyTp5lnQvTpY/DxacAZ4RZisHRHLJcAZQ== - dependencies: - define-properties "^1.1.2" - empower "^1.3.1" - power-assert-formatter "^1.4.1" - universal-deep-strict-equal "^1.2.1" - xtend "^4.0.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - -pretty-format@24.0.0-alpha.4: - version "24.0.0-alpha.4" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.4.tgz#cc1f7497e2496b71f8ad99f1526096e515fada03" - integrity sha512-icvbBt3XlLEVqPHdHwR2Ou9+hezS9Eccd+mA+fXfOU7T9t7ClOpq2HgCwlyw+3WogccCubKWnmzyrA/3ZZ/aOA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - -pretty-format@24.0.0-alpha.6: - version "24.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" - integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== - dependencies: - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - -private@^0.1.6: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -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" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -process@~0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= - -progress@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== - -promise-polyfill@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" - integrity sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc= - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2: - version "15.6.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== - dependencies: - loose-envify "^1.3.1" - object-assign "^4.1.1" - -proper-lockfile@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-3.2.0.tgz#89ca420eea1d55d38ca552578851460067bcda66" - integrity sha512-iMghHHXv2bsxl6NchhEaFck8tvX3F9cknEEh1SUpguUOBjN7PAAW9BLzmbc1g/mCD1gY3EE2EABBHPJfFdHFmA== - dependencies: - graceful-fs "^4.1.11" - retry "^0.12.0" - signal-exit "^3.0.2" - -protobufjs@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" - integrity sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA== - dependencies: - ascli "~1" - bytebuffer "~5" - glob "^7.0.5" - yargs "^3.10.0" - -protobufjs@^6.8.0, protobufjs@^6.8.6: - version "6.8.8" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" - integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.0" - "@types/node" "^10.1.0" - long "^4.0.0" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24: - version "1.1.29" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" - integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.4.0, pumpify@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - -range-parser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-clone-referenced-element@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz#9cdda7f2aeb54fea791f3ab8c6ab96c7a77d0158" - integrity sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg== - -react-deep-force-update@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" - integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== - -react-devtools-core@^3.4.0: - version "3.4.3" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.4.3.tgz#1a06b7dc546d41ecf8dc4fbabea2d79d339353cf" - integrity sha512-t3f6cRH5YSKv8qjRl1Z+1e0OwBZwJSdOAhJ9QAJdVKML7SmqAKKv3DxF+Ue03pE1N2UipPsLmaNcPzzMjIdZQg== - dependencies: - shell-quote "^1.6.1" - ws "^3.3.1" - -react-native@0.58.0-rc.1: - version "0.58.0-rc.1" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.58.0-rc.1.tgz#76e665ea07aafeae8436d74f8830954696d90115" - integrity sha512-iqHOIGRjRzdwKIIQMzYGOq+OogZvcJdp+ctwcaWnY0Q54cgO0N7MMgNmso+UVMpDpKc638CXnGEDqRKYmCJ14Q== - dependencies: - "@babel/runtime" "^7.0.0" - absolute-path "^0.0.0" - art "^0.10.0" - base64-js "^1.1.2" - chalk "^1.1.1" - commander "^2.9.0" - compression "^1.7.1" - connect "^3.6.5" - create-react-class "^15.6.3" - debug "^2.2.0" - denodeify "^1.2.1" - envinfo "^5.7.0" - errorhandler "^1.5.0" - escape-string-regexp "^1.0.5" - event-target-shim "^1.0.5" - fbjs "^1.0.0" - fbjs-scripts "^1.0.0" - fs-extra "^1.0.0" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.49.1" - metro-babel-register "^0.49.1" - metro-config "^0.49.1" - metro-core "^0.49.1" - metro-memory-fs "^0.49.1" - mime "^1.3.4" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-fetch "^2.2.0" - node-notifier "^5.2.1" - npmlog "^2.0.4" - nullthrows "^1.1.0" - opn "^3.0.2" - optimist "^0.6.1" - plist "^3.0.0" - pretty-format "24.0.0-alpha.4" - promise "^7.1.1" - prop-types "^15.5.8" - react-clone-referenced-element "^1.0.1" - react-devtools-core "^3.4.0" - regenerator-runtime "^0.11.0" - rimraf "^2.5.4" - semver "^5.0.3" - serve-static "^1.13.1" - shell-quote "1.6.1" - stacktrace-parser "^0.1.3" - ws "^1.1.0" - xcode "^1.0.0" - xmldoc "^0.4.0" - yargs "^9.0.0" - -react-proxy@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" - integrity sha1-nb/Z2SdSjDqp9ETkVYw3gwq4wmo= - dependencies: - lodash "^4.6.1" - react-deep-force-update "^1.0.0" - -react-transform-hmr@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" - integrity sha1-4aQL0Krvxy6N/Xp82gmvhQZjl7s= - dependencies: - global "^4.3.0" - react-proxy "^1.1.7" - -react@16.6.3: - version "16.6.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" - integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.11.2" - -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" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.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" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - 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" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - 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.6, readable-stream@^2.2.2, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - 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@~1.0.32: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -regenerate-unicode-properties@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" - integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - -regenerator-transform@^0.13.3: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" - integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== - dependencies: - private "^0.1.6" - -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - -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" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpu-core@^4.1.3: - version "4.2.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" - integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^7.0.0" - regjsgen "^0.4.0" - regjsparser "^0.3.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.0.2" - -regjsgen@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" - integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== - -regjsparser@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" - integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== - dependencies: - jsesc "~0.5.0" - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -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" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -request@^2.79.0, request@^2.81.0, request@^2.85.0, request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -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" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -reselect@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" - integrity sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc= - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== - dependencies: - path-parse "^1.0.5" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -retry-axios@0.3.2, retry-axios@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/retry-axios/-/retry-axios-0.3.2.tgz#5757c80f585b4cc4c4986aa2ffd47a60c6d35e13" - integrity sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ== - -retry-request@^3.0.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-3.3.2.tgz#fd8e0079e7b0dfc7056e500b6f089437db0da4df" - integrity sha512-WIiGp37XXDC6e7ku3LFoi7LCL/Gs9luGeeqvbPRb+Zl6OQMw4RCRfSaW+aLfE6lhz1R941UavE6Svl3Dm5xGIQ== - dependencies: - request "^2.81.0" - through2 "^2.0.0" - -retry-request@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-4.0.0.tgz#5c366166279b3e10e9d7aa13274467a05cb69290" - integrity sha512-S4HNLaWcMP6r8E4TMH52Y7/pM8uNayOcTDDQNBwsCccL1uI+Ol2TljxRDPzaNfbhOB30+XWP5NnZkB3LiJxi1w== - dependencies: - through2 "^2.0.0" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== - dependencies: - glob "^7.0.5" - -rimraf@~2.2.6: - version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= - -rimraf@~2.4.0: - version "2.4.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" - integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= - dependencies: - glob "^6.0.1" - -rsvp@^3.3.3: - version "3.6.2" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" - integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= - -rxjs@^6.1.0: - version "6.3.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, safe-buffer@^5.0.1, 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" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-json-stringify@~1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" - integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" - integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== - dependencies: - anymatch "^2.0.0" - capture-exit "^1.2.0" - exec-sh "^0.2.0" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.2.3" - -sanitize-filename@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" - integrity sha1-YS2hyWRz+gLczaktzVtKsWSmdyo= - dependencies: - truncate-utf8-bytes "^1.0.0" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -sax@~1.1.1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" - integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= - -scheduler@^0.11.2: - version "0.11.3" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.3.tgz#b5769b90cf8b1464f3f3cfcafe8e3cd7555a2d6b" - integrity sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== - -send@0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" - integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.4.0" - -serialize-error@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" - integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= - -serve-static@^1.13.1: - version "1.13.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" - integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.2" - send "0.16.2" - -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" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - 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" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - 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" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shell-quote@1.6.1, shell-quote@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" - -shell-utils@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/shell-utils/-/shell-utils-1.0.10.tgz#7fe7b8084f5d6d21323d941267013bc38aed063e" - integrity sha512-p1xuqhj3jgcXiV8wGoF1eL/NOvapN9tyGDoObqKwvZTUZn7fIzK75swLTEHfGa7sObeN9vxFplHw/zgYUYRTsg== - dependencies: - lodash "4.x.x" - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - -should-equal@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" - integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== - dependencies: - should-type "^1.4.0" - -should-format@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" - integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE= - dependencies: - should-type "^1.3.0" - should-type-adaptors "^1.0.1" - -should-sinon@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/should-sinon/-/should-sinon-0.0.6.tgz#be041a7c928f44ac9ccf5dc042d032618ce29f84" - integrity sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g== - -should-type-adaptors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" - integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== - dependencies: - should-type "^1.3.0" - should-util "^1.0.0" - -should-type@^1.3.0, should-type@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" - integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM= - -should-util@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063" - integrity sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM= - -should@^13.2.1: - version "13.2.3" - resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" - integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== - dependencies: - should-equal "^2.0.0" - should-format "^3.0.3" - should-type "^1.4.0" - should-type-adaptors "^1.0.1" - should-util "^1.0.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-plist@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-0.2.1.tgz#71766db352326928cf3a807242ba762322636723" - integrity sha1-cXZts1IyaSjPOoByQrp2IyJjZyM= - dependencies: - bplist-creator "0.0.7" - bplist-parser "0.1.1" - plist "2.0.1" - -sinon@^6.1.4, sinon@^6.2.0: - version "6.3.5" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-6.3.5.tgz#0f6d6a5b4ebaad1f6e8e019395542d1d02c144a0" - integrity sha512-xgoZ2gKjyVRcF08RrIQc+srnSyY1JDJtxu3Nsz07j1ffjgXoY6uPLf/qja6nDBZgzYYEovVkFryw2+KiZz11xQ== - dependencies: - "@sinonjs/commons" "^1.0.2" - "@sinonjs/formatio" "^3.0.0" - "@sinonjs/samsam" "^2.1.2" - diff "^3.5.0" - lodash.get "^4.4.2" - lolex "^2.7.5" - nise "^1.4.5" - supports-color "^5.5.0" - type-detect "^4.0.8" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slice-ansi@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" - integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - -snakeize@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/snakeize/-/snakeize-0.1.0.tgz#10c088d8b58eb076b3229bb5a04e232ce126422d" - integrity sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - 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" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - 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" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - 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" - -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" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - 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.5.9: - version "0.5.9" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -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" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.0, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -spawn-wrap@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" - integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.6.2" - signal-exit "^3.0.2" - which "^1.3.0" - -spdx-correct@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" - integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -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" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" - integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== - -split-array-stream@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-1.0.3.tgz#d2b75a8e5e0d824d52fdec8b8225839dc2e35dfa" - integrity sha1-0rdajl4Ngk1S/eyLgiWDncLjXfo= - dependencies: - async "^2.4.0" - is-stream-ended "^0.1.0" - -split-array-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-2.0.0.tgz#85a4f8bfe14421d7bca7f33a6d176d0c076a53b1" - integrity sha512-hmMswlVY91WvGMxs0k8MRgq8zb2mSen4FmDNc5AFiTWtrBpdZN6nwD6kROVe4vNL+ywrvbCKsWVCnEd4riELIg== - dependencies: - is-stream-ended "^0.1.4" - -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" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - 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" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" - integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stackframe@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" - integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw== - -stacktrace-parser@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" - integrity sha1-ATl5IuX2Ls8whFUiyVxP4dJefU4= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -statuses@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" - integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= - -statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== - -stream-buffers@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" - integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= - -stream-events@^1.0.1, stream-events@^1.0.3, stream-events@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" - integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== - dependencies: - stubs "^3.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -string-format-obj@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string-format-obj/-/string-format-obj-1.1.1.tgz#c7612ca4e2ad923812a81db192dc291850aa1f65" - integrity sha512-Mm+sROy+pHJmx0P/0Bs1uxIX6UhGJGj6xDGQZ5zh9v/SZRmLGevp+p0VJxV7lirrkAmQ2mvva/gHKpnF/pTb+Q== - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - 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, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringifier@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/stringifier/-/stringifier-1.4.0.tgz#d704581567f4526265d00ed8ecb354a02c3fec28" - integrity sha512-cNsMOqqrcbLcHTXEVmkw9y0fwDwkdgtZwlfyolzpQDoAE1xdNGhQhxBUfiDvvZIKl1hnUEgMv66nHwtMz3OjPw== - dependencies: - core-js "^2.0.0" - traverse "^0.6.6" - type-name "^2.0.1" - -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" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - 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" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== - dependencies: - ansi-regex "^4.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" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -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" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -stubs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" - integrity sha1-6NK6H6nJBXAwPAMLaQD31fiavls= - -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.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" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -table@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== - dependencies: - ajv "^6.6.1" - lodash "^4.17.11" - slice-ansi "2.0.0" - string-width "^2.1.1" - -tail@^1.2.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/tail/-/tail-1.4.0.tgz#884b216220b90804bfe87a4c8174c2efed0e2661" - integrity sha512-wjwfZw6wcMFTB1Po7NFUf4TdCDwX8duZjdTMhnHBEC677Q6mFRcVZE7f/nZDhG2Fpf/wEEKOJP9L7/b11/vlHQ== - -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -telnet-client@0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-0.15.3.tgz#99ec754e4acf6fa51dc69898f574df3c2550712e" - integrity sha512-GSfdzQV0BKIYsmeXq7bJFJ2wHeJud6icaIxCUf6QCGQUD6R0BBGbT1+yLDhq67JRdgRpwyPwUbV7JxFeRrZomQ== - dependencies: - bluebird "3.5.x" - -temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= - -temp@0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" - integrity sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k= - dependencies: - os-tmpdir "^1.0.0" - rimraf "~2.2.6" - -tempfile@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" - integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= - dependencies: - temp-dir "^1.0.0" - uuid "^3.0.1" - -test-exclude@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" - integrity sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw== - dependencies: - arrify "^1.0.1" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^1.0.1" - -text-encoding@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" - integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= - -through2@^2.0.0, through2@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -tinyqueue@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-1.2.3.tgz#b6a61de23060584da29f82362e45df1ec7353f3d" - integrity sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA== - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -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" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - 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" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - 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" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -traverse@^0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" - integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -truncate-utf8-bytes@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" - integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys= - dependencies: - utf8-byte-length "^1.0.1" - -tslib@1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" - integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== - -tslib@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8, type-detect@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-name@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" - integrity sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q= - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -ua-parser-js@^0.7.18: - version "0.7.19" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" - integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ== - -uglify-es@^3.1.9: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -uglify-js@^3.1.4: - version "3.4.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" - integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== - dependencies: - commander "~2.17.1" - source-map "~0.6.1" - -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" - integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" - integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg== - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - -universal-deep-strict-equal@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/universal-deep-strict-equal/-/universal-deep-strict-equal-1.2.2.tgz#0da4ac2f73cff7924c81fa4de018ca562ca2b0a7" - integrity sha1-DaSsL3PP95JMgfpN4BjKViyisKc= - dependencies: - array-filter "^1.0.0" - indexof "0.0.1" - object-keys "^1.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utf8-byte-length@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" - integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E= - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" - integrity sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE= - -uuid@^3.0.1, uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - -websocket-driver@>=0.5.1: - version "0.7.0" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" - integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs= - 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" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== - -whatwg-fetch@>=0.10.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - 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" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -window-size@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" - integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= - -wordwrap@^1.0.0, wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - 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" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^1.2.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8= - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= - dependencies: - mkdirp "^0.5.1" - -ws@^1.1.0, ws@^1.1.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" - integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w== - dependencies: - options ">=0.0.5" - ultron "1.0.x" - -ws@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^6.0.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" - integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== - dependencies: - async-limiter "~1.0.0" - -xcode@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-1.0.0.tgz#e1f5b1443245ded38c180796df1a10fdeda084ec" - integrity sha1-4fWxRDJF3tOMGAeW3xoQ/e2ghOw= - dependencies: - pegjs "^0.10.0" - simple-plist "^0.2.1" - uuid "3.0.1" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xmlbuilder@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" - integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M= - -xmlbuilder@^9.0.7: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= - -xmldoc@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" - integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= - dependencies: - sax "~1.1.1" - -xmldom@0.1.x: - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= - -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= - -xpipe@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" - integrity sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98= - -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= - -y18n@^3.2.0, y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= - dependencies: - camelcase "^4.1.0" - -yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" - integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= - dependencies: - camelcase "^4.1.0" - -yargs@11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" - integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== - dependencies: - cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^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 "^9.0.2" - -yargs@^3.10.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" - integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= - dependencies: - camelcase "^2.0.1" - cliui "^3.0.3" - decamelize "^1.1.1" - os-locale "^1.4.0" - string-width "^1.0.1" - window-size "^0.1.4" - y18n "^3.2.0" - -yargs@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - integrity sha1-UqzCP+7Kw0BCB47njAwAf1CF20w= - 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" diff --git a/tsconfig.json b/tsconfig.json index ee11838b..1f7dd063 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,10 @@ { + "include": ["packages/**/lib/*.d.ts", "packages/app-types/index.d.ts"], "compilerOptions": { "target": "es5", "module": "commonjs", + "declaration": true, + "importHelpers": true, "jsx": "react", "sourceMap": true, "strict": true, @@ -10,9 +13,13 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "moduleResolution": "node", + "skipLibCheck": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "lib": ["es2015", "es2016", "esnext", "dom"] }, - "files": ["./src/index.d.ts"] + "exclude": [ + "node_modules", + "**/*.spec.ts" + ] } diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..12c99dbb --- /dev/null +++ b/tslint.json @@ -0,0 +1,9 @@ +{ + "extends": ["tslint-config-airbnb", "tslint-config-prettier"], + "rulesDirectory": ["tslint-plugin-prettier"], + "rules": { + "prettier": true, + "import-name": false, + "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"] + } +} diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 00000000..59bcc6cf --- /dev/null +++ b/typedoc.json @@ -0,0 +1,4445 @@ +{ + "id": 0, + "name": "@react-native-firebase/analytics", + "kind": 0, + "flags": {}, + "children": [ + { + "id": 40, + "name": "\"@react-native-firebase/analytics\"", + "kind": 2, + "kindString": "Module", + "flags": {}, + "children": [ + { + "id": 43, + "name": "AnalyticsDefaultExport", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 125, + "character": 30 + } + ], + "type": { + "type": "reference", + "name": "ReactNativeFirebaseModuleAndStatics", + "id": 150, + "typeArguments": [ + { + "type": "reference", + "name": "Module", + "id": 3 + }, + { + "type": "reference", + "name": "Statics", + "id": 2 + } + ] + } + }, + { + "id": 41, + "name": "FirebaseNamespaceExport", + "kind": 32, + "kindString": "Variable", + "flags": { + "isConst": true + }, + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 114, + "character": 31 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reference", + "name": "__type" + }, + { + "type": "reference", + "name": "ReactNativeFirebaseNamespace" + } + ] + } + }, + { + "id": 42, + "name": "firebase", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "comment": { + "tags": [ + { + "tag": "example", + "text": "\n```js\nimport { firebase } from '@react-native-firebase/analytics';\nfirebase.analytics().logEvent(...);\n```\n" + } + ] + }, + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 123, + "character": 23 + } + ], + "type": { + "type": "reference", + "name": "ReactNativeFirebaseNamespace" + }, + "defaultValue": " FirebaseNamespaceExport" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 43, + 41, + 42 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 111, + "character": 49 + } + ] + }, + { + "id": 44, + "name": "\"@react-native-firebase/app-types\"", + "kind": 2, + "kindString": "Module", + "flags": {}, + "comment": { + "shortText": "Attach namespace to `firebase.` and `FirebaseApp.`." + }, + "children": [ + { + "id": 47, + "name": "FirebaseApp", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "children": [ + { + "id": 48, + "name": "analytics", + "kind": 2048, + "kindString": "Method", + "flags": {}, + "signatures": [ + { + "id": 49, + "name": "analytics", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Analytics integrates across Firebase features and provides\nyou with unlimited reporting for up to 500 distinct events\nthat you can define using the Firebase SDK. Analytics reports\nhelp you understand clearly how your users behave, which enables\nyou to make informed decisions regarding app marketing and\nperformance optimizations." + }, + "type": { + "type": "reference", + "name": "Module", + "id": 3 + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 167, + "character": 13 + } + ] + }, + { + "id": 114, + "name": "functions", + "kind": 2048, + "kindString": "Method", + "flags": { + "isOptional": true + }, + "signatures": [ + { + "id": 115, + "name": "functions", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "The Cloud Functions for Firebase client SDKs let you call functions\ndirectly from a Firebase app. To call a function from your app in this way,\nwrite and deploy an HTTPS Callable function in Cloud Functions,\nand then add client logic to call the function from your app." + }, + "parameters": [ + { + "id": 116, + "name": "region", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "Module", + "id": 92 + } + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 232, + "character": 13 + } + ] + }, + { + "id": 56, + "name": "utils", + "kind": 2048, + "kindString": "Method", + "flags": { + "isOptional": true + }, + "signatures": [ + { + "id": 57, + "name": "utils", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "parameters": [ + { + "id": 58, + "name": "app", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 47 + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseUtilsModule" + } + } + ], + "sources": [ + { + "fileName": "app/lib/index.d.ts", + "line": 37, + "character": 9 + } + ] + } + ], + "groups": [ + { + "title": "Methods", + "kind": 2048, + "children": [ + 48, + 114, + 56 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 158, + "character": 23 + }, + { + "fileName": "app/lib/index.d.ts", + "line": 36, + "character": 23 + }, + { + "fileName": "functions/lib/index.d.ts", + "line": 225, + "character": 23 + } + ] + }, + { + "id": 45, + "name": "ReactNativeFirebaseNamespace", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "children": [ + { + "id": 46, + "name": "analytics", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "comment": { + "shortText": "Analytics integrates across Firebase features and provides\nyou with unlimited reporting for up to 500 distinct events\nthat you can define using the Firebase SDK. Analytics reports\nhelp you understand clearly how your users behave, which enables\nyou to make informed decisions regarding app marketing and\nperformance optimizations." + }, + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 152, + "character": 13 + } + ], + "type": { + "type": "reference", + "name": "ReactNativeFirebaseModuleAndStatics", + "id": 150, + "typeArguments": [ + { + "type": "reference", + "name": "Module", + "id": 3 + }, + { + "type": "reference", + "name": "Statics", + "id": 2 + } + ] + } + }, + { + "id": 109, + "name": "functions", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "comment": { + "shortText": "The Cloud Functions for Firebase client SDKs let you call functions\ndirectly from a Firebase app. To call a function from your app in this way,\nwrite and deploy an HTTPS Callable function in Cloud Functions,\nand then add client logic to call the function from your app." + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 216, + "character": 13 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 110, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "signatures": [ + { + "id": 111, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "parameters": [ + { + "id": 112, + "name": "app", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 47 + } + } + ], + "type": { + "type": "reference", + "name": "Module", + "id": 92 + } + } + ], + "children": [ + { + "id": 113, + "name": "SDK_VERSION", + "kind": 32, + "kindString": "Variable", + "flags": {}, + "comment": { + "shortText": "This React Native Firebase Functions module version." + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 221, + "character": 26 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 113 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 216, + "character": 14 + } + ] + } + }, + { + "type": "reference", + "name": "Statics", + "id": 90 + } + ] + } + }, + { + "id": 52, + "name": "utils", + "kind": 1024, + "kindString": "Property", + "flags": { + "isOptional": true + }, + "sources": [ + { + "fileName": "app/lib/index.d.ts", + "line": 31, + "character": 9 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reflection", + "declaration": { + "id": 53, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "signatures": [ + { + "id": 54, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "parameters": [ + { + "id": 55, + "name": "app", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 47 + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseUtilsModule" + } + } + ] + } + } + ] + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 46, + 109, + 52 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 143, + "character": 40 + }, + { + "fileName": "app/lib/index.d.ts", + "line": 30, + "character": 40 + }, + { + "fileName": "functions/lib/index.d.ts", + "line": 209, + "character": 40 + } + ] + } + ], + "groups": [ + { + "title": "Interfaces", + "kind": 256, + "children": [ + 47, + 45 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 142, + "character": 49 + }, + { + "fileName": "app/lib/index.d.ts", + "line": 29, + "character": 49 + }, + { + "fileName": "functions/lib/index.d.ts", + "line": 208, + "character": 49 + } + ] + }, + { + "id": 101, + "name": "\"@react-native-firebase/functions\"", + "kind": 2, + "kindString": "Module", + "flags": {}, + "children": [ + { + "id": 104, + "name": "FunctionsDefaultExport", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 188, + "character": 30 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 105, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "signatures": [ + { + "id": 106, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "parameters": [ + { + "id": 107, + "name": "app", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 47 + } + } + ], + "type": { + "type": "reference", + "name": "Module", + "id": 92 + } + } + ], + "children": [ + { + "id": 108, + "name": "SDK_VERSION", + "kind": 32, + "kindString": "Variable", + "flags": {}, + "comment": { + "shortText": "This React Native Firebase Functions module version." + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 193, + "character": 24 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 108 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 188, + "character": 31 + } + ] + } + }, + { + "type": "reference", + "name": "Statics", + "id": 90 + } + ] + } + }, + { + "id": 102, + "name": "HttpsErrorCode", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 177, + "character": 29 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reference", + "name": "__type" + }, + { + "type": "reference", + "name": "HttpsErrorCode", + "id": 72 + } + ] + } + }, + { + "id": 103, + "name": "firebase", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "comment": { + "tags": [ + { + "tag": "example", + "text": "\n```js\nimport { firebase } from '@react-native-firebase/functions';\nfirebase.functions().httpsCallable(...);\n```\n" + } + ] + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 186, + "character": 23 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reference", + "name": "__type" + }, + { + "type": "reference", + "name": "ReactNativeFirebaseNamespace" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 104, + 102, + 103 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 173, + "character": 49 + } + ] + }, + { + "id": 50, + "name": "\"react-native-firebase\"", + "kind": 2, + "kindString": "Module", + "flags": {}, + "comment": { + "tags": [ + { + "tag": "firebase", + "text": "firebase\n" + } + ] + }, + "children": [ + { + "id": 51, + "name": "ReactNativeFirebase", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "sources": [ + { + "fileName": "app/lib/index.d.ts", + "line": 25, + "character": 27 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reference", + "name": "__type" + }, + { + "type": "reference", + "name": "ReactNativeFirebaseNamespace" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 51 + ] + } + ], + "sources": [ + { + "fileName": "app/lib/index.d.ts", + "line": 23, + "character": 38 + } + ] + }, + { + "id": 1, + "name": "Analytics", + "kind": 2, + "kindString": "Module", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Analytics integrates across Firebase features and provides\nyou with unlimited reporting for up to 500 distinct events\nthat you can define using the Firebase SDK. Analytics reports\nhelp you understand clearly how your users behave, which enables\nyou to make informed decisions regarding app marketing and\nperformance optimizations.", + "tags": [ + { + "tag": "firebase", + "text": "analytics\n" + } + ] + }, + "children": [ + { + "id": 3, + "name": "Module", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 39, + "name": "app", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "analytics/node_modules/@react-native-firebase/app-types/index.d.ts", + "line": 191, + "character": 5 + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp" + }, + "inheritedFrom": { + "type": "reference", + "name": "ReactNativeFirebaseModule.app" + } + }, + { + "id": 4, + "name": "logEvent", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 5, + "name": "logEvent", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Log a custom event with optional params.", + "tags": [ + { + "tag": "note", + "text": "100 characters is the maximum length for param key names.\n" + } + ] + }, + "parameters": [ + { + "id": 6, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 7, + "name": "params", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "\n" + }, + "type": { + "type": "reflection", + "declaration": { + "id": 8, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "indexSignature": [ + { + "id": 9, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": {}, + "parameters": [ + { + "id": 10, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 45, + "character": 34 + } + ] + } + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "reference", + "name": "Testy" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 45, + "character": 12 + } + ] + }, + { + "id": 37, + "name": "resetAnalyticsData", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 38, + "name": "resetAnalyticsData", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Clears all analytics data for this instance from the device and resets the app instance ID." + }, + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 107, + "character": 22 + } + ] + }, + { + "id": 11, + "name": "setAnalyticsCollectionEnabled", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 12, + "name": "setAnalyticsCollectionEnabled", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "If true, allows the device to collect analytical data and send it to Firebase.\nUseful for GDPR." + }, + "parameters": [ + { + "id": 13, + "name": "enabled", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "\n" + }, + "type": { + "type": "intrinsic", + "name": "boolean" + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 53, + "character": 33 + } + ] + }, + { + "id": 14, + "name": "setCurrentScreen", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 15, + "name": "setCurrentScreen", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Sets the current screen name.", + "tags": [ + { + "tag": "note", + "text": "Whilst screenClassOverride is optional, it is recommended it is\nalways sent as your current class name. For example on Android it will always\nshow as 'MainActivity' if you do not specify it.\n" + } + ] + }, + "parameters": [ + { + "id": 16, + "name": "screenName", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 17, + "name": "screenClassOverride", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 65, + "character": 20 + } + ] + }, + { + "id": 18, + "name": "setMinimumSessionDuration", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 19, + "name": "setMinimumSessionDuration", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Sets the minimum engagement time required before starting a session." + }, + "parameters": [ + { + "id": 20, + "name": "milliseconds", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "The default value is 10000 (10 seconds).\n" + }, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 72, + "character": 29 + } + ] + }, + { + "id": 21, + "name": "setSessionTimeoutDuration", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 22, + "name": "setSessionTimeoutDuration", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Sets the duration of inactivity that terminates the current session." + }, + "parameters": [ + { + "id": 23, + "name": "milliseconds", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "The default value is 1800000 (30 minutes).\n" + }, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 79, + "character": 29 + } + ] + }, + { + "id": 24, + "name": "setUserId", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 25, + "name": "setUserId", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Gives a user a unique identification." + }, + "parameters": [ + { + "id": 26, + "name": "id", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Set to null to remove a previously assigned id from analytics events\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 87, + "character": 13 + } + ] + }, + { + "id": 31, + "name": "setUserProperties", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 32, + "name": "setUserProperties", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Sets multiple key/value pair of data on the current user." + }, + "parameters": [ + { + "id": 33, + "name": "properties", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Set a property value to null to remove it.\n" + }, + "type": { + "type": "reflection", + "declaration": { + "id": 34, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "indexSignature": [ + { + "id": 35, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": {}, + "parameters": [ + { + "id": 36, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 102, + "character": 33 + } + ] + } + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 102, + "character": 21 + } + ] + }, + { + "id": 27, + "name": "setUserProperty", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 28, + "name": "setUserProperty", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Sets a key/value pair of data on the current user." + }, + "parameters": [ + { + "id": 29, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 30, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Set to null to remove a previously assigned id from analytics events.\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 95, + "character": 19 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 39 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 4, + 37, + 11, + 14, + 18, + 21, + 24, + 31, + 27 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 37, + "character": 25 + } + ], + "extendedTypes": [ + { + "type": "reference", + "name": "ReactNativeFirebaseModule" + } + ] + }, + { + "id": 2, + "name": "Statics", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 35, + "character": 26 + } + ] + } + ], + "groups": [ + { + "title": "Interfaces", + "kind": 256, + "children": [ + 3, + 2 + ] + } + ], + "sources": [ + { + "fileName": "analytics/lib/index.d.ts", + "line": 34, + "character": 26 + } + ] + }, + { + "id": 170, + "name": "App", + "kind": 2, + "kindString": "Module", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "firebase", + "text": "app\n" + } + ] + }, + "children": [ + { + "id": 171, + "name": "FirebaseApp", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 172, + "name": "name", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The name (identifier) for this App. '[DEFAULT]' is the default App." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 203, + "character": 17 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 173, + "name": "options", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The (read-only) configuration options from the app initialization." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 208, + "character": 20 + } + ], + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 174, + "name": "delete", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 175, + "name": "delete", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Make this app unusable and free up resources." + }, + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 213, + "character": 10 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 172, + 173 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 174 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 199, + "character": 30 + } + ] + }, + { + "id": 176, + "name": "ReactNativeFirebaseNamespace", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 188, + "name": "SDK_VERSION", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The current React Native Firebase version." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 254, + "character": 24 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 187, + "name": "apps", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "A (read-only) array of all the initialized Apps." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 249, + "character": 8 + } + ], + "type": { + "type": "array", + "elementType": { + "type": "reference", + "name": "FirebaseApp", + "id": 171 + } + } + }, + { + "id": 184, + "name": "app", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 185, + "name": "app", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Retrieve an instance of a FirebaseApp.", + "tags": [ + { + "tag": "example", + "text": "\n```js\nconst app = firebase.app('foo');\n```\n" + } + ] + }, + "parameters": [ + { + "id": 186, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional name of the app to return ('[DEFAULT]' if omitted)\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 171 + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 244, + "character": 7 + } + ] + }, + { + "id": 177, + "name": "initializeApp", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 178, + "name": "initializeApp", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Create (and initialize) a FirebaseApp." + }, + "parameters": [ + { + "id": 179, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Options to configure the services used in the App." + }, + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 180, + "name": "config", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional config for your firebase app\n" + }, + "type": { + "type": "reference", + "name": "FirebaseAppConfig", + "id": 126 + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 171 + } + }, + { + "id": 181, + "name": "initializeApp", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Create (and initialize) a FirebaseApp." + }, + "parameters": [ + { + "id": 182, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Options to configure the services used in the App." + }, + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 183, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional name of the app to initialize ('[DEFAULT]' if\nomitted)\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 171 + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 223, + "character": 17 + }, + { + "fileName": "app-types/index.d.ts", + "line": 232, + "character": 17 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 188, + 187 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 184, + 177 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 216, + "character": 47 + } + ] + } + ], + "groups": [ + { + "title": "Interfaces", + "kind": 256, + "children": [ + 171, + 176 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 198, + "character": 20 + } + ] + }, + { + "id": 59, + "name": "Functions", + "kind": 2, + "kindString": "Module", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The Cloud Functions for Firebase client SDKs let you call functions\ndirectly from a Firebase app. To call a function from your app in this way,\nwrite and deploy an HTTPS Callable function in Cloud Functions,\nand then add client logic to call the function from your app.", + "tags": [ + { + "tag": "firebase", + "text": "functions\n" + } + ] + }, + "children": [ + { + "id": 62, + "name": "HttpsCallable", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "An HttpsCallable is a reference to a \"callable\" http trigger in\nGoogle Cloud Functions." + }, + "signatures": [ + { + "id": 63, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "An HttpsCallable is a reference to a \"callable\" http trigger in\nGoogle Cloud Functions." + }, + "parameters": [ + { + "id": 64, + "name": "data", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "reference", + "name": "HttpsCallableResult", + "id": 60 + } + ] + } + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 101, + "character": 32 + } + ] + }, + { + "id": 60, + "name": "HttpsCallableResult", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "An HttpsCallableResult wraps a single result from a function call." + }, + "children": [ + { + "id": 61, + "name": "data", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 94, + "character": 17 + } + ], + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 61 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 93, + "character": 38 + } + ] + }, + { + "id": 65, + "name": "HttpsError", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 71, + "name": "Error", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 974, + "character": 19 + } + ], + "type": { + "type": "reference", + "name": "ErrorConstructor" + } + }, + { + "id": 66, + "name": "code", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "A standard error code that will be returned to the client. This also\ndetermines the HTTP status code of the response, as defined in code.proto." + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 110, + "character": 17 + } + ], + "type": { + "type": "reference", + "name": "FunctionsErrorCode", + "id": 100 + } + }, + { + "id": 67, + "name": "details", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "comment": { + "shortText": "Extra data to be converted to JSON and included in the error response." + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 114, + "character": 20 + } + ], + "type": { + "type": "intrinsic", + "name": "any" + } + }, + { + "id": 69, + "name": "message", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 964, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "name": "Error.message" + } + }, + { + "id": 68, + "name": "name", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 963, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "name": "Error.name" + } + }, + { + "id": 70, + "name": "stack", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 965, + "character": 9 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "overwrites": { + "type": "reference", + "name": "Error.stack" + }, + "inheritedFrom": { + "type": "reference", + "name": "Error.stack" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 71, + 66, + 67, + 69, + 68, + 70 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 105, + "character": 29 + } + ], + "extendedTypes": [ + { + "type": "reference", + "name": "Error" + } + ] + }, + { + "id": 72, + "name": "HttpsErrorCode", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 84, + "name": "ABORTED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 129, + "character": 11 + } + ], + "type": { + "type": "stringLiteral", + "value": "aborted" + } + }, + { + "id": 79, + "name": "ALREADY_EXISTS", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 124, + "character": 18 + } + ], + "type": { + "type": "stringLiteral", + "value": "already-exists" + } + }, + { + "id": 74, + "name": "CANCELLED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 119, + "character": 13 + } + ], + "type": { + "type": "stringLiteral", + "value": "cancelled" + } + }, + { + "id": 89, + "name": "DATA_LOSS", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 134, + "character": 13 + } + ], + "type": { + "type": "stringLiteral", + "value": "data-loss" + } + }, + { + "id": 77, + "name": "DEADLINE_EXCEEDED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 122, + "character": 21 + } + ], + "type": { + "type": "stringLiteral", + "value": "deadline-exceeded" + } + }, + { + "id": 83, + "name": "FAILED_PRECONDITION", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 128, + "character": 23 + } + ], + "type": { + "type": "stringLiteral", + "value": "failed-precondition" + } + }, + { + "id": 87, + "name": "INTERNAL", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 132, + "character": 12 + } + ], + "type": { + "type": "stringLiteral", + "value": "internal" + } + }, + { + "id": 76, + "name": "INVALID_ARGUMENT", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 121, + "character": 20 + } + ], + "type": { + "type": "stringLiteral", + "value": "invalid-argument" + } + }, + { + "id": 78, + "name": "NOT_FOUND", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 123, + "character": 13 + } + ], + "type": { + "type": "stringLiteral", + "value": "not-found" + } + }, + { + "id": 73, + "name": "OK", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 118, + "character": 6 + } + ], + "type": { + "type": "stringLiteral", + "value": "ok" + } + }, + { + "id": 85, + "name": "OUT_OF_RANGE", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 130, + "character": 16 + } + ], + "type": { + "type": "stringLiteral", + "value": "out-of-range" + } + }, + { + "id": 80, + "name": "PERMISSION_DENIED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 125, + "character": 21 + } + ], + "type": { + "type": "stringLiteral", + "value": "permission-denied" + } + }, + { + "id": 82, + "name": "RESOURCE_EXHAUSTED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 127, + "character": 22 + } + ], + "type": { + "type": "stringLiteral", + "value": "resource-exhausted" + } + }, + { + "id": 81, + "name": "UNAUTHENTICATED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 126, + "character": 19 + } + ], + "type": { + "type": "stringLiteral", + "value": "unauthenticated" + } + }, + { + "id": 88, + "name": "UNAVAILABLE", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 133, + "character": 15 + } + ], + "type": { + "type": "stringLiteral", + "value": "unavailable" + } + }, + { + "id": 86, + "name": "UNIMPLEMENTED", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 131, + "character": 17 + } + ], + "type": { + "type": "stringLiteral", + "value": "unimplemented" + } + }, + { + "id": 75, + "name": "UNKNOWN", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 120, + "character": 11 + } + ], + "type": { + "type": "stringLiteral", + "value": "unknown" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 84, + 79, + 74, + 89, + 77, + 83, + 87, + 76, + 78, + 73, + 85, + 80, + 82, + 81, + 88, + 86, + 75 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 117, + "character": 33 + } + ] + }, + { + "id": 92, + "name": "Module", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "firebase.functions().X" + }, + "children": [ + { + "id": 99, + "name": "app", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "analytics/node_modules/@react-native-firebase/app-types/index.d.ts", + "line": 191, + "character": 5 + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp" + }, + "inheritedFrom": { + "type": "reference", + "name": "ReactNativeFirebaseModule.app" + } + }, + { + "id": 93, + "name": "httpsCallable", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 94, + "name": "httpsCallable", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Gets an `HttpsCallable` instance that refers to the function with the given\nname.", + "returns": "The `HttpsCallable` instance.\n" + }, + "parameters": [ + { + "id": 95, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "The name of the https callable function." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "reference", + "name": "HttpsCallable", + "id": 62 + } + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 158, + "character": 17 + } + ] + }, + { + "id": 96, + "name": "useFunctionsEmulator", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 97, + "name": "useFunctionsEmulator", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Changes this instance to point to a Cloud Functions emulator running\nlocally.", + "text": "See https://firebase.google.com/docs/functions/local-emulator\n" + }, + "parameters": [ + { + "id": 98, + "name": "origin", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "the origin string of the local emulator started via firebase tools\n\"http://10.0.0.8:1337\".\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 169, + "character": 24 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 99 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 93, + 96 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 150, + "character": 25 + } + ], + "extendedTypes": [ + { + "type": "reference", + "name": "ReactNativeFirebaseModule" + } + ] + }, + { + "id": 90, + "name": "Statics", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "firebase.functions.X" + }, + "children": [ + { + "id": 91, + "name": "HttpsErrorCode", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Uppercase + underscored variables of @Functions.FunctionsErrorCode" + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 144, + "character": 18 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reference", + "name": "__type" + }, + { + "type": "reference", + "name": "HttpsErrorCode", + "id": 72 + } + ] + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 91 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 140, + "character": 26 + } + ] + }, + { + "id": 100, + "name": "FunctionsErrorCode", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The set of Firebase Functions status codes. The codes are the same at the\nones exposed by gRPC here:\nhttps://github.com/grpc/grpc/blob/master/doc/statuscodes.md", + "text": "Possible values:\n- 'cancelled': The operation was cancelled (typically by the caller).\n- 'unknown': Unknown error or an error from a different error domain.\n- 'invalid-argument': Client specified an invalid argument. Note that this\n differs from 'failed-precondition'. 'invalid-argument' indicates\n arguments that are problematic regardless of the state of the system\n (e.g. an invalid field name).\n- 'deadline-exceeded': Deadline expired before operation could complete.\n For operations that change the state of the system, this error may be\n returned even if the operation has completed successfully. For example,\n a successful response from a server could have been delayed long enough\n for the deadline to expire.\n- 'not-found': Some requested document was not found.\n- 'already-exists': Some document that we attempted to create already\n exists.\n- 'permission-denied': The caller does not have permission to execute the\n specified operation.\n- 'resource-exhausted': Some resource has been exhausted, perhaps a\n per-user quota, or perhaps the entire file system is out of space.\n- 'failed-precondition': Operation was rejected because the system is not\n in a state required for the operation's execution.\n- 'aborted': The operation was aborted, typically due to a concurrency\n issue like transaction aborts, etc.\n- 'out-of-range': Operation was attempted past the valid range.\n- 'unimplemented': Operation is not implemented or not supported/enabled.\n- 'internal': Internal errors. Means some invariants expected by\n underlying system has been broken. If you see one of these errors,\n something is very broken.\n- 'unavailable': The service is currently unavailable. This is most likely\n a transient condition and may be corrected by retrying with a backoff.\n- 'data-loss': Unrecoverable data loss or corruption.\n- 'unauthenticated': The request does not have valid authentication\n credentials for the operation.\n" + }, + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 71, + "character": 32 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "ok" + }, + { + "type": "stringLiteral", + "value": "cancelled" + }, + { + "type": "stringLiteral", + "value": "unknown" + }, + { + "type": "stringLiteral", + "value": "invalid-argument" + }, + { + "type": "stringLiteral", + "value": "deadline-exceeded" + }, + { + "type": "stringLiteral", + "value": "not-found" + }, + { + "type": "stringLiteral", + "value": "already-exists" + }, + { + "type": "stringLiteral", + "value": "permission-denied" + }, + { + "type": "stringLiteral", + "value": "resource-exhausted" + }, + { + "type": "stringLiteral", + "value": "failed-precondition" + }, + { + "type": "stringLiteral", + "value": "aborted" + }, + { + "type": "stringLiteral", + "value": "out-of-range" + }, + { + "type": "stringLiteral", + "value": "unimplemented" + }, + { + "type": "stringLiteral", + "value": "internal" + }, + { + "type": "stringLiteral", + "value": "unavailable" + }, + { + "type": "stringLiteral", + "value": "data-loss" + }, + { + "type": "stringLiteral", + "value": "unauthenticated" + } + ] + } + } + ], + "groups": [ + { + "title": "Interfaces", + "kind": 256, + "children": [ + 62, + 60, + 65, + 72, + 92, + 90 + ] + }, + { + "title": "Type aliases", + "kind": 4194304, + "children": [ + 100 + ] + } + ], + "sources": [ + { + "fileName": "functions/lib/index.d.ts", + "line": 31, + "character": 26 + } + ] + }, + { + "id": 130, + "name": "FirebaseApp", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 131, + "name": "name", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The name (identifier) for this App. '[DEFAULT]' is the default App." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 136, + "character": 15 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 132, + "name": "options", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The (read-only) configuration options from the app initialization." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 141, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 133, + "name": "delete", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 134, + "name": "delete", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Make this app unusable and free up resources." + }, + "type": { + "type": "reference", + "name": "Promise", + "typeArguments": [ + { + "type": "intrinsic", + "name": "void" + } + ] + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 146, + "character": 8 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 131, + 132 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 133 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 132, + "character": 28 + } + ] + }, + { + "id": 126, + "name": "FirebaseAppConfig", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 128, + "name": "automaticDataCollectionEnabled", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "comment": {}, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 123, + "character": 32 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + }, + { + "id": 129, + "name": "automaticResourceManagement", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "comment": { + "shortText": "If set to true it indicates that Firebase should close database connections\nautomatically when the app is in the background. Disabled by default." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 129, + "character": 29 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + }, + { + "id": 127, + "name": "name", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "comment": { + "shortText": "The Firebase App name, defaults to [DEFAULT] if none provided." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 118, + "character": 6 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 128, + 129, + 127 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 114, + "character": 34 + } + ] + }, + { + "id": 117, + "name": "NativeFirebaseError", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 125, + "name": "Error", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 974, + "character": 19 + } + ], + "type": { + "type": "reference", + "name": "ErrorConstructor" + } + }, + { + "id": 118, + "name": "code", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Firebase error code, e.g. `auth/invalid-email`" + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 24, + "character": 15 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 119, + "name": "message", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Firebase error message" + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 29, + "character": 18 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "overwrites": { + "type": "reference", + "name": "Error.message" + } + }, + { + "id": 123, + "name": "name", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 963, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "name": "Error.name" + } + }, + { + "id": 120, + "name": "namespace", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The firebase module namespace that this error originated from, e.g. 'analytics'" + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 34, + "character": 20 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 121, + "name": "nativeErrorCode", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The native sdks returned error code, different per platform" + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 39, + "character": 26 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "number" + } + ] + } + }, + { + "id": 122, + "name": "nativeErrorMessage", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The native sdks returned error message, different per platform" + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 44, + "character": 29 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 124, + "name": "stack", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "/Volumes/Projects/Projects/mono-react-native-firebase/node_modules/typescript/lib/lib.es5.d.ts", + "line": 965, + "character": 9 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "overwrites": { + "type": "reference", + "name": "Error.stack" + }, + "inheritedFrom": { + "type": "reference", + "name": "Error.stack" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 125, + 118, + 119, + 123, + 120, + 121, + 122, + 124 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 20, + "character": 36 + } + ], + "extendedTypes": [ + { + "type": "reference", + "name": "Error" + } + ] + }, + { + "id": 148, + "name": "ReactNativeFirebaseModule", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 149, + "name": "app", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 191, + "character": 5 + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 130 + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 149 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 190, + "character": 42 + } + ] + }, + { + "id": 135, + "name": "ReactNativeFirebaseNamespace", + "kind": 256, + "kindString": "Interface", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 147, + "name": "SDK_VERSION", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "The current React Native Firebase version." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 187, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 146, + "name": "apps", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "A (read-only) array of all the initialized Apps." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 182, + "character": 6 + } + ], + "type": { + "type": "array", + "elementType": { + "type": "reference", + "name": "FirebaseApp", + "id": 130 + } + } + }, + { + "id": 143, + "name": "app", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 144, + "name": "app", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Retrieve an instance of a FirebaseApp.", + "tags": [ + { + "tag": "example", + "text": "\n```js\nconst app = firebase.app('foo');\n```\n" + } + ] + }, + "parameters": [ + { + "id": 145, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional name of the app to return ('[DEFAULT]' if omitted)\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 130 + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 177, + "character": 5 + } + ] + }, + { + "id": 136, + "name": "initializeApp", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 137, + "name": "initializeApp", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Create (and initialize) a FirebaseApp." + }, + "parameters": [ + { + "id": 138, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Options to configure the services used in the App." + }, + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 139, + "name": "config", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional config for your firebase app\n" + }, + "type": { + "type": "reference", + "name": "FirebaseAppConfig", + "id": 126 + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 130 + } + }, + { + "id": 140, + "name": "initializeApp", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "comment": { + "shortText": "Create (and initialize) a FirebaseApp." + }, + "parameters": [ + { + "id": 141, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "comment": { + "text": "Options to configure the services used in the App." + }, + "type": { + "type": "reference", + "name": "FirebaseOptions", + "id": 156 + } + }, + { + "id": 142, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isOptional": true + }, + "comment": { + "text": "The optional name of the app to initialize ('[DEFAULT]' if\nomitted)\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "type": { + "type": "reference", + "name": "FirebaseApp", + "id": 130 + } + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 156, + "character": 15 + }, + { + "fileName": "app-types/index.d.ts", + "line": 165, + "character": 15 + } + ] + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 147, + 146 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 143, + 136 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 149, + "character": 45 + } + ] + }, + { + "id": 156, + "name": "FirebaseOptions", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 56, + "character": 27 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 157, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "indexSignature": [ + { + "id": 168, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": {}, + "parameters": [ + { + "id": 169, + "name": "name", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "children": [ + { + "id": 166, + "name": "androidClientId", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "iOS only - The Android client ID used in Google AppInvite when an iOS app has its Android version, for\nexample \"12345.apps.googleusercontent.com\"." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 105, + "character": 17 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 159, + "name": "apiKey", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "An API key used for authenticating requests from your app, e.g.\n\"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk\", used to identify your app to Google servers." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 66, + "character": 8 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 158, + "name": "appId", + "kind": 32, + "kindString": "Variable", + "flags": {}, + "comment": { + "shortText": "The Google App ID that is used to uniquely identify an instance of an app." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 60, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 165, + "name": "clientId", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "iOS only - The OAuth2 client ID for iOS application used to authenticate Google users, for example\n\"12345.apps.googleusercontent.com\", used for signing in with Google." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 99, + "character": 10 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 160, + "name": "databaseURL", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "The database root URL, e.g. \"http://abc-xyz-123.firebaseio.com\"." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 71, + "character": 13 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 167, + "name": "deepLinkURLScheme", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "iOS only - The URL scheme used to set up Durable Deep Link service." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 110, + "character": 19 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 162, + "name": "gaTrackingId", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "The tracking ID for Google Analytics, e.g. \"UA-12345678-1\", used to configure Google Analytics." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 81, + "character": 14 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 164, + "name": "messagingSenderId", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "The Project Number from the Google Developer's console, for example \"012345678901\", used to\nconfigure Google Cloud Messaging." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 93, + "character": 19 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 161, + "name": "projectId", + "kind": 32, + "kindString": "Variable", + "flags": {}, + "comment": { + "shortText": "The Project ID from the Firebase console, for example \"abc-xyz-123\"." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 76, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 163, + "name": "storageBucket", + "kind": 32, + "kindString": "Variable", + "flags": { + "isOptional": true + }, + "comment": { + "shortText": "The Google Cloud Storage bucket name, e.g. \"abc-xyz-123.storage.firebase.com\"." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 86, + "character": 15 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 166, + 159, + 158, + 165, + 160, + 167, + 162, + 164, + 161, + 163 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 56, + "character": 29 + } + ] + } + } + }, + { + "id": 150, + "name": "ReactNativeFirebaseModuleAndStatics", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 151, + "name": "M", + "kind": 131072, + "kindString": "Type parameter", + "flags": {} + }, + { + "id": 152, + "name": "S", + "kind": 131072, + "kindString": "Type parameter", + "flags": {} + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 47, + "character": 47 + } + ], + "type": { + "type": "intersection", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 153, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": {}, + "signatures": [ + { + "id": 154, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": {}, + "type": { + "type": "typeParameter", + "name": "M" + } + } + ], + "children": [ + { + "id": 155, + "name": "SDK_VERSION", + "kind": 32, + "kindString": "Variable", + "flags": {}, + "comment": { + "shortText": "This React Native Firebase module version." + }, + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 53, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [ + 155 + ] + } + ], + "sources": [ + { + "fileName": "app-types/index.d.ts", + "line": 47, + "character": 60 + } + ] + } + }, + { + "type": "typeParameter", + "name": "S" + } + ] + } + } + ], + "groups": [ + { + "title": "Modules", + "kind": 2, + "children": [ + 40, + 44, + 101, + 50, + 1, + 170, + 59 + ] + }, + { + "title": "Interfaces", + "kind": 256, + "children": [ + 130, + 126, + 117, + 148, + 135 + ] + }, + { + "title": "Type aliases", + "kind": 4194304, + "children": [ + 156, + 150 + ] + } + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e2128c4c..74aba806 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@babel/cli@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7" - integrity sha512-zbO/DtTnaDappBflIU3zYEgATLToRDmW5uN/EGH1GXaes7ydfjqmAoK++xmJIA+8HfDw7UyPZNdM8fhGhfmMhw== +"@babel/cli@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" + integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" @@ -26,18 +26,18 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" - integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== +"@babel/core@^7.0.0", "@babel/core@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" + integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" - "@babel/helpers" "^7.1.5" - "@babel/parser" "^7.1.6" - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.1.6" + "@babel/generator" "^7.2.2" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.2.2" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.2.2" + "@babel/types" "^7.2.2" convert-source-map "^1.1.0" debug "^4.1.0" json5 "^2.1.0" @@ -46,12 +46,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" - integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== +"@babel/generator@^7.0.0", "@babel/generator@^7.2.2": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.0.tgz#f663838cd7b542366de3aa608a657b8ccb2a99eb" + integrity sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg== dependencies: - "@babel/types" "^7.1.6" + "@babel/types" "^7.3.0" jsesc "^2.5.1" lodash "^4.17.10" source-map "^0.5.0" @@ -72,12 +72,12 @@ "@babel/helper-explode-assignable-expression" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-builder-react-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb" - integrity sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw== +"@babel/helper-builder-react-jsx@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" + integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.3.0" esutils "^2.0.0" "@babel/helper-call-delegate@^7.1.0": @@ -89,6 +89,17 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-create-class-features-plugin@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.0.tgz#2b01a81b3adc2b1287f9ee193688ef8dc71e718f" + integrity sha512-DUsQNS2CGLZZ7I3W3fvh0YpPDd6BuWJlDl+qmZZpABZHza2ErE3LxtEzLJFHFC1ZwtlAXvHhbFYbtM5o5B0WBw== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.2.3" + "@babel/helper-define-map@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" @@ -144,15 +155,15 @@ "@babel/types" "^7.0.0" "@babel/helper-module-transforms@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" - integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963" + integrity sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/template" "^7.2.2" + "@babel/types" "^7.2.2" lodash "^4.17.10" "@babel/helper-optimise-call-expression@^7.0.0": @@ -185,14 +196,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" - integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== +"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5" + integrity sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA== dependencies: "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.1.0" + "@babel/traverse" "^7.2.3" "@babel/types" "^7.0.0" "@babel/helper-simple-access@^7.1.0": @@ -211,23 +222,23 @@ "@babel/types" "^7.0.0" "@babel/helper-wrap-function@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" - integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/template" "^7.1.0" "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/types" "^7.2.0" -"@babel/helpers@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" - integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== +"@babel/helpers@^7.2.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" + integrity sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA== dependencies: "@babel/template" "^7.1.2" "@babel/traverse" "^7.1.5" - "@babel/types" "^7.1.5" + "@babel/types" "^7.3.0" "@babel/highlight@^7.0.0": version "7.0.0" @@ -238,175 +249,178 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" - integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.1.tgz#8f4ffd45f779e6132780835ffa7a215fa0b2d181" + integrity sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA== "@babel/plugin-external-helpers@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0.tgz#61ee7ba5dba27d7cad72a13d46bec23c060b762e" - integrity sha512-tZKTMdhZvTy0KCEX5EGQQm1RHr7jUa36q/yax1baEA0yZapVYmu10yW7LTqijITgSq416gPVjrcexiA6y4pJlA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz#7f4cb7dee651cd380d2034847d914288467a6be4" + integrity sha512-QFmtcCShFkyAsNtdCM3lJPmRe1iB+vPZymlB4LnDIKEBj2yKQLQKtoxXxJ8ePT5fwMl4QGg303p4mB0UsSI2/g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4" - integrity sha512-/PCJWN+CKt5v1xcGn4vnuu13QDoV+P7NcICP44BoonAJoPSGwVkgrXihFIQGiEjjPlUDBIw1cM7wYFLARS2/hw== + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.0.tgz#272636bc0fa19a0bc46e601ec78136a173ea36cd" + integrity sha512-wNHxLkEKTQ2ay0tnsam2z7fGZUi+05ziDJflEt3AZTP3oXLKHJp9HqhfroB/vdMvt3sda9fAbq7FsG8QPDrZBg== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-create-class-features-plugin" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.0.0.tgz#a057bbfd4649facfe39f33a537e18554bdd2b5da" - integrity sha512-cWhkx6SyjZ4caFOanoPmDNgQCuYYTmou4QXy886JsyLTw/vhWQbop2gLKsWyyswrJkKTB7fSNxVYbP/oEsoySA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.2.0.tgz#737b0da44b9254b6152fe29bb99c64e5691f6f68" + integrity sha512-NVfNe7F6nsasG1FnvcFxh2FN0l04ZNe75qTOAVOILWPam0tw9a63RtT/Dab8dPjedZa4fTQaQ83yMMywF9OSug== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-export-default-from" "^7.2.0" "@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.0.0.tgz#b72ec31adf612d062dc0348316246127a451e45f" - integrity sha512-QIN3UFo1ul4ruAsjIqK43PeXedo1qY74zeGrODJl1KfCGeMc6qJC4rb5Ylml/smzxibqsDeVZGH+TmWHCldRQQ== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.2.0.tgz#c3fda766187b2f2162657354407247a758ee9cf9" + integrity sha512-QXj/YjFuFJd68oDvoc1e8aqLr2wz7Kofzvp6Ekd/o7MWZl+nZ0/cpStxND+hlZ7DpRWAp7OmuyT2areZ2V3YUA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.1.tgz#f69fb6a1ea6a4e1c503994a91d9cf76f3c4b36e8" + integrity sha512-Nmmv1+3LqxJu/V5jU9vJmxR/KIRWFk2qLHmbB56yRRRFhlaSuOVXscX3gUmhaKgUhzA3otOHVubbIEVYsZ0eZg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.0.0.tgz#3d344d4152253379b8758e7d041148e8787c4a9d" - integrity sha512-7x8HLa71OzNiofbQUVakS0Kmg++6a+cXNfS7QKHbbv03SuSaumJyaWsfNgw+T7aqrJlqurYpZqrkPgXu0iZK0w== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.2.0.tgz#ae454f4c21c6c2ce8cb2397dc332ae8b420c5441" + integrity sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.2.0" "@babel/plugin-syntax-async-generators@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" - integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-class-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" - integrity sha512-cR12g0Qzn4sgkjrbrzWy2GE7m9vMl/sFkqZ3gIpAQdrvPDnLM8180i+ANDFIXfjHo9aqp0ccJlQ0QNZcFUbf9w== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz#23b3b7b9bcdabd73672a9149f728cd3be6214812" + integrity sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0.tgz#6dfb7d8b6c3be14ce952962f658f3b7eb54c33ee" - integrity sha512-Gt9xNyRrCHCiyX/ZxDGOcBnlJl0I3IWicpZRC4CdC0P5a/I07Ya2OAMEBU+J7GmRFVmIetqEYRko6QYRuKOESw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" + integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-export-default-from@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.0.0.tgz#084b639bce3d42f3c5bf3f68ccb42220bb2d729d" - integrity sha512-HNnjg/fFFbnuLAqr/Ocp1Y3GB4AjmXcu1xxn3ql3bS2kGrB/qi+Povshb8i3hOkE5jNozzh8r/0/lq1w8oOWbQ== +"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz#edd83b7adc2e0d059e2467ca96c650ab6d2f3820" + integrity sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17" - integrity sha512-zGcuZWiWWDa5qTZ6iAnpG0fnX/GOu49pGR5PFvkQ9GmKNaSphXQnlNXh/LG20sqWtNrx/eB6krzfEzcwvUyeFA== +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" + integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" - integrity sha512-PdmL2AoPsCLWxhIr3kG2+F9v4WH06Q3z+NoGVpQgnUNGcagXHq5sB3OXxkSahKq9TLdNMN/AJzFYSOo8UKDMHg== +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" + integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.0.0.tgz#b60931d5a15da82625fff6657c39419969598743" - integrity sha512-oAJmMsAvTSIk9y0sZdU2S/nY44PEUuHN7EzNDMgbuR4e/OwyfR9lSmoBJBZ2lslFZIqhksrTt4i+av7uKfNYDw== +"@babel/plugin-syntax-nullish-coalescing-operator@^7.0.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz#f75083dfd5ade73e783db729bbd87e7b9efb7624" + integrity sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== +"@babel/plugin-syntax-optional-catch-binding@^7.0.0", "@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-chaining@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.0.0.tgz#1e6ecba124310b5d3a8fc1e00d50b1c4c2e05e68" - integrity sha512-QXedQsZf8yua1nNrXSePT0TsGSQH9A1iK08m9dhCMdZeJaaxYcQfXdgHWVV6Cp7WE/afPVvSKIsAHK5wP+yxDA== +"@babel/plugin-syntax-optional-chaining@^7.0.0", "@babel/plugin-syntax-optional-chaining@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz#a59d6ae8c167e7608eaa443fda9fa8fa6bf21dff" + integrity sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-typescript@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.1.5.tgz#956a1f43dec8a9d6b36221f5c865335555fdcb98" - integrity sha512-VqK5DFcS6/T8mT5CcJv1BwZLYFxkHiGZmP7Hs87F53lSToE/qfL7TpPrqFSaKyZi9w7Z/b/tmOGZZDupcJjFvw== +"@babel/plugin-syntax-typescript@^7.0.0", "@babel/plugin-syntax-typescript@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.2.0.tgz#55d240536bd314dcbbec70fd949c5cabaed1de29" + integrity sha512-WhKr6yu6yGpGcNMVgIBuI9MkredpVc7Y3YR4UzEZmDztHoL6wV56YBHLhWnjO1EvId1B32HrD3DRFc+zSoKI1g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" + integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" - integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" "@babel/plugin-transform-classes@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953" + integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -418,113 +432,135 @@ globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" - integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-flow-comments@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-comments/-/plugin-transform-flow-comments-7.0.0.tgz#ad373ac02a6922edb0853a631f28e1c4b043de0b" - integrity sha512-Lv4LTUOV2/8Efb8fQeYt/EHxyCdW1/+ZhXckLFzBo/oegDo5Qpcy73SaAYkS95xPlk14F3AleeeQeaOLWwo8ww== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-comments/-/plugin-transform-flow-comments-7.2.0.tgz#472773f66c7c3994ad5e0f99850054a7500e2c68" + integrity sha512-o0EyefxfyCn9GhwvXMPP6P/DKmcHDwJ5UcUussaLUDSuPOU78YOUU76u/QIucOv/1wtMdLmepWZeYvnyoOSuyw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" "@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.1.6.tgz#4b7be62604d39e63cfe23b1d00d63e9fb7e763ba" - integrity sha512-0tyFAAjJmnRlr8MVJV39ASn1hv+PbdVP71hf7aAseqLfQ0o9QXk9htbMbq7/ZYXnUIp6gDw0lUUP0+PQMbbtmg== + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.2.3.tgz#e3ac2a594948454e7431c7db33e1d02d51b5cd69" + integrity sha512-xnt7UIk9GYZRitqCnsVMjQK1O2eKZwFB3CvvHjf5SGx6K6vr/MScCKQDnf1DxRaj501e3pXjti+inbSXX2ZUoQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" "@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-function-name@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-member-expression-literals@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" + integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/plugin-transform-object-assign@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0.tgz#fca6d7500d9675c42868b8f3882979201b9a5ad8" - integrity sha512-Dag8mxx7/03oj8F8PkNso8GEMhwGfeT0TL6KfMsa9Brjx4IpwZVl3WBvEmYks8BMhPmrvM5NQ/tjaMbwEj5ijA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz#6fdeea42be17040f119e38e23ea0f49f31968bde" + integrity sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng== dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-object-super@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + "@babel/plugin-transform-parameters@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-property-literals@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" + integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-display-name@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0.tgz#93759e6c023782e52c2da3b75eca60d4f10533ee" - integrity sha512-BX8xKuQTO0HzINxT6j/GiCwoJB0AOMs0HmLbEnAvcte8U8rSkNa/eSCAY+l1OA4JnCVq2jw2p6U8QQryy2fTPg== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" + integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0.tgz#28e00584f9598c0dd279f6280eee213fa0121c3c" - integrity sha512-OSeEpFJEH5dw/TtxTg4nijl4nHBbhqbKL94Xo/Y17WKIf2qJWeIk/QeXACF19lG1vMezkxqruwnTjVizaW7u7w== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f" + integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.1.6.tgz#e6188e7d2a2dcd2796d45a87f8b0a8c906f57d1a" - integrity sha512-iU/IUlPEYDRwuqLwqVobzPAZkBOQoZ9xRTBmj6ANuk5g/Egn/zdNGnXlSoKeNmKoYVeIRxx5GZhWmMhLik8dag== + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" + integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== dependencies: - "@babel/helper-builder-react-jsx" "^7.0.0" + "@babel/helper-builder-react-jsx" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-regenerator@^7.0.0": version "7.0.0" @@ -533,48 +569,58 @@ dependencies: regenerator-transform "^0.13.3" +"@babel/plugin-transform-runtime@^7.0.0", "@babel/plugin-transform-runtime@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.2.0.tgz#566bc43f7d0aedc880eaddbd29168d0f248966ea" + integrity sha512-jIgkljDdq4RYDnJyQsiWbdvGeei/0MOTtSHKO/rfbd/mXBxNpdlulMx49L0HQ4pug1fXannxoqCI+fYSle9eSw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" "@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript@^7.0.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.1.0.tgz#81e7b4be90e7317cbd04bf1163ebf06b2adee60b" - integrity sha512-TOTtVeT+fekAesiCHnPz+PSkYSdOSLyLn42DI45nxg6iCdlQY6LIj/tYqpMB0y+YicoTUiYiXqF8rG6SKfhw6Q== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.2.0.tgz#bce7c06300434de6a860ae8acf6a442ef74a99d1" + integrity sha512-EnI7i2/gJ7ZNr2MuyvN2Hu+BHJENlxWte5XygPvfj/MbvtOkWor9zcnHpMMQL2YYaaCcqtIvJUyJ7QVfoGs7ew== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.0.0" + "@babel/plugin-syntax-typescript" "^7.2.0" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" @@ -593,46 +639,79 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" - integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.2.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a" + integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA== dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.1.2" - "@babel/types" "^7.1.2" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" - integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.6" + "@babel/generator" "^7.2.2" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.1.6" - "@babel/types" "^7.1.6" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.10" -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" - integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.0.tgz#61dc0b336a93badc02bf5f69c4cd8e1353f2ffc0" + integrity sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw== dependencies: esutils "^2.0.2" lodash "^4.17.10" to-fast-properties "^2.0.0" +"@fimbul/bifrost@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.17.0.tgz#f0383ba7e40992e3193dc87e2ddfde2ad62a9cf4" + integrity sha512-gVTkJAOef5HtN6LPmrtt5fAUmBywwlgmObsU3FBhPoNeXPLaIl2zywXkJEtvvVLQnaFmtff3x+wIj5lHRCDE3Q== + dependencies: + "@fimbul/ymir" "^0.17.0" + get-caller-file "^2.0.0" + tslib "^1.8.1" + tsutils "^3.5.0" + +"@fimbul/ymir@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@fimbul/ymir/-/ymir-0.17.0.tgz#4f28389b9f804d1cd202e11983af1743488b7815" + integrity sha512-xMXM9KTXRLHLVS6dnX1JhHNEkmWHcAVCQ/4+DA1KKwC/AFnGHzu/7QfQttEPgw3xplT+ILf9e3i64jrFwB3JtA== + dependencies: + inversify "^5.0.0" + reflect-metadata "^0.1.12" + tslib "^1.8.1" + +"@iamstarkov/listr-update-renderer@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e" + integrity sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + "@invertase/babel-preset-react-native-syntax@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@invertase/babel-preset-react-native-syntax/-/babel-preset-react-native-syntax-0.1.3.tgz#23e6f2d5feef0decaf9ff76c8c83f9a06d79441b" @@ -650,6 +729,616 @@ "@babel/plugin-transform-flow-comments" "^7.0.0" "@babel/plugin-transform-flow-strip-types" "^7.0.0" +"@lerna/add@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.10.6.tgz#6f2c6b26eb905c40fef4180f3ffa34ad9dbb860b" + integrity sha512-FxQ5Bmyb5fF+3BQiNffM6cTeGCrl4uaAuGvxFIWF6Pgz6U14tUc1e16xgKDvVb1CurzJgIV5sLOT5xmCOqv1kA== + dependencies: + "@lerna/bootstrap" "3.10.6" + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/npm-conf" "3.7.0" + "@lerna/validation-error" "3.6.0" + dedent "^0.7.0" + libnpm "^2.0.1" + p-map "^1.2.0" + semver "^5.5.0" + +"@lerna/batch-packages@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/batch-packages/-/batch-packages-3.10.6.tgz#2d6dfc9be13ea4da49244dd84bfcd46c3d62f4d0" + integrity sha512-sInr3ZQJFMh9Zq+ZUoVjX8R67j9ViRkVy0uEMsOfG+jZlXj1lRPRMPRiRgU0jXSYEwCdwuAB5pTd9tTx0VCJUw== + dependencies: + "@lerna/package-graph" "3.10.6" + "@lerna/validation-error" "3.6.0" + libnpm "^2.0.1" + +"@lerna/bootstrap@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.10.6.tgz#d250baa9cfe9026c4f78e6cf7c9761a90b24e363" + integrity sha512-qbGjAxRpV/eiI9CboUIpsPPGpSogs8mN2/iDaAUBTaWVFVz/YyU64nui84Gll0kbdaHOyPput+kk2S8NCSCCdg== + dependencies: + "@lerna/batch-packages" "3.10.6" + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/has-npm-version" "3.10.0" + "@lerna/npm-install" "3.10.0" + "@lerna/package-graph" "3.10.6" + "@lerna/pulse-till-done" "3.7.1" + "@lerna/rimraf-dir" "3.10.0" + "@lerna/run-lifecycle" "3.10.5" + "@lerna/run-parallel-batches" "3.0.0" + "@lerna/symlink-binary" "3.10.0" + "@lerna/symlink-dependencies" "3.10.0" + "@lerna/validation-error" "3.6.0" + dedent "^0.7.0" + get-port "^3.2.0" + libnpm "^2.0.1" + multimatch "^2.1.0" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + read-package-tree "^5.1.6" + semver "^5.5.0" + +"@lerna/changed@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.10.6.tgz#48fed2e6c890b39a71f1dac29e42a6f853956d71" + integrity sha512-nZDVq/sKdhgoAg1BVnpqjqUUz5+zedG+AnU+6mjEN2f23YVtRCsW55N4I9eEdW2pxXUaCY85Hj/HPSA74BYaFg== + dependencies: + "@lerna/collect-updates" "3.10.1" + "@lerna/command" "3.10.6" + "@lerna/listable" "3.10.6" + "@lerna/output" "3.6.0" + "@lerna/version" "3.10.6" + +"@lerna/check-working-tree@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.10.0.tgz#5ed9f2c5c942bee92afcd8cb5361be44ed0251e3" + integrity sha512-NdIPhDgEtGHfeGjB9F0oAoPLywgMpjnJhLLwTNQkelDHo2xNAVpG8kV+A2UJ+cU5UXCZA4RZFxKNmw86rO+Drw== + dependencies: + "@lerna/describe-ref" "3.10.0" + "@lerna/validation-error" "3.6.0" + +"@lerna/child-process@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.3.0.tgz#71184a763105b6c8ece27f43f166498d90fe680f" + integrity sha512-q2d/OPlNX/cBXB6Iz1932RFzOmOHq6ZzPjqebkINNaTojHWuuRpvJJY4Uz3NGpJ3kEtPDvBemkZqUBTSO5wb1g== + dependencies: + chalk "^2.3.1" + execa "^1.0.0" + strong-log-transformer "^2.0.0" + +"@lerna/clean@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.10.6.tgz#31e4a12a722e57ca7adc0c9bc30ba70d55572bb8" + integrity sha512-MuL8HOwnyvVtr6GOiAN/Ofjbx+BJdCrtjrM1Uuh8FFnbnZTPVf+0MPxL2jVzPMo0PmoIrX3fvlwvzKNk/lH0Ug== + dependencies: + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/prompt" "3.6.0" + "@lerna/pulse-till-done" "3.7.1" + "@lerna/rimraf-dir" "3.10.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + +"@lerna/cli@3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.10.7.tgz#2f88ae4a3c53fa4d3a4f61b5f447bbbcc69546e2" + integrity sha512-yuoz/24mIfYit3neKqoE5NVs42Rj9A6A6SlkNPDfsy3v/Vh7SgYkU3cwiGyvwBGzIdhqL4/SWYo8H7YJLs0C+g== + dependencies: + "@lerna/global-options" "3.10.6" + dedent "^0.7.0" + libnpm "^2.0.1" + yargs "^12.0.1" + +"@lerna/collect-updates@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.10.1.tgz#3ad60aa31826c0c0cfdf8bf41e58e6c5c86aeb3a" + integrity sha512-vb0wEJ8k63G+2CR/ud1WeVHNJ21Fs6Ew6lbdGZXnF4ZvaFWxWJZpoHeWwzjhMdJ75QdTzUaIhTG1hnH9faQNMw== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/describe-ref" "3.10.0" + libnpm "^2.0.1" + minimatch "^3.0.4" + slash "^1.0.0" + +"@lerna/command@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.10.6.tgz#709bd1c66220da67f65dbe1fc88bb7ba5bb85446" + integrity sha512-jPZswMZXOpAaIuSF5hrz+eaWQzbDrvwbrkCoRJKfiAHx7URAkE6MQe9DeAnqrTKMqwfg0RciSrZLc8kWYfrzCQ== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/package-graph" "3.10.6" + "@lerna/project" "3.10.0" + "@lerna/validation-error" "3.6.0" + "@lerna/write-log-file" "3.6.0" + dedent "^0.7.0" + execa "^1.0.0" + is-ci "^1.0.10" + libnpm "^2.0.1" + lodash "^4.17.5" + +"@lerna/conventional-commits@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.10.0.tgz#284cc16bd3c387f841ff6bec42bcadaa2d13d8e4" + integrity sha512-8FvO0eR8g/tEgkb6eRVYaD39TsqMKsOXp17EV48jciciEqcrF/d1Ypu6ilK1GDp6R/1m2mbjt/b52a/qrO+xaw== + dependencies: + "@lerna/validation-error" "3.6.0" + conventional-changelog-angular "^5.0.2" + conventional-changelog-core "^3.1.5" + conventional-recommended-bump "^4.0.4" + fs-extra "^7.0.0" + get-stream "^4.0.0" + libnpm "^2.0.1" + semver "^5.5.0" + +"@lerna/create-symlink@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.6.0.tgz#f1815cde2fc9d8d2315dfea44ee880f2f1bc65f1" + integrity sha512-YG3lTb6zylvmGqKU+QYA3ylSnoLn+FyLH5XZmUsD0i85R884+EyJJeHx/zUk+yrL2ZwHS4RBUgJfC24fqzgPoA== + dependencies: + cmd-shim "^2.0.2" + fs-extra "^7.0.0" + libnpm "^2.0.1" + +"@lerna/create@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.10.6.tgz#85c7398cad912516c0ac6054a5c0c4145ab6cadb" + integrity sha512-OddQtGBHM2/eJONggLWoTE6275XGbnJ6dIVF+fLsKS93o4GC6g+qcc6Y7lUWHm5bfpeOwNOVKwj0tvqBZ6MgoA== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/command" "3.10.6" + "@lerna/npm-conf" "3.7.0" + "@lerna/validation-error" "3.6.0" + camelcase "^4.1.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + globby "^8.0.1" + init-package-json "^1.10.3" + libnpm "^2.0.1" + p-reduce "^1.0.0" + pify "^3.0.0" + semver "^5.5.0" + slash "^1.0.0" + validate-npm-package-license "^3.0.3" + validate-npm-package-name "^3.0.0" + whatwg-url "^7.0.0" + +"@lerna/describe-ref@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.10.0.tgz#266380feece6013ab9674f52bd35bf0be5b0460d" + integrity sha512-fouh3FQS07QxJJp/mW8LkGnH0xMRAzpBlejtZaiRwfDkW2kd6EuHaj8I/2/p21Wsprcvuu4dqmyia2YS1xFb/w== + dependencies: + "@lerna/child-process" "3.3.0" + libnpm "^2.0.1" + +"@lerna/diff@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.10.6.tgz#b4c5a50d8c7e79619376e2c913ec1c627dfd0cdf" + integrity sha512-0MqFhosjrqsIdXiKIu7t3CiJELqiU9mkjFBhYPB7JruAzpPwjMXJnC6/Ur5/7LXJYYVpqGQwZI9ZaZlOYJhhrw== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/command" "3.10.6" + "@lerna/validation-error" "3.6.0" + libnpm "^2.0.1" + +"@lerna/exec@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.10.6.tgz#5564b614b7e39c1f034f5e0736c9e020945f2f12" + integrity sha512-cdHqaRBMYceJu8rZLO8b4ZeR27O+xKPHgzi13OOOfBJQjrTuacjMWyHgmpy8jWc/0f7QnTl4VsHks7VJ3UK+vw== + dependencies: + "@lerna/batch-packages" "3.10.6" + "@lerna/child-process" "3.3.0" + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/run-parallel-batches" "3.0.0" + "@lerna/validation-error" "3.6.0" + +"@lerna/filter-options@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.10.6.tgz#e05a8b8de6efc16c47c83f0ac58291008efba4b8" + integrity sha512-r/dQbqN+RGFKZNn+DyWehswFmAkny/fkdMB2sRM2YVe7zRTtSl95YxD9DtdYnpJTG/jbOVICS/L5QJakrI6SSw== + dependencies: + "@lerna/collect-updates" "3.10.1" + "@lerna/filter-packages" "3.10.0" + dedent "^0.7.0" + +"@lerna/filter-packages@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.10.0.tgz#75f9a08184fc4046da2057e0218253cd6f493f05" + integrity sha512-3Acdj+jbany6LnQSuImU4ttcK5ULHSVug8Gh/EvwTewKCDpHAuoI3eyuzZOnSBdMvDOjE03uIESQK0dNNsn6Ow== + dependencies: + "@lerna/validation-error" "3.6.0" + libnpm "^2.0.1" + multimatch "^2.1.0" + +"@lerna/get-npm-exec-opts@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.6.0.tgz#ea595eb28d1f34ba61a92ee8391f374282b4b76e" + integrity sha512-ruH6KuLlt75aCObXfUIdVJqmfVq7sgWGq5mXa05vc1MEqxTIiU23YiJdWzofQOOUOACaZkzZ4K4Nu7wXEg4Xgg== + dependencies: + libnpm "^2.0.1" + +"@lerna/get-packed@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-3.7.0.tgz#549c7738f7be5e3b1433e82ed9cda9123bcd1ed5" + integrity sha512-yuFtjsUZIHjeIvIYQ/QuytC+FQcHwo3peB+yGBST2uWCLUCR5rx6knoQcPzbxdFDCuUb5IFccFGd3B1fHFg3RQ== + dependencies: + fs-extra "^7.0.0" + ssri "^6.0.1" + tar "^4.4.8" + +"@lerna/global-options@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.10.6.tgz#c491a64b0be47eca4ffc875011958a5ee70a9a3e" + integrity sha512-k5Xkq1M/uREFC2R9uwN5gcvIgjj4iOXo0YyeEXCMWBiW3j2GL9xN4d1MmAIcrYlAzVYh6kLlWaFWl/rNIneHIw== + +"@lerna/has-npm-version@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.10.0.tgz#d3a73c0fedd2f2e9c6fbe166c41809131dc939d2" + integrity sha512-N4RRYxGeivuaKgPDzrhkQOQs1Sg4tOnxnEe3akfqu1wDA4Ng5V6Y2uW3DbkAjFL3aNJhWF5Vbf7sBsGtfgDQ8w== + dependencies: + "@lerna/child-process" "3.3.0" + semver "^5.5.0" + +"@lerna/import@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.10.6.tgz#36b65854857e8ab5dfd98a1caea4d365ecc06578" + integrity sha512-LlGxhfDhovoNoBJLF3PYd3j/G2GFTnfLh0V38+hBQ6lomMNJbjkACfiLVomQxPWWpYLk0GTlpWYR8YGv6L7Ifw== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/command" "3.10.6" + "@lerna/prompt" "3.6.0" + "@lerna/pulse-till-done" "3.7.1" + "@lerna/validation-error" "3.6.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + p-map-series "^1.0.0" + +"@lerna/init@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.10.6.tgz#b5c5166b2ddf00ea0f2742a1f53f59221478cf9a" + integrity sha512-RIlEx+ofWLYRNjxCkkV3G0XQPM+/KA5RXRDb5wKQLYO1f+tZAaHoUh8fHDIvxGf/ohY/OIjYYGSsU+ysimfwiQ== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/command" "3.10.6" + fs-extra "^7.0.0" + p-map "^1.2.0" + write-json-file "^2.3.0" + +"@lerna/link@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.10.6.tgz#4201cabbfc27bebaf1a400f8cfbd238f285dd3c7" + integrity sha512-dwD6qftRWitgLDYbqtDrgO7c8uF5C0fHVew5M6gU5m9tBJidqd7cDwHv/bXboLEI63U7tt5y6LY+wEpYUFsBRw== + dependencies: + "@lerna/command" "3.10.6" + "@lerna/package-graph" "3.10.6" + "@lerna/symlink-dependencies" "3.10.0" + p-map "^1.2.0" + slash "^1.0.0" + +"@lerna/list@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.10.6.tgz#7c43c09301ea01528f4dab3b22666f021e8ba9a5" + integrity sha512-3ElQBj2dOB4uUkpsjC1bxdeZwEzRBuV1pBBs5E1LncwsZf7D9D99Z32fuZsDaCHpEMgHAD4/j8juI3/7m5dkaQ== + dependencies: + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/listable" "3.10.6" + "@lerna/output" "3.6.0" + +"@lerna/listable@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.10.6.tgz#cea92de89d9f293c6d63e00be662bed03f85c496" + integrity sha512-F7ZuvesSgeuMiJf99eOum5p1MQGQStykcmHH1ek+LQRMiGGF1o3PkBxPvHTZBADGOFarek8bFA5TVmRAMX7NIw== + dependencies: + "@lerna/batch-packages" "3.10.6" + chalk "^2.3.1" + columnify "^1.5.4" + +"@lerna/log-packed@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.6.0.tgz#bed96c2bdd47f076d9957d0c6069b2edc1518145" + integrity sha512-T/J41zMkzpWB5nbiTRS5PmYTFn74mJXe6RQA2qhkdLi0UqnTp97Pux1loz3jsJf2yJtiQUnyMM7KuKIAge0Vlw== + dependencies: + byte-size "^4.0.3" + columnify "^1.5.4" + has-unicode "^2.0.1" + libnpm "^2.0.1" + +"@lerna/npm-conf@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.7.0.tgz#f101d4fdf07cefcf1161bcfaf3c0f105b420a450" + integrity sha512-+WSMDfPKcKzMfqq283ydz9RRpOU6p9wfx0wy4hVSUY/6YUpsyuk8SShjcRtY8zTM5AOrxvFBuuV90H4YpZ5+Ng== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +"@lerna/npm-dist-tag@3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.8.5.tgz#5ce22a72576badc8cb6baf85550043d63e66ea44" + integrity sha512-VO57yKTB4NC2LZuTd4w0LmlRpoFm/gejQ1gqqLGzSJuSZaBXmieElFovzl21S07cqiy7FNVdz75x7/a6WCZ6XA== + dependencies: + figgy-pudding "^3.5.1" + libnpm "^2.0.1" + +"@lerna/npm-install@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.10.0.tgz#fcd6688a3a2cd0e702a03c54c22eb7ae8b3dacb0" + integrity sha512-/6/XyLY9/4jaMPBOVYUr4wZxQURIfwoELY0qCQ8gZ5zv4cOiFiiCUxZ0i4fxqFtD7nJ084zq1DsZW0aH0CIWYw== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/get-npm-exec-opts" "3.6.0" + fs-extra "^7.0.0" + libnpm "^2.0.1" + signal-exit "^3.0.2" + write-pkg "^3.1.0" + +"@lerna/npm-publish@3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.10.7.tgz#9326b747b905a7f0e69d4be3f557859c3e359649" + integrity sha512-oU3/Q+eHC1fRjh7bk6Nn4tRD1OLR6XZVs3v+UWMWMrF4hVSV61pxcP5tpeI1n4gDQjSgh7seI4EzKVJe/WfraA== + dependencies: + "@lerna/run-lifecycle" "3.10.5" + figgy-pudding "^3.5.1" + fs-extra "^7.0.0" + libnpm "^2.0.1" + +"@lerna/npm-run-script@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.10.0.tgz#49a9204eddea136da15a8d8d9eba2c3175b77ddd" + integrity sha512-c21tBXLF1Wje4tx/Td9jKIMrlZo/8QQiyyadjdKpwyyo7orSMsVNXGyJwvZ4JVVDcwC3GPU6HQvkt63v7rcyaw== + dependencies: + "@lerna/child-process" "3.3.0" + "@lerna/get-npm-exec-opts" "3.6.0" + libnpm "^2.0.1" + +"@lerna/output@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-3.6.0.tgz#a69384bc685cf3b21aa1bfc697eb2b9db3333d0b" + integrity sha512-9sjQouf6p7VQtVCRnzoTGlZyURd48i3ha3WBHC/UBJnHZFuXMqWVPKNuvnMf2kRXDyoQD+2mNywpmEJg5jOnRg== + dependencies: + libnpm "^2.0.1" + +"@lerna/pack-directory@3.10.5": + version "3.10.5" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-3.10.5.tgz#9bdabceacb74e1f54e47bae925e193978f2aae51" + integrity sha512-Ulj24L9XdgjJIxBr6ZjRJEoBULVH3c10lqunUdW41bswXhzhirRtQIxv0+5shngNjDwgMmJfOBcuCVKPSez4tg== + dependencies: + "@lerna/get-packed" "3.7.0" + "@lerna/package" "3.7.2" + "@lerna/run-lifecycle" "3.10.5" + figgy-pudding "^3.5.1" + libnpm "^2.0.1" + npm-packlist "^1.1.12" + tar "^4.4.8" + temp-write "^3.4.0" + +"@lerna/package-graph@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.10.6.tgz#8940d1ed7003100117cb1b618f7690585c00db81" + integrity sha512-mpIOJbhi+xLqT9BcUrLVD4We8WUdousQf/QndbEWl8DWAW1ethtRHVsCm9ufdBB3F9nj4PH/hqnDWWwqE+rS4w== + dependencies: + "@lerna/validation-error" "3.6.0" + libnpm "^2.0.1" + semver "^5.5.0" + +"@lerna/package@3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.7.2.tgz#03c69fd7fb965c372c8c969165a2f7d6dfe2dfcb" + integrity sha512-8A5hN2CekM1a0Ix4VUO/g+REo+MsnXb8lnQ0bGjr1YGWzSL5NxYJ0Z9+0pwTfDpvRDYlFYO0rMVwBUW44b4dUw== + dependencies: + libnpm "^2.0.1" + load-json-file "^4.0.0" + write-pkg "^3.1.0" + +"@lerna/project@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.10.0.tgz#98272bf2eb93e9b21850edae568d696bf7fdebda" + integrity sha512-9QRl8aGHuyU4zVEELQmNPnJTlS7XHqX7w9I9isCXdnilKc2R0MyvUs21lj6Yyt6xTuQnqD158TR9tbS4QufYQQ== + dependencies: + "@lerna/package" "3.7.2" + "@lerna/validation-error" "3.6.0" + cosmiconfig "^5.0.2" + dedent "^0.7.0" + dot-prop "^4.2.0" + glob-parent "^3.1.0" + globby "^8.0.1" + libnpm "^2.0.1" + load-json-file "^4.0.0" + p-map "^1.2.0" + resolve-from "^4.0.0" + write-json-file "^2.3.0" + +"@lerna/prompt@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.6.0.tgz#b17cc464dec9d830619723e879dc747367378217" + integrity sha512-nyAjPMolJ/ZRAAVcXrUH89C4n1SiWvLh4xWNvWYKLcf3PI5yges35sDFP/HYrM4+cEbkNFuJCRq6CxaET4PRsg== + dependencies: + inquirer "^6.2.0" + libnpm "^2.0.1" + +"@lerna/publish@3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.10.7.tgz#8c5a3268398152e1f7993ff7bb6722a0363797af" + integrity sha512-Qd8pml2l9s6GIvNX1pTnia+Ddjsm9LF3pRRoOQeugAdv2IJNf45c/83AAEyE9M2ShG5VjgxEITNW4Lg49zipjQ== + dependencies: + "@lerna/batch-packages" "3.10.6" + "@lerna/check-working-tree" "3.10.0" + "@lerna/child-process" "3.3.0" + "@lerna/collect-updates" "3.10.1" + "@lerna/command" "3.10.6" + "@lerna/describe-ref" "3.10.0" + "@lerna/log-packed" "3.6.0" + "@lerna/npm-conf" "3.7.0" + "@lerna/npm-dist-tag" "3.8.5" + "@lerna/npm-publish" "3.10.7" + "@lerna/output" "3.6.0" + "@lerna/pack-directory" "3.10.5" + "@lerna/prompt" "3.6.0" + "@lerna/pulse-till-done" "3.7.1" + "@lerna/run-lifecycle" "3.10.5" + "@lerna/run-parallel-batches" "3.0.0" + "@lerna/validation-error" "3.6.0" + "@lerna/version" "3.10.6" + figgy-pudding "^3.5.1" + fs-extra "^7.0.0" + libnpm "^2.0.1" + p-finally "^1.0.0" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + semver "^5.5.0" + +"@lerna/pulse-till-done@3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-3.7.1.tgz#a9e55380fa18f6896a3e5b23621a4227adfb8f85" + integrity sha512-MzpesZeW3Mc+CiAq4zUt9qTXI9uEBBKrubYHE36voQTSkHvu/Rox6YOvfUr+U7P6k8frFPeCgGpfMDTLhiqe6w== + dependencies: + libnpm "^2.0.1" + +"@lerna/resolve-symlink@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.6.0.tgz#985344796b704ff32afa923901e795e80741b86e" + integrity sha512-TVOAEqHJSQVhNDMFCwEUZPaOETqHDQV1TQWQfC8ZlOqyaUQ7veZUbg0yfG7RPNzlSpvF0ZaGFeR0YhYDAW03GA== + dependencies: + fs-extra "^7.0.0" + libnpm "^2.0.1" + read-cmd-shim "^1.0.1" + +"@lerna/rimraf-dir@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.10.0.tgz#2d9435054ab7bbc5519db0a2654c5d8cacd27f98" + integrity sha512-RSKSfxPURc58ERCD/PuzorR86lWEvIWNclXYGvIYM76yNGrWiDF44pGHQvB4J+Lxa5M+52ZtZC/eOC7A7YCH4g== + dependencies: + "@lerna/child-process" "3.3.0" + libnpm "^2.0.1" + path-exists "^3.0.0" + rimraf "^2.6.2" + +"@lerna/run-lifecycle@3.10.5": + version "3.10.5" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.10.5.tgz#ea4422bb70c0f8d4382ecb2a626c8ba0ca88550b" + integrity sha512-YPmXviaxVlhcKM6IkDTIpTq24mxOuMCilo+MTr1RLoafgB9ZTmP2AHRiFt/sy14wOsq2Zqr0wJyj8KFlDYLTkA== + dependencies: + "@lerna/npm-conf" "3.7.0" + figgy-pudding "^3.5.1" + libnpm "^2.0.1" + +"@lerna/run-parallel-batches@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/run-parallel-batches/-/run-parallel-batches-3.0.0.tgz#468704934084c74991d3124d80607857d4dfa840" + integrity sha512-Mj1ravlXF7AkkewKd9YFq9BtVrsStNrvVLedD/b2wIVbNqcxp8lS68vehXVOzoL/VWNEDotvqCQtyDBilCodGw== + dependencies: + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/run@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.10.6.tgz#4c159a719b0ec010409dfe8f9535c9a3c3f3e06a" + integrity sha512-KS2lWbu/8WUUscQPi9U8sPO6yYpzf/0GmODjpruR1nRi1u/tuncdjTiG+hjGAeFC1BD7YktT9Za6imIpE8RXmA== + dependencies: + "@lerna/batch-packages" "3.10.6" + "@lerna/command" "3.10.6" + "@lerna/filter-options" "3.10.6" + "@lerna/npm-run-script" "3.10.0" + "@lerna/output" "3.6.0" + "@lerna/run-parallel-batches" "3.0.0" + "@lerna/timer" "3.5.0" + "@lerna/validation-error" "3.6.0" + p-map "^1.2.0" + +"@lerna/symlink-binary@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.10.0.tgz#5acdde86dfd50c9270d7d2a93bade203cff41b3d" + integrity sha512-6mQsG+iVjBo8cD8s24O+YgFrwDyUGfUQbK4ryalAXFHI817Zd4xlI3tjg3W99whCt6rt6D0s1fpf8eslMN6dSw== + dependencies: + "@lerna/create-symlink" "3.6.0" + "@lerna/package" "3.7.2" + fs-extra "^7.0.0" + p-map "^1.2.0" + +"@lerna/symlink-dependencies@3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.10.0.tgz#a20226e8e97af6a6bc4b416bfc28c0c5e3ba9ddd" + integrity sha512-vGpg5ydwGgQCuWNX5y7CRL38mGpuLhf1GRq9wMm7IGwnctEsdSNqvvE+LDgqtwEZASu5+vffYUkL0VlFXl8uWA== + dependencies: + "@lerna/create-symlink" "3.6.0" + "@lerna/resolve-symlink" "3.6.0" + "@lerna/symlink-binary" "3.10.0" + fs-extra "^7.0.0" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/timer@3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-3.5.0.tgz#8dee6acf002c55de64678c66ef37ca52143f1b9b" + integrity sha512-TAb99hqQN6E3JBGtG9iyZNPq1/DbmqgBOeNrKtdJsGvIeX/NGLgUDWMrj2h04V4O+jpBFmSf6HIld6triKmxCA== + +"@lerna/validation-error@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-3.6.0.tgz#550cf66bb2ef88edc02e36017b575a7a9100d5d8" + integrity sha512-MWltncGO5VgMS0QedTlZCjFUMF/evRjDMMHrtVorkIB2Cp5xy0rkKa8iDBG43qpUWeG1giwi58yUlETBcWfILw== + dependencies: + libnpm "^2.0.1" + +"@lerna/version@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.10.6.tgz#c31c2bb1aabbdc851407534155567b5cdf48e0fb" + integrity sha512-77peW2ROlHHl1e/tHBUmhpb8tsO6CIdlx34XapZhUuIVykrkOuqVFFxqMecrGG8SJe0e3l1G+Fah7bJTQcG0kw== + dependencies: + "@lerna/batch-packages" "3.10.6" + "@lerna/check-working-tree" "3.10.0" + "@lerna/child-process" "3.3.0" + "@lerna/collect-updates" "3.10.1" + "@lerna/command" "3.10.6" + "@lerna/conventional-commits" "3.10.0" + "@lerna/output" "3.6.0" + "@lerna/prompt" "3.6.0" + "@lerna/run-lifecycle" "3.10.5" + "@lerna/validation-error" "3.6.0" + chalk "^2.3.1" + dedent "^0.7.0" + libnpm "^2.0.1" + minimatch "^3.0.4" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + p-waterfall "^1.0.0" + semver "^5.5.0" + slash "^1.0.0" + temp-write "^3.4.0" + +"@lerna/write-log-file@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-3.6.0.tgz#b8d5a7efc84fa93cbd67d724d11120343b2a849a" + integrity sha512-OkLK99V6sYXsJsYg+O9wtiFS3z6eUPaiz2e6cXJt80mfIIdI1t2dnmyua0Ib5cZWExQvx2z6Y32Wlf0MnsoNsA== + dependencies: + libnpm "^2.0.1" + write-file-atomic "^2.3.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@react-native-firebase/tests-firebase-functions@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@react-native-firebase/tests-firebase-functions/-/tests-firebase-functions-0.0.5.tgz#6cf417c1e981b014dfb353888fe1e184141ff49f" + integrity sha512-cISbuhGU0lLPsC7qnlAHgPkqPsNSPaG2SPplSYiokRDpt3PBxVEWGCc6/yNeDQzkT+cguzc4eXUqc777x9pzBQ== + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -657,6 +1346,101 @@ dependencies: any-observable "^0.3.0" +"@sinonjs/commons@^1.0.2": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849" + integrity sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^3.0.0", "@sinonjs/formatio@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.1.0.tgz#6ac9d1eb1821984d84c4996726e45d1646d8cce5" + integrity sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg== + dependencies: + "@sinonjs/samsam" "^2 || ^3" + +"@sinonjs/samsam@^2 || ^3": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.0.2.tgz#304fb33bd5585a0b2df8a4c801fcb47fa84d8e43" + integrity sha512-m08g4CS3J6lwRQk1pj1EO+KEVWbrbXsmi9Pw0ySmrIbcVxVaedoFgLvFsV8wHLwh01EpROVz3KvVcD1Jmks9FQ== + dependencies: + "@sinonjs/commons" "^1.0.2" + array-from "^2.1.1" + lodash.get "^4.4.2" + +"@sinonjs/samsam@^2.1.2": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.3.tgz#62cf2a9b624edc795134135fe37fc2ae8ea36be3" + integrity sha512-8zNeBkSKhU9a5cRNbpCKau2WWPfan+Q2zDlcXvXyhn9EsMqgYs4qzo0XHNVlXC6ABQL8fT6nV+zzo5RTHJzyXw== + +"@types/events@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== + +"@types/fs-extra@^5.0.3": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.4.tgz#b971134d162cc0497d221adde3dbb67502225599" + integrity sha512-DsknoBvD8s+RFfSGjmERJ7ZOP1HI0UZRA3FSI+Zakhrc/Gy26YQsLI+m5V5DHxroHRJqCDLKJp7Hixn8zyaF7g== + dependencies: + "@types/node" "*" + +"@types/glob@*": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/handlebars@^4.0.38": + version "4.0.40" + resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.40.tgz#b714e13d296a75bff3f199316d1311933ca79ffd" + integrity sha512-sGWNtsjNrLOdKha2RV1UeF8+UbQnPSG7qbe5wwbni0mw4h2gHXyPFUMOC+xwGirIiiydM/HSqjDO4rk6NFB18w== + +"@types/highlight.js@^9.12.3": + version "9.12.3" + resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca" + integrity sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ== + +"@types/lodash@^4.14.110": + version "4.14.120" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.120.tgz#cf265d06f6c7a710db087ed07523ab8c1a24047b" + integrity sha512-jQ21kQ120mo+IrDs1nFNVm/AsdFxIx2+vZ347DbogHJPd/JzKNMOqU6HCYin1W6v8l5R9XSO2/e9cxmn7HAnVw== + +"@types/marked@^0.4.0": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.4.2.tgz#64a89e53ea37f61cc0f3ee1732c555c2dbf6452f" + integrity sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg== + +"@types/minimatch@*", "@types/minimatch@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/shelljs@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.1.tgz#133e874b5fb816a2e1c8647839c82d76760b1191" + integrity sha512-1lQw+48BuVgp6c1+z8EMipp18IdnV2dLh6KQGwOm+kJy9nPjEkaqRKmwbDNEYf//EKBvKcwOC6V2cDrNxVoQeQ== + dependencies: + "@types/glob" "*" + "@types/node" "*" + +JSONStream@^1.0.4, JSONStream@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + 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" @@ -681,20 +1465,41 @@ acorn-jsx@^5.0.0: integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== acorn@^6.0.2: - version "6.0.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" - integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + version "6.0.5" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" + integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg== + +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== + dependencies: + humanize-ms "^1.2.1" ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" - integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== + version "6.7.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.7.0.tgz#e3ce7bb372d6577bb1839f1dfdfcbf5ad2948d96" + integrity sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -778,11 +1583,28 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.0.3: +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + +aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +"aproba@^1.1.2 || 2", aproba@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + 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" @@ -846,11 +1668,31 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + array-includes@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" @@ -874,6 +1716,18 @@ array-slice@^0.2.3: resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -884,12 +1738,17 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + art@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2" integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ== -asap@~2.0.3: +asap@^2.0.0, asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -931,7 +1790,7 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== -async@^2.4.0: +async@^2.4.0, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== @@ -973,7 +1832,7 @@ axobject-query@^2.0.1: dependencies: ast-types-flow "0.0.7" -babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -982,35 +1841,10 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^6.26.0, babel-core@^6.7.2: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - 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-eslint@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" - integrity sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g== +babel-eslint@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" + integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" @@ -1019,432 +1853,52 @@ babel-eslint@^9.0.0: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== +babel-plugin-istanbul@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893" + integrity sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ== 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" + find-up "^3.0.0" + istanbul-lib-instrument "^3.0.0" + test-exclude "^5.0.0" -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" - integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= +babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: + version "7.0.0-beta.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" + integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== + +babel-preset-fbjs@^3.0.0, babel-preset-fbjs@^3.0.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.1.2.tgz#3a067309fed19dd435aeaea56cbf59fdd672bc15" + integrity sha512-Bfrc4T3sub3TlXB19SQGKVigAiZpXJh05Cng8Iytn0TODXa86CigTkQnGun1FMQZJHrrpBpbm/IVDj+4K9lwAQ== 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" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - 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" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -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" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - 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" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - 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" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - 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" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - 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" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - 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" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= - 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" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.8.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" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" - -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" - integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= - -babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= - -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" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - -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" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= - -babel-plugin-syntax-trailing-function-commas@^6.8.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" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-transform-class-properties@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= - 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-es2015-arrow-functions@^6.8.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" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.8.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" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.8.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" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - 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.8.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" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - 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.8.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" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.8.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" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-for-of@^6.8.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" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.8.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" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.8.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" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-commonjs@^6.8.0: - 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" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== - 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-object-super@^6.8.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" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.8.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" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - 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.8.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" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.8.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" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-template-literals@^6.8.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" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es3-member-expression-literals@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-member-expression-literals/-/babel-plugin-transform-es3-member-expression-literals-6.22.0.tgz#733d3444f3ecc41bef8ed1a6a4e09657b8969ebb" - integrity sha1-cz00RPPsxBvvjtGmpOCWV7iWnrs= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es3-property-literals@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-property-literals/-/babel-plugin-transform-es3-property-literals-6.22.0.tgz#b2078d5842e22abf40f73e8cde9cd3711abd5758" - integrity sha1-sgeNWELiKr9A9z6M3pzTcRq9V1g= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.8.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" - integrity sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988= - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-object-rest-spread@^6.8.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" - integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - -babel-plugin-transform-react-display-name@^6.8.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" - integrity sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" - integrity sha1-hAoCjn30YN/DotKfDA2R9jduZqM= - dependencies: - babel-helper-builder-react-jsx "^6.24.1" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.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" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-fbjs@2.3.0, babel-preset-fbjs@^2.1.2: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-2.3.0.tgz#92ff81307c18b926895114f9828ae1674c097f80" - integrity sha512-ZOpAI1/bN0Y3J1ZAK9gRsFkHy9gGgJoDRUjtUCla/129LC7uViq9nIK22YdHfey8szohYoZY3f9L2lGOv0Edqw== - dependencies: - babel-plugin-check-es2015-constants "^6.8.0" - babel-plugin-syntax-class-properties "^6.8.0" - babel-plugin-syntax-flow "^6.8.0" - babel-plugin-syntax-jsx "^6.8.0" - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-plugin-syntax-trailing-function-commas "^6.8.0" - babel-plugin-transform-class-properties "^6.8.0" - babel-plugin-transform-es2015-arrow-functions "^6.8.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.8.0" - babel-plugin-transform-es2015-block-scoping "^6.8.0" - babel-plugin-transform-es2015-classes "^6.8.0" - babel-plugin-transform-es2015-computed-properties "^6.8.0" - babel-plugin-transform-es2015-destructuring "^6.8.0" - babel-plugin-transform-es2015-for-of "^6.8.0" - babel-plugin-transform-es2015-function-name "^6.8.0" - babel-plugin-transform-es2015-literals "^6.8.0" - babel-plugin-transform-es2015-modules-commonjs "^6.8.0" - babel-plugin-transform-es2015-object-super "^6.8.0" - babel-plugin-transform-es2015-parameters "^6.8.0" - babel-plugin-transform-es2015-shorthand-properties "^6.8.0" - babel-plugin-transform-es2015-spread "^6.8.0" - babel-plugin-transform-es2015-template-literals "^6.8.0" - babel-plugin-transform-es3-member-expression-literals "^6.8.0" - babel-plugin-transform-es3-property-literals "^6.8.0" - babel-plugin-transform-flow-strip-types "^6.8.0" - babel-plugin-transform-object-rest-spread "^6.8.0" - babel-plugin-transform-react-display-name "^6.8.0" - babel-plugin-transform-react-jsx "^6.8.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - 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.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" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - 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" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - 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.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" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-member-expression-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-property-literals" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" balanced-match@^1.0.0: version "1.0.0" @@ -1489,15 +1943,51 @@ bcrypt-pbkdf@^1.0.0: tweetnacl "^0.14.3" big-integer@^1.6.7: - version "1.6.36" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" - integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + version "1.6.41" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.41.tgz#6fb0e51bc8661129ef3832d46c939170b81ca794" + integrity sha512-d5AT9lMTYJ/ZE/4gzxb+5ttPcRWljVsvv7lF1w9KzkPhVUhBtHrjDo1J8swfZKepfLsliDhYa31zRYwcD0Yg9w== + +bin-links@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757" + integrity sha512-8eEHVgYP03nILphilltWjeIjMbKyJo3wvp9K816pHbhP301ismzw15mxAAEVQ/USUwcP++1uNrbERbp8lOA6Fg== + dependencies: + bluebird "^3.5.0" + cmd-shim "^2.0.2" + gentle-fs "^2.0.0" + graceful-fs "^4.1.11" + write-file-atomic "^2.3.0" binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@3.5.x, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + bplist-creator@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" @@ -1545,6 +2035,11 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + bser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -1552,21 +2047,79 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +buffer-crc32@^0.2.13: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +bunyan-debug-stream@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-1.1.1.tgz#4740a00b7d5c2d9d1b714925ab0802516040813e" + integrity sha512-jJbQ1gXUL6vMmZVdbaTFK1v1sGa7axLrSQQwkB6HU9HCPTzsw2HsKcPHm1vgXZlEck/4IvEuRwg/9+083YelCg== + dependencies: + colors "^1.0.3" + exception-formatter "^1.0.4" + +bunyan@^1.8.12: + version "1.8.12" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" + integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c= + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.10.6" + mv "~2" + safe-json-stringify "~1" + +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= + +byte-size@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23" + integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw== + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= +cacache@^11.0.1, cacache@^11.3.2: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== + dependencies: + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -1582,6 +2135,21 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +caching-transform@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-2.0.0.tgz#e1292bd92d35b6e8b1ed7075726724b3bd64eea0" + integrity sha512-tTfemGmFWe7KZ3KN6VsSgQZbd9Bgo7A40wlp4PTsJJvFu4YAnEC5YnfdiKq6Vh2i9XJLnA9n8OXD46orVpnPMw== + dependencies: + make-dir "^1.0.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + write-file-atomic "^2.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -1589,13 +2157,6 @@ caller-callsite@^2.0.0: dependencies: callsites "^2.0.0" -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= - dependencies: - callsites "^0.2.0" - caller-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" @@ -1603,17 +2164,39 @@ caller-path@^2.0.0: dependencies: caller-callsite "^2.0.0" -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= - callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -camelcase@^4.1.0: +callsites@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" + integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= @@ -1630,6 +2213,11 @@ capture-exit@^1.2.0: dependencies: rsvp "^3.3.3" +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1646,10 +2234,10 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1665,7 +2253,16 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@^2.0.0, chokidar@^2.0.3: +child-process-promise@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" + integrity sha1-RzChHvYQ+tRQuPIjx50x172tgHQ= + dependencies: + cross-spawn "^4.0.2" + node-version "^1.0.0" + promise-polyfill "^6.0.1" + +chokidar@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== @@ -1695,6 +2292,11 @@ ci-info@^1.5.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -1710,6 +2312,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1748,6 +2355,19 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +cmd-shim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + integrity sha1-b8vamUg6j9FdfTChlspp1oii79s= + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + 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" @@ -1789,6 +2409,19 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +colors@^1.0.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +columnify@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" @@ -1796,7 +2429,12 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.14.1, commander@^2.8.1, commander@^2.9.0: +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@^2.11.0, commander@^2.12.1, commander@^2.14.1, commander@^2.15.1, commander@^2.8.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== @@ -1806,11 +2444,24 @@ commander@~2.13.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg= + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -1841,7 +2492,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.6.0: +concat-stream@^1.5.0, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -1851,6 +2502,26 @@ concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + connect@^3.6.5: version "3.6.6" resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" @@ -1871,13 +2542,108 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -convert-source-map@^1.1.0, convert-source-map@^1.5.1: +conventional-changelog-angular@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.2.tgz#39d945635e03b6d0c9d4078b1df74e06163dc66a" + integrity sha512-yx7m7lVrXmt4nKWQgWZqxSALEiAKZhOAcbxdUaU9575mB0CzXVbgrgpfSnSP7OqWDUTYGD0YVJ0MSRdyOPgAwA== + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-core@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.1.5.tgz#c2edf928539308b54fe1b90a2fc731abc021852c" + integrity sha512-iwqAotS4zk0wA4S84YY1JCUG7X3LxaRjJxuUo6GI4dZuIy243j5nOg/Ora35ExT4DOiw5dQbMMQvw2SUjh6moQ== + dependencies: + conventional-changelog-writer "^4.0.2" + conventional-commits-parser "^3.0.1" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "2.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^2.0.2" + lodash "^4.2.1" + normalize-package-data "^2.3.5" + q "^1.5.1" + read-pkg "^3.0.0" + read-pkg-up "^3.0.0" + through2 "^2.0.0" + +conventional-changelog-preset-loader@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.2.tgz#81d1a07523913f3d17da3a49f0091f967ad345b0" + integrity sha512-pBY+qnUoJPXAXXqVGwQaVmcye05xi6z231QM98wHWamGAmu/ghkBprQAwmF5bdmyobdVxiLhPY3PrCfSeUNzRQ== + +conventional-changelog-writer@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.2.tgz#eb493ed84269e7a663da36e49af51c54639c9a67" + integrity sha512-d8/FQY/fix2xXEBUhOo8u3DCbyEw3UOQgYHxLsPDw+wHUDma/GQGAGsGtoH876WyNs32fViHmTOUrgRKVLvBug== + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.1" + dateformat "^3.0.0" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^2.0.0" + +conventional-commits-filter@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz#55a135de1802f6510b6758e0a6aa9e0b28618db3" + integrity sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A== + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz#fe1c49753df3f98edb2285a5e485e11ffa7f2e4c" + integrity sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +conventional-recommended-bump@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.0.4.tgz#05540584641d3da758c8863c09788fcaeb586872" + integrity sha512-9mY5Yoblq+ZMqJpBzgS+RpSq+SUfP2miOR3H/NR9drGf08WCrY9B6HAGJZEm6+ThsVP917VHAahSOjM6k1vhPg== + dependencies: + concat-stream "^1.6.0" + conventional-changelog-preset-loader "^2.0.2" + conventional-commits-filter "^2.0.1" + conventional-commits-parser "^3.0.1" + git-raw-commits "2.0.0" + git-semver-tags "^2.0.2" + meow "^4.0.0" + q "^1.5.1" + +convert-source-map@^1.1.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== dependencies: safe-buffer "~5.1.1" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" @@ -1888,17 +2654,26 @@ core-js@^1.0.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= -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" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== +core-js@^2.2.2, core-js@^2.4.1, core-js@^2.5.7: + version "2.6.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.3.tgz#4b70938bdffdaf64931e66e2db158f0892289c49" + integrity sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ== core-util-is@1.0.2, 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" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.2, cosmiconfig@^5.0.5: +cosmiconfig@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cosmiconfig@^5.0.2, cosmiconfig@^5.0.5, cosmiconfig@^5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== @@ -1908,6 +2683,13 @@ cosmiconfig@^5.0.2, cosmiconfig@^5.0.5: js-yaml "^3.9.0" parse-json "^4.0.0" +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + create-react-class@^15.6.3: version "15.6.3" resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" @@ -1917,6 +2699,14 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" +cross-spawn@^4, cross-spawn@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1937,11 +2727,35 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + damerau-levenshtein@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" integrity sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ= +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + integrity sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc= + dependencies: + number-is-nan "^1.0.0" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1950,9 +2764,19 @@ dashdash@^1.12.0: assert-plus "^1.0.0" date-fns@^1.27.2: - version "1.29.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" - integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== + +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + integrity sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8= debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -1961,7 +2785,7 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@=3.1.0: +debug@3.1.0, debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -1976,13 +2800,26 @@ debug@^3.1.0: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" -decamelize@^1.1.1, decamelize@^1.2.0: +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2007,7 +2844,21 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -define-properties@^1.1.2: +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -2036,6 +2887,18 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -2061,22 +2924,66 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detox@9.1.2, detox@^9.0.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/detox/-/detox-9.1.2.tgz#f71b9dafcf006ef9a4a456528726b38a107205cf" + integrity sha512-pVyyDHPekYxzQK+sComeYXau5oNG1ZyMGjhEB8ecSbg5EaK1MhIyaLDxri4eDXVnOgLizFP9gqHZSgPcpdITRg== + dependencies: + bunyan "^1.8.12" + bunyan-debug-stream "^1.1.0" + child-process-promise "^2.2.0" + commander "^2.15.1" + fs-extra "^4.0.2" + get-port "^2.1.0" + ini "^1.3.4" + lodash "^4.17.5" + minimist "^1.2.0" + proper-lockfile "^3.0.2" + sanitize-filename "^1.6.1" + shell-utils "^1.0.9" + tail "^1.2.3" + telnet-client "0.15.3" + tempfile "^2.0.0" + ws "^1.1.1" + +dezalgo@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= + dependencies: + asap "^2.0.0" + wrappy "1" + +diff@3.5.0, diff@^3.2.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +doctrine@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" + integrity sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM= + dependencies: + esutils "^1.1.6" + isarray "0.0.1" doctrine@1.5.0: version "1.5.0" @@ -2098,6 +3005,47 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.1.0, dot-prop@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +dtrace-provider@~0.8: + version "0.8.7" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" + integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= + dependencies: + nan "^2.10.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" + integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2133,11 +3081,23 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" +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" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + envinfo@^5.7.0: version "5.12.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= + 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" @@ -2145,6 +3105,13 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d" + integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw== + dependencies: + stackframe "^1.0.4" + errorhandler@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.0.tgz#eaba64ca5d542a311ac945f582defc336165d9f4" @@ -2153,18 +3120,19 @@ errorhandler@^1.5.0: accepts "~1.3.3" escape-html "~1.0.3" -es-abstract@^1.6.1, es-abstract@^1.7.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" - integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== +es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.7.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== dependencies: - es-to-primitive "^1.1.1" + es-to-primitive "^1.2.0" function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" + has "^1.0.3" + is-callable "^1.1.4" is-regex "^1.0.4" + object-keys "^1.0.12" -es-to-primitive@^1.1.1: +es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== @@ -2173,12 +3141,29 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, 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" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -2192,7 +3177,7 @@ eslint-config-airbnb-base@^13.1.0: object.assign "^4.1.0" object.entries "^1.0.4" -eslint-config-airbnb@^17.0.0: +eslint-config-airbnb@^17.1.0: version "17.1.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz#3964ed4bc198240315ff52030bf8636f42bc4732" integrity sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw== @@ -2201,14 +3186,14 @@ eslint-config-airbnb@^17.0.0: object.assign "^4.1.0" object.entries "^1.0.4" -eslint-config-prettier@^3.0.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d" - integrity sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA== +eslint-config-prettier@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz#8ca3ffac4bd6eeef623a0651f9d754900e3ec217" + integrity sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ== dependencies: get-stdin "^6.0.0" -eslint-import-resolver-node@^0.3.1: +eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== @@ -2216,38 +3201,38 @@ eslint-import-resolver-node@^0.3.1: debug "^2.6.9" resolve "^1.5.0" -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= +eslint-module-utils@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" + integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w== dependencies: debug "^2.6.8" - pkg-dir "^1.0.0" + pkg-dir "^2.0.0" -eslint-plugin-flowtype@^2.50.1: - version "2.50.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" - integrity sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ== +eslint-plugin-flowtype@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.2.1.tgz#45e032aee54e695dfc41a891e92b7afedfc62c77" + integrity sha512-1lymqM8Cawxu5xsS8TaCrLWJYUmUdoG4hCfa7yWOhCf0qZn/CvI8FxqkhdOP6bAosBn5zeYxKe3Q/4rfKN8a+A== dependencies: lodash "^4.17.10" eslint-plugin-import@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + version "2.15.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.15.0.tgz#d8f3c28b8988ccde5df964706faa7c1e52f0602a" + integrity sha512-LEHqgR+RcnpGqYW7h9WMkPb/tP+ekKxWdQDztfTtZeV43IHF+X8lXU+1HOCcR4oXD24qRgEwNSxIweD5uNKGVg== dependencies: contains-path "^0.1.0" - debug "^2.6.8" + debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.3.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" read-pkg-up "^2.0.0" - resolve "^1.6.0" + resolve "^1.9.0" -eslint-plugin-jsx-a11y@^6.1.1: +eslint-plugin-jsx-a11y@^6.1.2: version "6.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88" integrity sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw== @@ -2261,7 +3246,7 @@ eslint-plugin-jsx-a11y@^6.1.1: has "^1.0.3" jsx-ast-utils "^2.0.1" -eslint-plugin-prettier@^2.6.2: +eslint-plugin-prettier@^2.2.0: version "2.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== @@ -2269,16 +3254,25 @@ eslint-plugin-prettier@^2.6.2: fast-diff "^1.1.1" jest-docblock "^21.0.0" -eslint-plugin-react@^7.10.0: - version "7.11.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" - integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw== +eslint-plugin-prettier@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz#19d521e3981f69dd6d14f64aec8c6a6ac6eb0b0d" + integrity sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react@^7.11.1: + version "7.12.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" + integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" has "^1.0.3" jsx-ast-utils "^2.0.1" + object.fromentries "^2.0.0" prop-types "^15.6.2" + resolve "^1.9.0" eslint-restricted-globals@^0.1.1: version "0.1.1" @@ -2311,10 +3305,10 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^5.5.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" - integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== +eslint@^5.12.1: + version "5.12.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.1.tgz#5ca9931fb9029d04e7be92b03ce3b58edfac7e3b" + integrity sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.5.3" @@ -2325,7 +3319,7 @@ eslint@^5.5.0: eslint-scope "^4.0.0" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^4.0.0" + espree "^5.0.0" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^2.0.0" @@ -2333,9 +3327,9 @@ eslint@^5.5.0: glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" + import-fresh "^3.0.0" imurmurhash "^0.1.4" inquirer "^6.1.0" - is-resolvable "^1.1.0" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" @@ -2348,17 +3342,16 @@ eslint@^5.5.0: pluralize "^7.0.0" progress "^2.0.0" regexpp "^2.0.1" - require-uncached "^1.0.3" semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" table "^5.0.2" text-table "^0.2.0" -espree@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== +espree@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" + integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA== dependencies: acorn "^6.0.2" acorn-jsx "^5.0.0" @@ -2388,6 +3381,11 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +esutils@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" + integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= + esutils@^2.0.0, esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2408,6 +3406,13 @@ eventemitter3@^3.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== +exception-formatter@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/exception-formatter/-/exception-formatter-1.0.7.tgz#3291616b86fceabefa97aee6a4708032c6e3b96d" + integrity sha512-zV45vEsjytJrwfGq6X9qd1Ll56cW4NC2mhCO6lqwMk4ZpA1fZ6C3UiaQM/X7if+7wZFmCgss3ahp9B/uVFuLRw== + dependencies: + colors "^1.0.3" + exec-sh@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" @@ -2415,19 +3420,6 @@ exec-sh@^0.2.0: dependencies: merge "^1.2.0" -execa@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" - integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== - dependencies: - cross-spawn "^6.0.0" - 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" - execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -2441,13 +3433,13 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" - integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" + cross-spawn "^6.0.0" + get-stream "^4.0.0" is-stream "^1.1.0" npm-run-path "^2.0.0" p-finally "^1.0.0" @@ -2572,11 +3564,23 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= -fast-diff@^1.1.1: +fast-diff@^1.1.1, fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== +fast-glob@^2.0.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" + integrity sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -2594,14 +3598,19 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs-scripts@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-0.8.3.tgz#b854de7a11e62a37f72dab9aaf4d9b53c4a03174" - integrity sha512-aUJ/uEzMIiBYuj/blLp4sVNkQQ7ZEB/lyplG1IzzOmZ83meiWecrGg5jBo4wWrxXmO4RExdtsSV1QkTjPt2Gag== +fbjs-css-vars@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" + integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== + +fbjs-scripts@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.0.1.tgz#7d8d09d76e83308bf3b1fc7b4c9c6fd081c5ef64" + integrity sha512-x8bfX7k0z5B24Ue0YqjZq/2QxxaKZUNbkGdX//zbQDElMJFqBRrvRi8O3qds7UNNzs78jYqIYCS32Sk/wu5UJg== dependencies: + "@babel/core" "^7.0.0" ansi-colors "^1.0.1" - babel-core "^6.7.2" - babel-preset-fbjs "^2.1.2" + babel-preset-fbjs "^3.0.0" core-js "^2.4.1" cross-spawn "^5.1.0" fancy-log "^1.3.2" @@ -2610,7 +3619,7 @@ fbjs-scripts@^0.8.1: semver "^5.1.0" through2 "^2.0.0" -fbjs@0.8.17, fbjs@^0.8.9: +fbjs@^0.8.9: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -2623,6 +3632,25 @@ fbjs@0.8.17, fbjs@^0.8.9: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +fbjs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" + integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA== + dependencies: + core-js "^2.4.1" + fbjs-css-vars "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -2694,6 +3722,20 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + +find-npm-prefix@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" + integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== + find-package@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-package/-/find-package-1.0.0.tgz#d7738da67e3c5f055c24d3e19aa1aeed063c3e83" @@ -2743,26 +3785,23 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -flow-bin@^0.80.0: - version "0.80.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.80.0.tgz#04cc1ee626a6f50786f78170c92ebe1745235403" - integrity sha512-0wRnqvXErQRPrx6GBLB5swgndfWkotd9MgfePgT7Z+VsE046c8Apzl7KKTCypB/pzn0pZF2g5Jurxxb2umET8g== +flow-bin@^0.89.0: + version "0.89.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.89.0.tgz#6bd29c2af7e0f429797f820662f33749105c32fa" + integrity sha512-DkO4PsXYrl53V6G5+t5HbRMC5ajYUQej2LEGPUZ+j9okTb41Sn5j9vfxsCpXMEAslYnQoysHhYu4GUZsQX/DrQ== -flow-copy-source@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flow-copy-source/-/flow-copy-source-2.0.2.tgz#096e579a9bb63a38afc5d4dd68ac847a5be27594" - integrity sha512-IHKgy45Q+Xs7UanUZyFFJae/ubMKtzj0dU4vs1YoqlfKl2wzLTaqehyTpjqO4vLAnL48yGvLfnttncX5Utn/4g== +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== dependencies: - chokidar "^2.0.0" - fs-extra "^7.0.0" - glob "^7.0.0" - kefir "^3.7.3" - yargs "^12.0.1" + inherits "^2.0.1" + readable-stream "^2.0.4" follow-redirects@^1.3.0: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + version "1.6.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.1.tgz#514973c44b5757368bad8bddfe52f81f015c94cb" + integrity sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ== dependencies: debug "=3.1.0" @@ -2778,6 +3817,14 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -2804,6 +3851,14 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + fs-extra@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" @@ -2813,6 +3868,15 @@ fs-extra@^1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" +fs-extra@^4.0.1, fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -2834,20 +3898,49 @@ fs-readdir-recursive@^1.1.0: resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== +fs-vacuum@^1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY= + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.2, fsevents@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== dependencies: nan "^2.9.2" node-pre-gyp "^0.10.0" -function-bind@^1.1.0, function-bind@^1.1.1: +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== @@ -2857,6 +3950,15 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + gauge@~1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" @@ -2882,10 +3984,29 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -genversion@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/genversion/-/genversion-2.1.0.tgz#6bbaa6c7398659b738ab03adce69cc4619969375" - integrity sha512-BBhXZASvA8i+0vcgQOCtTVVtCRJRDNintm7xfmxX8p4NA/LTncHwzX4+AmKFuSX4K2/nLIBjYAvSEZXeGK6AZA== +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== + +gentle-fs@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.0.1.tgz#585cfd612bfc5cd52471fdb42537f016a5ce3687" + integrity sha512-cEng5+3fuARewXktTEGbwsktcldA+YsnUEaXZwcK/3pjSE1X9ObnTs+/8rYf8s+RnIcQm2D5x3rwpN7Zom8Bew== + dependencies: + aproba "^1.1.2" + fs-vacuum "^1.2.10" + graceful-fs "^4.1.11" + iferr "^0.1.5" + mkdirp "^0.5.1" + path-is-inside "^1.0.2" + read-cmd-shim "^1.0.1" + slide "^1.1.6" + +genversion@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/genversion/-/genversion-2.1.1.tgz#ab2e782148893e258273a01579ed3ac443012ce0" + integrity sha512-/ui/svWs0oDae9o/396/1dK2yYFmNn+bt62iqN0IHoOlhgVFt3RwF+gtCxExLDlWVSPqvXAGEOOeuOabExuUvg== dependencies: commander "^2.11.0" find-package "^1.0.0" @@ -2897,11 +4018,44 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-caller-file@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.1.tgz#25835260d3a2b9665fcdbb08cb039a7bbf7011c0" + integrity sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg== + get-own-enumerable-property-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + integrity sha1-xztInAbYDMVTbCyFP54FIyBWly0= + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-port@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-2.1.0.tgz#8783f9dcebd1eea495a334e1a6a251e78887ab1a" + integrity sha1-h4P53OvR7qSVozThpqJR54iHqxo= + dependencies: + pinkie-promise "^2.0.0" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -2912,6 +4066,13 @@ get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + 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" @@ -2924,6 +4085,40 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +git-raw-commits@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" + integrity sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg== + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.2.tgz#f506ec07caade191ac0c8d5a21bdb8131b4934e3" + integrity sha512-34lMF7Yo1xEmsK2EkbArdoU79umpvm0MfzaDkSNYSJqtM5QLAVTPWgpiXSVI5o/O9EvZPSrP4Zvnec/CqhSd5w== + dependencies: + meow "^4.0.0" + semver "^5.5.0" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= + dependencies: + ini "^1.3.2" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -2947,7 +4142,35 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + 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" + +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -2959,6 +4182,13 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + global@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" @@ -2968,25 +4198,77 @@ global@^4.3.0: process "~0.5.1" globals@^11.1.0, globals@^11.7.0: - version "11.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== + version "11.10.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50" + integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ== -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +globby@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +handlebars@^4.0.11, handlebars@^4.0.2, handlebars@^4.0.6: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3017,7 +4299,7 @@ has-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= -has-unicode@^2.0.0: +has-unicode@^2.0.0, has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= @@ -3060,24 +4342,31 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -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" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +highlight.js@^9.13.1: + version "9.13.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" + integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== home-or-tmp@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs= -hosted-git-info@^2.1.4: +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +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" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -3088,6 +4377,14 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3097,14 +4394,36 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -husky@^0.14.3: - version "0.14.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" - integrity sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA== +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== dependencies: - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +husky@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" @@ -3113,6 +4432,11 @@ iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: dependencies: safer-buffer ">= 2.1.2 < 3" +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" @@ -3120,6 +4444,11 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -3138,11 +4467,39 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + indent-string@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -3156,16 +4513,30 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@~1.3.0: +ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + inquirer@^3.0.6: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -3186,7 +4557,7 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^6.1.0: +inquirer@^6.1.0, inquirer@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== @@ -3205,13 +4576,23 @@ inquirer@^6.1.0: strip-ansi "^5.0.0" through "^2.3.6" -invariant@^2.2.2, invariant@^2.2.4: +interpret@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" +inversify@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" + integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -3222,6 +4603,11 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + 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" @@ -3260,7 +4646,7 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.3, is-callable@^1.1.4: +is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== @@ -3272,6 +4658,13 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.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" @@ -3388,6 +4781,19 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -3407,7 +4813,7 @@ is-number@^4.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== -is-obj@^1.0.1: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= @@ -3419,7 +4825,26 @@ is-observable@^1.1.0: dependencies: symbol-observable "^1.1.0" -is-plain-obj@^1.1.0: +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +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" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= @@ -3446,6 +4871,11 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" @@ -3458,16 +4888,21 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-resolvable@^1.1.0: +is-retry-allowed@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -3475,16 +4910,33 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + dependencies: + text-extensions "^1.0.0" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -3520,12 +4972,62 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -jest-docblock@23.2.0, jest-docblock@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" - integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c= +istanbul-lib-coverage@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA== + +istanbul-lib-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72" + integrity sha512-ufiZoiJ8CxY577JJWEeFuxXZoMqiKpq/RqZtOAYuQLvlkbJWscq9n3gc4xrCGH9n4pW0qnTxOz1oyMmVtk8E1w== dependencies: - detect-newline "^2.1.0" + append-transform "^1.0.0" + +istanbul-lib-instrument@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9" + integrity sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + +istanbul-lib-report@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535" + integrity sha512-rJ8uR3peeIrwAxoDEbK4dJ7cqqtxBisZKCuwkMtMv0xYzaAnsAi3AHrHPAAtNXzG/bcCgZZ3OJVqm1DTi9ap2Q== + dependencies: + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + supports-color "^5.4.0" + +istanbul-lib-source-maps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e" + integrity sha512-30l40ySg+gvBLcxTrLzR4Z2XTRj3HgRCA/p2rnbs/3OiTaoj054gAbuP5DcLOtwqmy4XW8qXBHzrmP2/bQ9i3A== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^2.0.1" + make-dir "^1.3.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-reports@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7" + integrity sha512-CT0QgMBJqs6NJLF678ZHcquUAZIoBIUNzdJrRJfpkI9OnzG6MkUfHxbJC3ln981dMswC7/B1mfX3LNkhgJxsuw== + dependencies: + handlebars "^4.0.11" jest-docblock@^21.0.0: version "21.2.0" @@ -3537,24 +5039,28 @@ jest-get-type@^22.1.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== -jest-haste-map@23.5.0: - version "23.5.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.5.0.tgz#d4ca618188bd38caa6cb20349ce6610e194a8065" - integrity sha512-bt9Swigb6KZ6ZQq/fQDUwdUeHenVvZ6G/lKwJjwRGp+Fap8D4B3bND3FaeJg7vXVsLX8hXshRArbVxLop/5wLw== +jest-haste-map@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz#fb2c785080f391b923db51846b86840d0d773076" + integrity sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw== dependencies: fb-watchman "^2.0.0" graceful-fs "^4.1.11" invariant "^2.2.4" - jest-docblock "^23.2.0" - jest-serializer "^23.0.1" - jest-worker "^23.2.0" + jest-serializer "^24.0.0-alpha.6" + jest-worker "^24.0.0-alpha.6" micromatch "^2.3.11" - sane "^2.0.0" + sane "^3.0.0" -jest-serializer@23.0.1, jest-serializer@^23.0.1: - version "23.0.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" - integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= +jest-serializer@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz#27d2fee4b1a85698717a30c3ec2ab80767312597" + integrity sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw== + +jest-serializer@^24.0.0-alpha.6: + version "24.0.0-alpha.12" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.0.0-alpha.12.tgz#44478e6256f9e2b76a24cd56ba49923e33fe5522" + integrity sha512-7Cfomo8PLwRcbFmOEXPAokb0+lCkmFUKOjP+XUvRz31JoLhrR+Ty5+CHjwZmtHBssdbAuK28lwMWX/XId9HhNw== jest-validate@^23.5.0: version "23.6.0" @@ -3566,13 +5072,39 @@ jest-validate@^23.5.0: leven "^2.1.0" pretty-format "^23.6.0" -jest-worker@23.2.0, jest-worker@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" - integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk= +jest-worker@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz#463681b92c117c57107135c14b9b9d6cd51d80ce" + integrity sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA== dependencies: merge-stream "^1.0.1" +jest-worker@^24.0.0-alpha.6: + version "24.0.0-alpha.12" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.0.0-alpha.12.tgz#b7ca1fb774b4eddc342768b7a63d89be5e6a762f" + integrity sha512-BzGiUwc2LPyrvOuCMqdiLqWU78C+lHbHI/hcJgWonTda0RS7aCcrgSJx5t9+56U9rzMMxDC75S9khJ0oi3fYQA== + dependencies: + merge-stream "^1.0.1" + supports-color "^5.5.0" + +jet@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/jet/-/jet-0.2.1.tgz#65ddafa0f72df483e72923bae3f2934655971e78" + integrity sha512-muR97xGmv4xl3g2hK3O/2bdo20twh015uo8rjZm2OoaqnkCn46Xfx1ODZDOUXS7Tiygof4H2JPo/DmOTaMiIKw== + dependencies: + chalk "^2.4.1" + error-stack-parser "^2.0.2" + istanbul-lib-coverage "^1.2.0" + should "^13.2.1" + should-sinon "0.0.6" + sinon "^6.1.4" + source-map "^0.7.3" + tinyqueue "^1.2.3" + ws "^6.0.0" + optionalDependencies: + detox "^9.0.1" + mocha "^5.2.0" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -3583,10 +5115,10 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.12.0, js-yaml@^3.9.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== +js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0: + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -3596,11 +5128,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -3611,7 +5138,7 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.1: +json-parse-better-errors@^1.0.0, 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" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -3638,16 +5165,11 @@ json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - json5@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" @@ -3674,6 +5196,11 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3691,12 +5218,10 @@ jsx-ast-utils@^2.0.1: dependencies: array-includes "^3.0.3" -kefir@^3.7.3: - version "3.8.5" - resolved "https://registry.yarnpkg.com/kefir/-/kefir-3.8.5.tgz#ce8d952707ea833d9d995a96b92daa744dea83ba" - integrity sha512-u4UxHyIvdOOM62Y/yAtYPeYEg/yUfwl5/QF3ksrTRxEdhpa7LAFChntZxVqbcf0gCGblZzL/JnV/gZYWOps3Qw== - dependencies: - symbol-observable "1.0.4" +just-extend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" + integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== kind-of@^1.1.0: version "1.1.0" @@ -3734,6 +5259,13 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" @@ -3748,6 +5280,29 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +lerna@^3.6.0: + version "3.10.7" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.10.7.tgz#9d308b1fee1697f89fe90e6bc37e51c03b531557" + integrity sha512-ha/dehl/L3Nw0pbdir5z6Hrv2oYBg5ym2fTcuk8HCLe7Zdb/ylIHdrgW8CU9eTVZkwr4et8RdVtxFA/+xa65/Q== + dependencies: + "@lerna/add" "3.10.6" + "@lerna/bootstrap" "3.10.6" + "@lerna/changed" "3.10.6" + "@lerna/clean" "3.10.6" + "@lerna/cli" "3.10.7" + "@lerna/create" "3.10.6" + "@lerna/diff" "3.10.6" + "@lerna/exec" "3.10.6" + "@lerna/import" "3.10.6" + "@lerna/init" "3.10.6" + "@lerna/link" "3.10.6" + "@lerna/list" "3.10.6" + "@lerna/publish" "3.10.7" + "@lerna/run" "3.10.6" + "@lerna/version" "3.10.6" + import-local "^1.0.0" + libnpm "^2.0.1" + leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" @@ -3761,22 +5316,129 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lint-staged@^7.2.2: - version "7.3.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.3.0.tgz#90ff33e5ca61ed3dbac35b6f6502dbefdc0db58d" - integrity sha512-AXk40M9DAiPi7f4tdJggwuKIViUplYtVj1os1MVEteW7qOkU50EOehayCfO9TsoGK24o/EsWb41yrEgfJDDjCw== +libnpm@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-2.0.1.tgz#a48fcdee3c25e13c77eb7c60a0efe561d7fb0d8f" + integrity sha512-qTKoxyJvpBxHZQB6k0AhSLajyXq9ZE/lUsZzuHAplr2Bpv9G+k4YuYlExYdUCeVRRGqcJt8hvkPh4tBwKoV98w== dependencies: + bin-links "^1.1.2" + bluebird "^3.5.3" + find-npm-prefix "^1.0.2" + libnpmaccess "^3.0.1" + libnpmconfig "^1.2.1" + libnpmhook "^5.0.2" + libnpmorg "^1.0.0" + libnpmpublish "^1.1.0" + libnpmsearch "^2.0.0" + libnpmteam "^1.0.1" + lock-verify "^2.0.2" + npm-lifecycle "^2.1.0" + npm-logical-tree "^1.2.1" + npm-package-arg "^6.1.0" + npm-profile "^4.0.1" + npm-registry-fetch "^3.8.0" + npmlog "^4.1.2" + pacote "^9.2.3" + read-package-json "^2.0.13" + stringify-package "^1.0.0" + +libnpmaccess@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.1.tgz#5b3a9de621f293d425191aa2e779102f84167fa8" + integrity sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA== + dependencies: + aproba "^2.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + +libnpmconfig@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0" + integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA== + dependencies: + figgy-pudding "^3.5.1" + find-up "^3.0.0" + ini "^1.3.5" + +libnpmhook@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.2.tgz#d12817b0fb893f36f1d5be20017f2aea25825d94" + integrity sha512-vLenmdFWhRfnnZiNFPNMog6CK7Ujofy2TWiM2CrpZUjBRIhHkJeDaAbJdYCT6W4lcHtyrJR8yXW8KFyq6UAp1g== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^3.8.0" + +libnpmorg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.0.tgz#979b868c48ba28c5820e3bb9d9e73c883c16a232" + integrity sha512-o+4eVJBoDGMgRwh2lJY0a8pRV2c/tQM/SxlqXezjcAg26Qe9jigYVs+Xk0vvlYDWCDhP0g74J8UwWeAgsB7gGw== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^3.8.0" + +libnpmpublish@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.1.tgz#ff0c6bb0b4ad2bda2ad1f5fba6760a4af37125f0" + integrity sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.5.1" + get-stream "^4.0.0" + lodash.clonedeep "^4.5.0" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + semver "^5.5.1" + ssri "^6.0.1" + +libnpmsearch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.0.tgz#de05af47ada81554a5f64276a69599070d4a5685" + integrity sha512-vd+JWbTGzOSfiOc+72MU6y7WqmBXn49egCCrIXp27iE/88bX8EpG64ST1blWQI1bSMUr9l1AKPMVsqa2tS5KWA== + dependencies: + figgy-pudding "^3.5.1" + get-stream "^4.0.0" + npm-registry-fetch "^3.8.0" + +libnpmteam@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.1.tgz#ff704b1b6c06ea674b3b1101ac3e305f5114f213" + integrity sha512-gDdrflKFCX7TNwOMX1snWojCoDE5LoRWcfOC0C/fqF7mBq8Uz9zWAX4B2RllYETNO7pBupBaSyBDkTAC15cAMg== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.4.1" + get-stream "^4.0.0" + npm-registry-fetch "^3.8.0" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +lint-staged@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" + integrity sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ== + dependencies: + "@iamstarkov/listr-update-renderer" "0.4.1" chalk "^2.3.1" commander "^2.14.1" - cosmiconfig "^5.0.2" + cosmiconfig "5.0.6" debug "^3.1.0" dedent "^0.7.0" - execa "^0.9.0" + del "^3.0.0" + execa "^1.0.0" find-parent-dir "^0.3.0" + g-status "^2.0.2" is-glob "^4.0.0" is-windows "^1.0.2" jest-validate "^23.5.0" - listr "^0.14.1" + listr "^0.14.2" lodash "^4.17.5" log-symbols "^2.2.0" micromatch "^3.1.8" @@ -3785,7 +5447,7 @@ lint-staged@^7.2.2: path-is-inside "^1.0.2" pify "^3.0.0" please-upgrade-node "^3.0.2" - staged-git-files "1.1.1" + staged-git-files "1.1.2" string-argv "^0.0.2" stringify-object "^3.2.2" @@ -3818,7 +5480,7 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr@^0.14.1: +listr@^0.14.2: version "0.14.3" resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== @@ -3833,6 +5495,17 @@ listr@^0.14.1: p-map "^2.0.0" rxjs "^6.3.3" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + 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" @@ -3843,6 +5516,16 @@ load-json-file@^2.0.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" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + 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" @@ -3859,11 +5542,39 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lock-verify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.0.2.tgz#148e4f85974915c9e3c34d694b7de9ecb18ee7a8" + integrity sha512-QNVwK0EGZBS4R3YQ7F1Ox8p41Po9VGl2QG/2GsuvTbkJZYSsPeWHKMbbH6iZMCHWSMww5nrJroZYnGzI4cePuw== + dependencies: + npm-package-arg "^5.1.2 || 6" + semver "^5.4.1" + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash.pad@^4.1.0: version "4.5.1" resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" @@ -3879,12 +5590,32 @@ lodash.padstart@^4.1.0: resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1: +lodash@4.x.x, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -3912,6 +5643,11 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" +lolex@^2.3.2, lolex@^2.7.5: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -3919,7 +5655,20 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@^4.0.1: +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.3: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== @@ -3927,13 +5676,37 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -make-dir@^1.0.0: +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^1.0.0, make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" +make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ== + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -3953,6 +5726,16 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -3960,10 +5743,34 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marked@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66" + integrity sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw== + +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + math-random@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" - integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= mem@^1.1.0: version "1.1.0" @@ -3981,6 +5788,44 @@ mem@^4.0.0: mimic-fn "^1.0.0" p-is-promise "^1.1.0" +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + merge-stream@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" @@ -3988,15 +5833,20 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + merge@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== -metro-babel-register@^0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.45.6.tgz#c0dfb78b7d4f8454468a515a3118a12b08e855cc" - integrity sha512-Io8JinYIzGcXiTaO7o0DGw8wFcAiITTb7mLh3lbuJd9PndbPOo+jhrHkTsNtXc9MRHiT4KbEheXJ/QoeLKJK/Q== +metro-babel-register@^0.49.1: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.49.2.tgz#746c73311135bd6c2af4d83c2cc6c5cbcf0e8a65" + integrity sha512-xx+SNwJ3Dl4MmSNn1RpUGc7b5pyTxXdpqpE7Fuk499rZffypVI1uhKOjKt2lwQhlyD03sXuvB/m3RdEg3mivWg== dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" @@ -4011,59 +5861,60 @@ metro-babel-register@^0.45.6: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel7-plugin-react-transform@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.45.6.tgz#e13b7b0e87e4f908d61b1bf88753af1119e19f58" - integrity sha512-NsVKqiBaF+Tm3FXzqiEExl9iJG+EimbpQP5h9ygxBE4AsYRc2S3X/YD/1ds3RTHMgfhinWVaus+DrG5OqK5mTA== +metro-babel7-plugin-react-transform@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.49.2.tgz#d4c43faa6f2b91cc1b244a36a5d708ae8d39dbb2" + integrity sha512-LpJT8UvqF/tvVqEwiLUTMjRPhEGdI8e2dr3424XaRANba3j0nqmrbKdJQsPE8TrcqMWR4RHmfsXk0ti5QrEvJg== dependencies: "@babel/helper-module-imports" "^7.0.0" -metro-cache@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.45.6.tgz#7ca9f66bc038a309d21e4c5264b806a692ca5a55" - integrity sha512-v7q2pLsI7oABEjpwPJwTd7ufwKvpctVOddcffI/2hRhuJC/seLlqkRt7kv+Q/WfaR9X4KLcEoIjZmgNy4cw1ag== +metro-cache@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.49.2.tgz#355dd3dba9fbd805a7ca6f55646216d35ca98225" + integrity sha512-GFeK4bPQn/U9bbRlVPhu2dYMe/b/GsNOFPEResOxr0kQreHV81rs6Jzcr4pU+9HY7vFiEQ1oggnsLUmANuRyPQ== dependencies: - jest-serializer "23.0.1" - metro-core "0.45.6" + jest-serializer "24.0.0-alpha.6" + metro-core "0.49.2" mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.45.6.tgz#f08472ea8c4807bd23263c42948019a9a4f34ada" - integrity sha512-ZhVtkpXhOi+qWi7vdE3HGIhyyBT1wtIukQuxTMwLTUluv2/1DClo/uX9inmf++CmOhOpU7QpqrMzl6vf+AwnOg== +metro-config@0.49.2, metro-config@^0.49.1: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.49.2.tgz#d9dd0cc32fdb9731b4685b0019c98874a6e4443b" + integrity sha512-olh50qIMWd+Mj47TQeFnIW9NIquMpfq2g2NT5k+rwI38Xfk+KBnV4BamxtzZuViH7eQI06+Cdyu4NvcZffBXGg== dependencies: cosmiconfig "^5.0.5" - metro "0.45.6" - metro-cache "0.45.6" - metro-core "0.45.6" + metro "0.49.2" + metro-cache "0.49.2" + metro-core "0.49.2" + pretty-format "24.0.0-alpha.6" -metro-core@0.45.6, metro-core@^0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.45.6.tgz#b8654196cbeb28f75a23756422348f870117e4e3" - integrity sha512-M0YkGnkjStdCsSNYVW+aVlJ4WjwcqjIhQV+VzEnGZYdyo6cMi9MxUZ69iV2jIxd3LAeaQQaNe8OQtQp8dfIh/g== +metro-core@0.49.2, metro-core@^0.49.1: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.49.2.tgz#e3d7f9f02454863fc047bd75c2e37d5544c72d1a" + integrity sha512-kqhvNPOUTUWOqfm4nFF8l0zWMp2BKO1BUx5KY7osFnVTUpDkuq9Iy433FqEFVhA2jUISrmnd0CTIPcDQyFNllQ== dependencies: - jest-haste-map "23.5.0" + jest-haste-map "24.0.0-alpha.6" lodash.throttle "^4.1.1" - metro-resolver "0.45.6" + metro-resolver "0.49.2" wordwrap "^1.0.0" -metro-memory-fs@^0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.45.6.tgz#9a1fffbde2744b0a0a1d6fcd16f7cb43508f8d7b" - integrity sha512-YAGoNQVTM/vl65jR/ztucAZJIk0ejD3INZT0LiISRULBt6Rxfiqa22v5GG0Enq+95vlgmt26g+auHM2nxTUInQ== +metro-memory-fs@^0.49.1: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.49.2.tgz#af3128b8a60d02d4aed427558b42c8d210a5543c" + integrity sha512-bt7ve7iud5gU4Duo9MVMqohJ0nBxILHmQxFhDXOvJnttiDuIfQQUK84pVlo8maNkFbN8uxEJPLBjpD1DC1IOxA== -metro-minify-uglify@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.45.6.tgz#72cd952371a50b9204fd89d89e8041640237b7c1" - integrity sha512-l+lZ7Gg6CN9XddgmwAbo7zOLT2QB9a6VALXLzmvr6gB1mc6SBZwtAh+hARvdymtcr1CgbaWADZPAA+W3oQZH4g== +metro-minify-uglify@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.49.2.tgz#f3b8615cb0e9afd714e4952842bcb9f4d71b4822" + integrity sha512-LfnR5N2784pnHe5ShioNkLHyUA1unDU6iLivehX2Waxno1oIP3xKYl/u/VTDET4L8AvLwa5HFACE2hbiWjGQ2Q== dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.45.6.tgz#077ce4039d6461a1b699b215612985415f9816a9" - integrity sha512-qh+iXlV2tDfvHYbhh1meihxnzXXXB8nF1fi8z2HFxqYDkFBM48XewXO6mLz97PL8lmuTGvX/2dYVuFtriENw1w== +metro-react-native-babel-preset@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.49.2.tgz#8d53610e044e0c9a53a03d307e1c51f9e8577abc" + integrity sha512-N0+4ramShYCHSAVEPUNWIZuKZskWj8/RDSoinhadHpdpHORMbMxLkexSOVHLluB+XFQ+DENLEx5oVPYwOlENBA== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" @@ -4090,6 +5941,7 @@ metro-react-native-babel-preset@0.45.6: "@babel/plugin-transform-react-jsx" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-runtime" "^7.0.0" "@babel/plugin-transform-shorthand-properties" "^7.0.0" "@babel/plugin-transform-spread" "^7.0.0" "@babel/plugin-transform-sticky-regex" "^7.0.0" @@ -4097,27 +5949,27 @@ metro-react-native-babel-preset@0.45.6: "@babel/plugin-transform-typescript" "^7.0.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - metro-babel7-plugin-react-transform "0.45.6" + metro-babel7-plugin-react-transform "0.49.2" react-transform-hmr "^1.0.4" -metro-resolver@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.45.6.tgz#385407cf8c086f005775d2d28178cf36984273f9" - integrity sha512-RY4tqKxSEz4ahLPaJlx30x6vG8HVyLT3w5aUDcyB5B2eQH3ckLnyUYUpd0sT7HFoJ1T5U5DFtWvS3P4yJcRB7A== +metro-resolver@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.49.2.tgz#b7580d7a24fdf96170a9d4099a66b29a18e6e5f8" + integrity sha512-Si9/A+jNQmVWlLSi6fXSG1tDEanYu99PMz/cAvM+aZy1yX9RyqfJzHzWVdr4lrNh+4DKCgDea94B9BjezqNYyw== dependencies: absolute-path "^0.0.0" -metro-source-map@0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.45.6.tgz#49b20bbbc8f047ede7546b6721ab0214a1ad360d" - integrity sha512-FBubSEEitGrvUeuCPVwXTJX7Y1WjFhsUHickqQE+mXplOgREyeZ7o80ffqEWitfsMUQN9385LxIPmAdPzQXLsQ== +metro-source-map@0.49.2: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.49.2.tgz#0f9e3d0286fc9549652c99b56b7aa2aec12372e7" + integrity sha512-gUQ9wq8iR05QeMqRbAJ+L961LVfoNKLBXSeEzHxoDNSwZ7jFYLMKn0ofLlfMy0S1javZGisS51l5OScLt83naQ== dependencies: source-map "^0.5.6" -metro@0.45.6, metro@^0.45.6: - version "0.45.6" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.45.6.tgz#b4d7bf5edc39c5f7d73a6bc4d940e03415aa919b" - integrity sha512-+RinU6Qcea/zX9xxfrgmeFBwJ3tsdgLyBJm4tQOmusU4kE8YEE4LQ3IGG60qk3wzYloflMB/8ilIGG4Z/gz2Ew== +metro@0.49.2, metro@^0.49.1: + version "0.49.2" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.49.2.tgz#0fd615d9f451893a0816721b46e94dcf49dda0f6" + integrity sha512-GSNMigeQq+QQ++qwEnWx0hjtYCZIvogn4JuqpKqOyVqNbg+aIheJPvxfDzjF9OXM5WHuNsTfGLW8n5kbUmQJSg== dependencies: "@babel/core" "^7.0.0" "@babel/generator" "^7.0.0" @@ -4128,30 +5980,30 @@ metro@0.45.6, metro@^0.45.6: "@babel/types" "^7.0.0" absolute-path "^0.0.0" async "^2.4.0" - babel-preset-fbjs "2.3.0" + babel-preset-fbjs "^3.0.1" + buffer-crc32 "^0.2.13" chalk "^1.1.1" concat-stream "^1.6.0" connect "^3.6.5" debug "^2.2.0" denodeify "^1.2.1" eventemitter3 "^3.0.0" - fbjs "0.8.17" + fbjs "^1.0.0" fs-extra "^1.0.0" graceful-fs "^4.1.3" image-size "^0.6.0" - jest-docblock "23.2.0" - jest-haste-map "23.5.0" - jest-worker "23.2.0" + jest-haste-map "24.0.0-alpha.6" + jest-worker "24.0.0-alpha.6" json-stable-stringify "^1.0.1" lodash.throttle "^4.1.1" merge-stream "^1.0.1" - metro-cache "0.45.6" - metro-config "0.45.6" - metro-core "0.45.6" - metro-minify-uglify "0.45.6" - metro-react-native-babel-preset "0.45.6" - metro-resolver "0.45.6" - metro-source-map "0.45.6" + metro-cache "0.49.2" + metro-config "0.49.2" + metro-core "0.49.2" + metro-minify-uglify "0.49.2" + metro-react-native-babel-preset "0.49.2" + metro-resolver "0.49.2" + metro-source-map "0.49.2" mime-types "2.1.11" mkdirp "^0.5.1" node-fetch "^2.2.0" @@ -4253,19 +6105,27 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -4275,7 +6135,7 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.4: +minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== @@ -4284,12 +6144,28 @@ minipass@^2.2.1, minipass@^2.3.4: yallist "^3.0.0" minizlib@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" - integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== dependencies: minipass "^2.2.1" +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -4298,13 +6174,40 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, 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" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== + +moment@^2.10.6: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + morgan@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" @@ -4316,25 +6219,61 @@ morgan@^1.9.0: on-finished "~2.3.0" on-headers "~1.0.1" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@^2.0.0, ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.9.2: - version "2.11.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" - integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +mv@~2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" + integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + +nan@^2.10.0, nan@^2.9.2: + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== nanomatch@^1.2.9: version "1.2.13" @@ -4358,6 +6297,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= + needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" @@ -4377,6 +6321,26 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +nise@^1.4.5: + version "1.4.8" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.8.tgz#ce91c31e86cf9b2c4cac49d7fcd7f56779bfd6b0" + integrity sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw== + dependencies: + "@sinonjs/formatio" "^3.1.0" + just-extend "^4.0.2" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + text-encoding "^0.6.4" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -4390,6 +6354,24 @@ node-fetch@^2.2.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4426,6 +6408,18 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-version@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" + integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -4434,7 +6428,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2: +normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== @@ -4444,11 +6438,6 @@ normalize-package-data@^2.3.2: 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" - integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= - normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -4461,10 +6450,39 @@ npm-bundled@^1.0.1: resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== -npm-packlist@^1.1.6: - version "1.1.12" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" - integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== +npm-lifecycle@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz#1eda2eedb82db929e3a0c50341ab0aad140ed569" + integrity sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g== + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.11" + node-gyp "^3.8.0" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +npm-logical-tree@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" + integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg== + +"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", "npm-package-arg@^5.1.2 || 6", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.12, npm-packlist@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" + integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -4476,6 +6494,36 @@ npm-path@^2.0.2: dependencies: which "^1.2.10" +npm-pick-manifest@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" + integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-profile@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.1.tgz#d350f7a5e6b60691c7168fbb8392c3603583f5aa" + integrity sha512-NQ1I/1Q7YRtHZXkcuU1/IyHeLy6pd+ScKg4+DQHdfsm769TGq6HPrkbuNJVJS4zwE+0mvvmeULzQdWn2L2EsVA== + dependencies: + aproba "^1.1.2 || 2" + figgy-pudding "^3.4.1" + npm-registry-fetch "^3.8.0" + +npm-registry-fetch@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc" + integrity sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw== + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + 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" @@ -4492,16 +6540,7 @@ npm-which@^3.0.1: npm-path "^2.0.2" which "^1.2.10" -npmlog@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - -npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -4511,16 +6550,56 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" +npmlog@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + nullthrows@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.0.tgz#832bb19ef7fedab989f81675c846e2858a3917a2" - integrity sha512-YoigDq49JRqVCUlb4XlwZirXQiNCoXdwoyfklXJAEYHN+XKHWgDkrcWxNgxEtP7N+XF9Akp7Lr6wLq8HZxLttw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== 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" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +nyc@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.1.0.tgz#463665c7ff6b5798e322624a5eb449a678db90e3" + integrity sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg== + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^2.0.0" + convert-source-map "^1.6.0" + debug-log "^1.0.1" + find-cache-dir "^2.0.0" + find-up "^3.0.0" + foreground-child "^1.5.6" + glob "^7.1.3" + istanbul-lib-coverage "^2.0.1" + istanbul-lib-hook "^2.0.1" + istanbul-lib-instrument "^3.0.0" + istanbul-lib-report "^2.0.2" + istanbul-lib-source-maps "^2.0.1" + istanbul-reports "^2.0.1" + make-dir "^1.3.0" + merge-source-map "^1.1.0" + resolve-from "^4.0.0" + rimraf "^2.6.2" + signal-exit "^3.0.2" + spawn-wrap "^1.4.2" + test-exclude "^5.0.0" + uuid "^3.3.2" + yargs "11.1.0" + yargs-parser "^9.0.2" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -4563,13 +6642,23 @@ object.assign@^4.1.0: object-keys "^1.0.11" object.entries@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" - integrity sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8= + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519" + integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +object.fromentries@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" + integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA== dependencies: define-properties "^1.1.2" - es-abstract "^1.6.1" - function-bind "^1.1.0" + es-abstract "^1.11.0" + function-bind "^1.1.1" has "^1.0.1" object.omit@^2.0.0: @@ -4599,7 +6688,7 @@ on-headers@~1.0.1: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -4613,7 +6702,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opencollective-postinstall@^2.0.0: +opencollective-postinstall@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.1.tgz#798e83e168f7b91949061c2683f762af747f17cc" integrity sha512-saQQ9hjLwu/oS0492eyYotoh+bra1819cfAT5rjY/e4REWwuc8IgZ844Oo44SiftWcJuBiqp0SA0BFVbmLX0IQ== @@ -4650,7 +6739,7 @@ options@>=0.0.5: resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= -os-homedir@^1.0.0: +os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= @@ -4665,20 +6754,20 @@ os-locale@^2.0.0: mem "^1.1.0" os-locale@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" - integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - execa "^0.10.0" + execa "^1.0.0" lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: +osenv@0, osenv@^0.1.4, osenv@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -4718,9 +6807,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== dependencies: p-try "^2.0.0" @@ -4738,7 +6827,14 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" -p-map@^1.1.1: +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + +p-map@^1.1.1, p-map@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== @@ -4748,6 +6844,16 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== +p-pipe@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" + integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k= + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -4758,6 +6864,82 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== +p-waterfall@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-1.0.0.tgz#7ed94b3ceb3332782353af6aae11aa9fc235bb00" + integrity sha1-ftlLPOszMngjU69qrhGqn8I1uwA= + dependencies: + p-reduce "^1.0.0" + +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pacote@^9.2.3: + version "9.4.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.4.0.tgz#af979abdeb175cd347c3e33be3241af1ed254807" + integrity sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w== + dependencies: + bluebird "^3.5.3" + cacache "^11.3.2" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" + lru-cache "^5.1.1" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^2.2.3" + npm-registry-fetch "^3.8.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.8" + unique-filename "^1.1.1" + which "^1.3.1" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parent-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" + integrity sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA== + dependencies: + callsites "^3.0.0" + parents@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" @@ -4765,6 +6947,11 @@ parents@^1.0.1: dependencies: path-platform "~0.11.15" +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -4805,6 +6992,20 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= +patch-package@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-5.1.2.tgz#01753261026dbf6fb223cc0bbd2931a29da9dfc2" + integrity sha512-6NA7/hcAG/eZ6TcugOIkmRMA9wg/CVm+gyJpWJwc7Z8E0dkMeQwnVw5oDvhG+bEHBhsQLn+rF7PAx7p2QWnfNA== + dependencies: + chalk "^1.1.3" + cross-spawn "^5.1.0" + fs-extra "^4.0.1" + minimist "^1.2.0" + rimraf "^2.6.1" + slash "^1.0.0" + tmp "^0.0.31" + update-notifier "^2.2.0" + path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -4822,12 +7023,12 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.2: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -4837,7 +7038,7 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== @@ -4847,6 +7048,22 @@ path-platform@~0.11.15: resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I= +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -4854,17 +7071,19 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -pegjs@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" - integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -4893,13 +7112,6 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -4907,7 +7119,14 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -please-upgrade-node@^3.0.2: +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== @@ -4958,15 +7177,43 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= -prettier@^1.14.2: - version "1.15.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" - integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.15.3: + version "1.16.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.1.tgz#534c2c9d7853f8845e5e078384e71973bd74089f" + integrity sha512-XXUITwIkGb3CPJ2hforHah/zTINRyie5006Jd2HKy2qz7snEJXl0KLfsJZW/wst9g6R2rFvqba3VpNYdu1hDcA== + +pretty-format@24.0.0-alpha.4: + version "24.0.0-alpha.4" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.4.tgz#cc1f7497e2496b71f8ad99f1526096e515fada03" + integrity sha512-icvbBt3XlLEVqPHdHwR2Ou9+hezS9Eccd+mA+fXfOU7T9t7ClOpq2HgCwlyw+3WogccCubKWnmzyrA/3ZZ/aOA== + dependencies: + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + +pretty-format@24.0.0-alpha.6: + version "24.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz#25ad2fa46b342d6278bf241c5d2114d4376fbac1" + integrity sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA== + dependencies: + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" pretty-format@^23.6.0: version "23.6.0" @@ -4976,12 +7223,7 @@ pretty-format@^23.6.0: ansi-regex "^3.0.0" ansi-styles "^3.2.0" -pretty-format@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-4.3.1.tgz#530be5c42b3c05b36414a7a2a4337aa80acd0e8d" - integrity sha1-UwvlxCs8BbNkFKeipDN6qArNDo0= - -private@^0.1.6, private@^0.1.8: +private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -4997,9 +7239,27 @@ process@~0.5.1: integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= progress@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-polyfill@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" + integrity sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc= + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= + dependencies: + err-code "^1.0.0" + retry "^0.10.0" promise@^7.1.1: version "7.3.1" @@ -5008,7 +7268,14 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.8, prop-types@^15.6.2: +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + dependencies: + read "1" + +prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== @@ -5016,15 +7283,61 @@ prop-types@^15.5.8, prop-types@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" +proper-lockfile@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-3.2.0.tgz#89ca420eea1d55d38ca552578851460067bcda66" + integrity sha512-iMghHHXv2bsxl6NchhEaFck8tvX3F9cknEEh1SUpguUOBjN7PAAW9BLzmbc1g/mCD1gY3EE2EABBHPJfFdHFmA== + dependencies: + graceful-fs "^4.1.11" + retry "^0.12.0" + signal-exit "^3.0.2" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: - version "1.1.29" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" - integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" punycode@^1.4.1: version "1.4.1" @@ -5036,11 +7349,21 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + randomatic@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" @@ -5055,7 +7378,7 @@ range-parser@~1.2.0: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= -rc@^1.2.7: +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -5075,29 +7398,30 @@ react-deep-force-update@^1.0.0: resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1" integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA== -react-devtools-core@3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.3.4.tgz#9e497a94b73413b91774bf3e3197e539d5f9a21d" - integrity sha512-6lsBDRInT9jU8Ya8bnKWJSsnaGg/xk1ZSfvhc/dHc3n2CUTMfGlqm2tGeZQ9WEoe0Y2K7Lg90Kvb1E8anLePaQ== +react-devtools-core@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.0.tgz#77009517d72594fe6e2794f5ae160646d77fc467" + integrity sha512-picLP5RMESANerl2Ieo2rcMmVBqTG5QgIkSGcoJqvT5V4+HpLRjz5QW8xC85i+bXLdJmjoi3ZE9qDpNa5m7S4A== dependencies: shell-quote "^1.6.1" ws "^3.3.1" -react-dom@^16.5.0: - version "16.6.3" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.3.tgz#8fa7ba6883c85211b8da2d0efeffc9d3825cccc0" - integrity sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ== +react-dom@^16.6.3: + version "16.7.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" + integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.2" + scheduler "^0.12.0" -react-native@0.57.1: - version "0.57.1" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.57.1.tgz#a8bffeac13e200b95bbebd11f7131570902e1e74" - integrity sha512-d+bRxIFjCrvXVbvPhuyLvE8NSiYKzldBzL+sJjSGxNqOOb2UIjLfB1BGUkI3n3X7KAYEUp4KUhT7YfA2qsRi/w== +react-native@^0.58.1: + version "0.58.1" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.58.1.tgz#3cc0563d315d0fc605f6bae341fb952e119d31c3" + integrity sha512-8aD0PBTney5dKQ4MBOfBEcHmdm2OBCx/9gSbeT4OUXE54fNNmDfbkVnx7EZ1iwvEdOiAl+pEpWqgAb/tvhRwBA== dependencies: + "@babel/runtime" "^7.0.0" absolute-path "^0.0.0" art "^0.10.0" base64-js "^1.1.2" @@ -5112,17 +7436,18 @@ react-native@0.57.1: errorhandler "^1.5.0" escape-string-regexp "^1.0.5" event-target-shim "^1.0.5" - fbjs "0.8.17" - fbjs-scripts "^0.8.1" + fbjs "^1.0.0" + fbjs-scripts "^1.0.0" fs-extra "^1.0.0" glob "^7.1.1" graceful-fs "^4.1.3" inquirer "^3.0.6" lodash "^4.17.5" - metro "^0.45.6" - metro-babel-register "^0.45.6" - metro-core "^0.45.6" - metro-memory-fs "^0.45.6" + metro "^0.49.1" + metro-babel-register "^0.49.1" + metro-config "^0.49.1" + metro-core "^0.49.1" + metro-memory-fs "^0.49.1" mime "^1.3.4" minimist "^1.2.0" mkdirp "^0.5.1" @@ -5130,23 +7455,23 @@ react-native@0.57.1: node-fetch "^2.2.0" node-notifier "^5.2.1" npmlog "^2.0.4" + nullthrows "^1.1.0" opn "^3.0.2" optimist "^0.6.1" plist "^3.0.0" - pretty-format "^4.2.1" + pretty-format "24.0.0-alpha.4" promise "^7.1.1" prop-types "^15.5.8" react-clone-referenced-element "^1.0.1" - react-devtools-core "3.3.4" - react-timer-mixin "^0.13.2" + react-devtools-core "^3.4.0" regenerator-runtime "^0.11.0" rimraf "^2.5.4" semver "^5.0.3" serve-static "^1.13.1" shell-quote "1.6.1" stacktrace-parser "^0.1.3" - ws "^1.1.0" - xcode "^0.9.1" + ws "^1.1.5" + xcode "^1.0.0" xmldoc "^0.4.0" yargs "^9.0.0" @@ -5158,11 +7483,6 @@ react-proxy@^1.1.7: lodash "^4.6.1" react-deep-force-update "^1.0.0" -react-timer-mixin@^0.13.2: - version "0.13.4" - resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.4.tgz#75a00c3c94c13abe29b43d63b4c65a88fc8264d3" - integrity sha512-4+ow23tp/Tv7hBM5Az5/Be/eKKF7DIvJ09voz5LyHGQaqqz9WV8YMs31eFvcYQs7d451LSg7kDJV70XYN/Ug/Q== - react-transform-hmr@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" @@ -5171,15 +7491,53 @@ react-transform-hmr@^1.0.4: global "^4.3.0" react-proxy "^1.1.7" -react@^16.5.0: - version "16.6.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" - integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== +react@^16.6.3: + version "16.7.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" + integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.2" + scheduler "^0.12.0" + +read-cmd-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + integrity sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs= + dependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg== + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@^5.1.6: + version "5.2.1" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.1.tgz#6218b187d6fac82289ce4387bbbaf8eef536ad63" + integrity sha512-2CNoRoh95LxY47LvqrehIAfUVda2JbuFE/HaGYs42bNrGG+ojbw1h3zOcPcQ+1GQ3+rkzNndZn85u1XyZ3UsIA== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" read-pkg-up@^2.0.0: version "2.0.0" @@ -5189,6 +7547,31 @@ read-pkg-up@^2.0.0: 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" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.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" @@ -5198,7 +7581,32 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + +read@1, read@~1.0.1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -5211,6 +7619,16 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c= + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + readdirp@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5220,6 +7638,34 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +reflect-metadata@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -5270,29 +7716,51 @@ regexpp@^2.0.1: integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^4.1.3: - version "4.2.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" - integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== + version "4.4.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.4.0.tgz#8d43e0d1266883969720345e70c275ee0aec0d32" + integrity sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA== dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^7.0.0" - regjsgen "^0.4.0" - regjsparser "^0.3.0" + regjsgen "^0.5.0" + regjsparser "^0.6.0" unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.0.2" -regjsgen@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" - integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== +registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" -regjsparser@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" - integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== dependencies: jsesc "~0.5.0" +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + 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" @@ -5341,6 +7809,11 @@ request@^2.87.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +require-all@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312" + integrity sha1-Rz1JcEvjEBFc4ST3c4Ox69hnExI= + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5351,35 +7824,34 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + resolve-from "^3.0.0" resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== +resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" @@ -5394,18 +7866,35 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: - glob "^7.0.5" + glob "^7.1.3" rimraf@~2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" + integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= + dependencies: + glob "^6.0.1" + rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -5418,6 +7907,18 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + rx-lite-aggregates@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" @@ -5437,11 +7938,16 @@ rxjs@^6.1.0, rxjs@^6.3.3: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, 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" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-json-stringify@~1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -5454,14 +7960,15 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^2.0.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" - integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o= +sane@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-3.1.0.tgz#995193b7dc1445ef1fe41ddfca2faf9f111854c6" + integrity sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q== dependencies: anymatch "^2.0.0" capture-exit "^1.2.0" exec-sh "^0.2.0" + execa "^1.0.0" fb-watchman "^2.0.0" micromatch "^3.1.4" minimist "^1.1.1" @@ -5470,6 +7977,13 @@ sane@^2.0.0: optionalDependencies: fsevents "^1.2.3" +sanitize-filename@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" + integrity sha1-YS2hyWRz+gLczaktzVtKsWSmdyo= + dependencies: + truncate-utf8-bytes "^1.0.0" + sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -5480,10 +7994,10 @@ sax@~1.1.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" integrity sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA= -scheduler@^0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3" - integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg== +scheduler@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b" + integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -5493,11 +8007,23 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" @@ -5589,16 +8115,88 @@ shell-quote@1.6.1, shell-quote@^1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" +shell-utils@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/shell-utils/-/shell-utils-1.0.10.tgz#7fe7b8084f5d6d21323d941267013bc38aed063e" + integrity sha512-p1xuqhj3jgcXiV8wGoF1eL/NOvapN9tyGDoObqKwvZTUZn7fIzK75swLTEHfGa7sObeN9vxFplHw/zgYUYRTsg== + dependencies: + lodash "4.x.x" + +shelljs@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" + integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +should-equal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" + integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== + dependencies: + should-type "^1.4.0" + +should-format@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" + integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE= + dependencies: + should-type "^1.3.0" + should-type-adaptors "^1.0.1" + +should-sinon@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/should-sinon/-/should-sinon-0.0.6.tgz#be041a7c928f44ac9ccf5dc042d032618ce29f84" + integrity sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g== + +should-type-adaptors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" + integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== + dependencies: + should-type "^1.3.0" + should-util "^1.0.0" + +should-type@^1.3.0, should-type@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" + integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM= + +should-util@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063" + integrity sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM= + +should@^13.2.1, should@^13.2.3: + version "13.2.3" + resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" + integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== + dependencies: + should-equal "^2.0.0" + should-format "^3.0.3" + should-type "^1.4.0" + should-type-adaptors "^1.0.1" + should-util "^1.0.0" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-git@^1.85.0: + version "1.107.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" + integrity sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA== + dependencies: + debug "^4.0.1" + simple-plist@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-0.2.1.tgz#71766db352326928cf3a807242ba762322636723" @@ -5608,6 +8206,21 @@ simple-plist@^0.2.1: bplist-parser "0.1.1" plist "2.0.1" +sinon@^6.1.4, sinon@^6.2.0: + version "6.3.5" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-6.3.5.tgz#0f6d6a5b4ebaad1f6e8e019395542d1d02c144a0" + integrity sha512-xgoZ2gKjyVRcF08RrIQc+srnSyY1JDJtxu3Nsz07j1ffjgXoY6uPLf/qja6nDBZgzYYEovVkFryw2+KiZz11xQ== + dependencies: + "@sinonjs/commons" "^1.0.2" + "@sinonjs/formatio" "^3.0.0" + "@sinonjs/samsam" "^2.1.2" + diff "^3.5.0" + lodash.get "^4.4.2" + lolex "^2.7.5" + nise "^1.4.5" + supports-color "^5.5.0" + type-detect "^4.0.8" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -5632,11 +8245,16 @@ slice-ansi@2.0.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slide@^1.1.5: +slide@^1.1.5, slide@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= +smart-buffer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" + integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -5667,6 +8285,29 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +socks-proxy-agent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" + integrity sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw== + dependencies: + agent-base "~4.2.0" + socks "~2.2.0" + +socks@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b" + integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q== + dependencies: + ip "^1.1.5" + smart-buffer "^4.0.1" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + 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" @@ -5678,17 +8319,10 @@ source-map-resolve@^0.5.0: 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" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - source-map-support@^0.5.9: - version "0.5.9" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + version "0.5.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" + integrity sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -5698,20 +8332,37 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + spdx-correct@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" - integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -5730,9 +8381,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" - integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -5741,15 +8392,29 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" - integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== + version "1.16.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" + integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -5761,15 +8426,27 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +ssri@^6.0.0, ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stackframe@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" + integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw== + stacktrace-parser@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" integrity sha1-ATl5IuX2Ls8whFUiyVxP4dJefU4= -staged-git-files@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" - integrity sha512-H89UNKr1rQJvI1c/PIR3kiAMBV23yvR7LItZiV74HWZwzt7f3YHuujJ9nJZlt58WlFox7XQsOahexwk7nTe69A== +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== static-extend@^0.1.1: version "0.1.2" @@ -5799,6 +8476,19 @@ stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + string-argv@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" @@ -5837,6 +8527,11 @@ stringify-object@^3.2.2: is-obj "^1.0.1" is-regexp "^1.0.0" +stringify-package@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.0.tgz#e02828089333d7d45cd8c287c30aa9a13375081b" + integrity sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g== + 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" @@ -5858,6 +8553,13 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.0.0" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -5868,6 +8570,13 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" @@ -5878,39 +8587,64 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strong-log-transformer@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" + integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== + dependencies: + duplexer "^0.1.1" + minimist "^1.2.0" + through "^2.3.4" + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.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" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -symbol-observable@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" - integrity sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0= - symbol-observable@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== table@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" - integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== + version "5.2.1" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.1.tgz#e78463702b1be9f7131c39860bcfb1b81114c2a1" + integrity sha512-qmhNs2GEHNqY5fd2Mo+8N1r2sw/rvTAAvBZTaTx+Y7PHLypqyrxr1MdIu0pLw6Xvl/Gi4ONu/sdceP8vvUjkyA== dependencies: ajv "^6.6.1" lodash "^4.17.11" slice-ansi "2.0.0" string-width "^2.1.1" -tar@^4: +tail@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/tail/-/tail-1.4.0.tgz#884b216220b90804bfe87a4c8174c2efed0e2661" + integrity sha512-wjwfZw6wcMFTB1Po7NFUf4TdCDwX8duZjdTMhnHBEC677Q6mFRcVZE7f/nZDhG2Fpf/wEEKOJP9L7/b11/vlHQ== + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4, tar@^4.4.8: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== @@ -5923,6 +8657,30 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +telnet-client@0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-0.15.3.tgz#99ec754e4acf6fa51dc69898f574df3c2550712e" + integrity sha512-GSfdzQV0BKIYsmeXq7bJFJ2wHeJud6icaIxCUf6QCGQUD6R0BBGbT1+yLDhq67JRdgRpwyPwUbV7JxFeRrZomQ== + dependencies: + bluebird "3.5.x" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +temp-write@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" + integrity sha1-jP9jD7fp2gXwR8dM5M5NaFRX1JI= + dependencies: + graceful-fs "^4.1.2" + is-stream "^1.1.0" + make-dir "^1.0.0" + pify "^3.0.0" + temp-dir "^1.0.0" + uuid "^3.0.1" + temp@0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" @@ -5931,6 +8689,41 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +test-exclude@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7" + integrity sha512-bO3Lj5+qFa9YLfYW2ZcXMOV1pmQvw+KS/DpjqhyX6Y6UZ8zstpZJ+mA2ERkXfpOqhxsJlQiLeVXD3Smsrs6oLw== + dependencies: + arrify "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^1.0.1" + +text-encoding@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= + +text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -5941,7 +8734,7 @@ throat@^4.1.0: resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= -through2@^2.0.0: +through2@^2.0.0, through2@^2.0.2: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -5949,7 +8742,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6: +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -5959,6 +8752,23 @@ time-stamp@^1.0.0: resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +tinyqueue@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-1.2.3.tgz#b6a61de23060584da29f82362e45df1ec7353f3d" + integrity sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA== + +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + integrity sha1-jzirlDjhcxXl29izZX6L+yd65Kc= + dependencies: + os-tmpdir "~1.0.1" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -5971,11 +8781,6 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= -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" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -6014,16 +8819,137 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -tslib@^1.9.0: +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys= + dependencies: + utf8-byte-length "^1.0.1" + +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== + +tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslint-config-airbnb@^5.11.1: + version "5.11.1" + resolved "https://registry.yarnpkg.com/tslint-config-airbnb/-/tslint-config-airbnb-5.11.1.tgz#51a27fbb8bf24c144d064a274a71da47e7ece617" + integrity sha512-hkaittm2607vVMe8eotANGN1CimD5tor7uoY3ypg2VTtEcDB/KGWYbJOz58t8LI4cWSyWtgqYQ5F0HwKxxhlkQ== + dependencies: + tslint-consistent-codestyle "^1.14.1" + tslint-eslint-rules "^5.4.0" + tslint-microsoft-contrib "~5.2.1" + +tslint-config-prettier@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc" + integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw== + +tslint-consistent-codestyle@^1.14.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.15.0.tgz#a3acf8d0a3ca0dc7d1285705102ba1fe4a17c4cb" + integrity sha512-6BNDBbZh2K0ibRXe70Mkl9gfVttxQ3t3hqV1BRDfpIcjrUoOgD946iH4SrXp+IggDgeMs3dJORjD5tqL5j4jXg== + dependencies: + "@fimbul/bifrost" "^0.17.0" + tslib "^1.7.1" + tsutils "^2.29.0" + +tslint-eslint-rules@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" + integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== + dependencies: + doctrine "0.7.2" + tslib "1.9.0" + tsutils "^3.0.0" + +tslint-microsoft-contrib@~5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.2.1.tgz#a6286839f800e2591d041ea2800c77487844ad81" + integrity sha512-PDYjvpo0gN9IfMULwKk0KpVOPMhU6cNoT9VwCOLeDl/QS8v8W2yspRpFFuUS7/c5EIH/n8ApMi8TxJAz1tfFUA== + dependencies: + tsutils "^2.27.2 <2.29.0" + +tslint-plugin-prettier@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tslint-plugin-prettier/-/tslint-plugin-prettier-2.0.1.tgz#95b6a3b766622ffc44375825d7760225c50c3680" + integrity sha512-4FX9JIx/1rKHIPJNfMb+ooX1gPk5Vg3vNi7+dyFYpLO+O57F4g+b/fo1+W/G0SUOkBLHB/YKScxjX/P+7ZT/Tw== + dependencies: + eslint-plugin-prettier "^2.2.0" + lines-and-columns "^1.1.6" + tslib "^1.7.1" + +tslint@^5.12.1: + version "5.12.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.1.tgz#8cec9d454cf8a1de9b0a26d7bdbad6de362e52c1" + integrity sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw== + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@^2.27.2, tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +"tsutils@^2.27.2 <2.29.0": + version "2.28.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" + integrity sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA== + dependencies: + tslib "^1.8.1" + +tsutils@^3.0.0, tsutils@^3.5.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.7.0.tgz#f97bdd2f109070bd1865467183e015b25734b477" + integrity sha512-n+e+3q7Jx2kfZw7tjfI9axEIWBY0sFMOlC+1K70X0SeXpO/UYSB+PN+E9tIJNqViB7oiXQdqD7dNchnvoneZew== + dependencies: + tslib "^1.8.1" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -6043,15 +8969,48 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8, type-detect@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.0.3: - version "3.2.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.1.tgz#0b7a04b8cf3868188de914d9568bd030f0c56192" - integrity sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg== +typedoc-default-themes@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" + integrity sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic= + +typedoc@^0.14.1: + version "0.14.2" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.14.2.tgz#769f457f4f9e4bdb8b5f3b177c86b6a31d8c3dc3" + integrity sha512-aEbgJXV8/KqaVhcedT7xG6d2r+mOvB5ep3eIz1KuB5sc4fDYXcepEEMdU7XSqLFO5hVPu0nllHi1QxX2h/QlpQ== + dependencies: + "@types/fs-extra" "^5.0.3" + "@types/handlebars" "^4.0.38" + "@types/highlight.js" "^9.12.3" + "@types/lodash" "^4.14.110" + "@types/marked" "^0.4.0" + "@types/minimatch" "3.0.3" + "@types/shelljs" "^0.8.0" + fs-extra "^7.0.0" + handlebars "^4.0.6" + highlight.js "^9.13.1" + lodash "^4.17.10" + marked "^0.4.0" + minimatch "^3.0.0" + progress "^2.0.0" + shelljs "^0.8.2" + typedoc-default-themes "^0.5.0" + typescript "3.2.x" + +typescript@3.2.x, typescript@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" + integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== ua-parser-js@^0.7.18: version "0.7.19" @@ -6066,6 +9025,19 @@ uglify-es@^3.1.9: commander "~2.13.0" source-map "~0.6.1" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + ultron@1.0.x: version "1.0.2" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" @@ -6076,6 +9048,11 @@ ultron@~1.1.0: resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== +umask@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -6109,6 +9086,27 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -6127,11 +9125,32 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +update-notifier@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -6144,6 +9163,13 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + urlgrey@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" @@ -6154,6 +9180,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E= + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -6164,17 +9195,12 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" - integrity sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE= - -uuid@^3.3.2: +uuid@^3.0.1, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -validate-npm-package-license@^3.0.1: +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -6182,6 +9208,13 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -6211,17 +9244,38 @@ watch@~0.18.0: exec-sh "^0.2.0" minimist "^1.2.0" +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + whatwg-fetch@>=0.10.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.10, which@^1.2.9, which@^1.3.0: +which@1, which@^1.2.10, which@^1.2.9, which@^1.3.0, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -6235,6 +9289,13 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -6275,6 +9336,35 @@ write-file-atomic@^1.2.0: imurmurhash "^0.1.4" slide "^1.1.5" +write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0, write-json-file@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -6282,7 +9372,7 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^1.1.0: +ws@^1.1.0, ws@^1.1.1, ws@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w== @@ -6299,14 +9389,25 @@ ws@^3.3.1: safe-buffer "~5.1.0" ultron "~1.1.0" -xcode@^0.9.1: - version "0.9.3" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-0.9.3.tgz#910a89c16aee6cc0b42ca805a6d0b4cf87211cf3" - integrity sha1-kQqJwWrubMC0LKgFptC0z4chHPM= +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + +xcode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-1.1.0.tgz#9fcb63f417a9af377bfb743a5c22afce4e1da964" + integrity sha512-hllHFtfsNu5WbVzj8KbGNdI3NgOYmTLZqyF4a9c9J1aGMhAdxmLLsXlpG0Bz8fEtKh6I3pyargRXN0ZlLpcF5w== dependencies: - pegjs "^0.10.0" simple-plist "^0.2.1" - uuid "3.0.1" + uuid "^3.3.2" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= xmlbuilder@8.2.2: version "8.2.2" @@ -6345,7 +9446,7 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= -"y18n@^3.2.1 || ^4.0.0": +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== @@ -6375,6 +9476,31 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^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 "^9.0.2" + yargs@^12.0.1: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"

+ +
+
+