Replace react-native-fcm by react-native-firebase

parent c70bf244
......@@ -2,7 +2,6 @@ import { select } from 'redux-saga/effects';
import { expectSaga } from 'redux-saga-test-plan';
import * as matchers from 'redux-saga-test-plan/matchers';
import { Platform } from 'react-native';
import FCM from 'react-native-fcm';
import pushNotificationsSaga from '../../app/sagas/pushNotifications';
import { apiRequest, tokenSelector } from '../../app/utils/url';
import * as pushActions from '../../app/actions/pushNotifications';
......@@ -12,22 +11,31 @@ jest.mock('../../app/utils/url', () => ({
tokenSelector: () => 'token',
}));
jest.mock('react-native-fcm', () => ({
getFCMToken: jest.fn(),
requestPermissions: jest.fn(),
deleteInstanceId: jest.fn(),
const mockIid = {
delete: jest.fn(),
};
const mockMessaging = {
hasPermission: jest.fn(),
getToken: jest.fn(),
requestPermission: jest.fn(),
};
jest.mock('react-native-firebase', () => ({
iid: () => mockIid,
messaging: () => mockMessaging,
}));
describe('pushNotifications saga', () => {
beforeAll(() => {
FCM.getFCMToken.mockReturnValue('token');
mockMessaging.getToken.mockReturnValue('token');
});
describe('register', () => {
beforeEach(() => {
Platform.OS = 'ios';
FCM.requestPermissions.mockReset();
FCM.getFCMToken.mockReset();
mockMessaging.requestPermission.mockReset();
mockMessaging.getToken.mockReset();
apiRequest.mockReset();
});
......@@ -38,7 +46,7 @@ describe('pushNotifications saga', () => {
.dispatch(pushActions.register())
.silentRun()
.then(() => {
expect(FCM.requestPermissions).toBeCalled();
expect(mockMessaging.requestPermission).toBeCalled();
}));
it('should not request permissions when platform is Android', () => {
......@@ -50,31 +58,29 @@ describe('pushNotifications saga', () => {
.dispatch(pushActions.register())
.silentRun()
.then(() => {
expect(FCM.requestPermissions).not.toBeCalled();
expect(mockMessaging.requestPermission).not.toBeCalled();
});
});
it('should post a token to the server', () => {
return expectSaga(pushNotificationsSaga)
.provide([
[select(tokenSelector), 'token'],
[matchers.call.like({ fn: apiRequest, args: ['events'] }), { results: 'data' }],
])
.dispatch(pushActions.register())
.silentRun()
.then(() => {
expect(apiRequest).toBeCalledWith('devices',
{
body: '{"type":"ios"}',
headers: {
Accept: 'application/json',
Authorization: 'Token token',
'Content-Type': 'application/json',
},
method: 'POST',
});
});
});
it('should post a token to the server', () => expectSaga(pushNotificationsSaga)
.provide([
[select(tokenSelector), 'token'],
[matchers.call.like({ fn: apiRequest, args: ['events'] }), { results: 'data' }],
])
.dispatch(pushActions.register())
.silentRun()
.then(() => {
expect(apiRequest).toBeCalledWith('devices',
{
body: '{"type":"ios"}',
headers: {
Accept: 'application/json',
Authorization: 'Token token',
'Content-Type': 'application/json',
},
method: 'POST',
});
}));
});
describe('invalidate', () => {
......@@ -82,7 +88,7 @@ describe('pushNotifications saga', () => {
.dispatch(pushActions.invalidate())
.silentRun()
.then(() => {
expect(FCM.deleteInstanceId).toBeCalled();
expect(mockIid.delete).toBeCalled();
}));
});
});
import { NativeModules } from 'react-native';
NativeModules.RNFirebase = {
apps: [],
};
......@@ -152,12 +152,13 @@ dependencies {
implementation project(':react-native-vector-icons')
implementation project(':react-native-snackbar')
implementation project(':react-native-linear-gradient')
implementation project(':react-native-fcm')
implementation project(':react-native-firebase')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'com.google.firebase:firebase-core:11.4.0'
implementation "com.google.firebase:firebase-core:16.0.1"
implementation "com.google.firebase:firebase-messaging:17.1.0"
}
// Run this once to be able to run the application with BUCK
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.thaliapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22"/>
<application
android:name=".MainApplication"
......@@ -12,7 +11,8 @@
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:launchMode="singleTop">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
......@@ -34,18 +34,21 @@
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<service android:name="com.evollu.react.fcm.MessagingService" android:enabled="true" android:exported="true">
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/magenta" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification" />
......
......@@ -3,10 +3,14 @@ package com.thaliapp;
import android.app.Application;
import com.facebook.react.ReactApplication;
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
import io.invertase.firebase.instanceid.RNFirebaseInstanceIdPackage;
import io.sentry.RNSentryPackage;
import com.azendoo.reactnativesnackbar.SnackbarPackage;
import com.i18n.reactnativei18n.ReactNativeI18n;
import com.evollu.react.fcm.FIRMessagingPackage;
import com.BV.LinearGradient.LinearGradientPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.facebook.react.ReactNativeHost;
......@@ -27,12 +31,15 @@ public class MainApplication extends Application implements ReactApplication {
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
return Arrays.asList(
new MainReactPackage(),
new RNSentryPackage(),
new SnackbarPackage(),
new ReactNativeI18n(),
new FIRMessagingPackage(),
new RNFirebasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebaseNotificationsPackage(),
new RNFirebaseInstanceIdPackage(),
new LinearGradientPackage(),
new VectorIconsPackage()
);
......
......@@ -2,15 +2,12 @@
buildscript {
repositories {
maven {
url 'https://maven.google.com/'
name 'Google'
}
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.google.gms:google-services:3.2.0'
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.google.gms:google-services:4.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......@@ -19,23 +16,13 @@ buildscript {
allprojects {
repositories {
maven {
url "https://maven.google.com" // Google's Maven repository
}
google()
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
configurations.all {
resolutionStrategy {
// Fixes https://github.com/evollu/react-native-fcm/issues/857#issuecomment-375243825
force 'com.google.firebase:firebase-messaging:11.4.0'
force 'com.google.firebase:firebase-core:11.4.0'
force 'com.google.android.gms:play-services-gcm:11.4.0'
}
}
}
}
......
......@@ -5,8 +5,8 @@ include ':react-native-snackbar'
project(':react-native-snackbar').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-snackbar/android')
include ':react-native-locale-detector'
project(':react-native-locale-detector').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-locale-detector/android')
include ':react-native-fcm'
project(':react-native-fcm').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fcm/android')
include ':react-native-firebase'
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')
include ':react-native-linear-gradient'
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
include ':react-native-vector-icons'
......
import React, { Component } from 'react';
import { Linking, Platform, NativeModules } from 'react-native';
import {
Linking, Platform, NativeModules, Alert,
} from 'react-native';
import { applyMiddleware, createStore } from 'redux';
import { Provider } from 'react-redux';
import { I18nextProvider } from 'react-i18next';
import createSagaMiddleware from 'redux-saga';
import FCM, { FCMEvent } from 'react-native-fcm';
import firebase from 'react-native-firebase';
import locale from 'react-native-locale-detector';
import Moment from 'moment';
import 'moment/locale/nl';
......@@ -29,24 +31,6 @@ const sagaMiddleware = createSagaMiddleware();
const store = createStore(reducers, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(sagas);
FCM.on(FCMEvent.Notification, async (notif) => {
if (notif.fcm) {
FCM.presentLocalNotification({
title: notif.fcm.title,
body: notif.fcm.body,
color: notif.fcm.color,
icon: notif.fcm.icon === null ? 'ic_notification' : notif.fcm.icon,
action: notif.fcm.action,
tag: notif.fcm.tag,
show_in_foreground: true,
});
}
});
FCM.on(FCMEvent.RefreshToken, async () => {
store.dispatch(register());
});
class Main extends Component {
constructor() {
super();
......@@ -60,9 +44,19 @@ class Main extends Component {
componentDidMount() {
store.dispatch(sessionActions.init());
this.addDeepLinkingHandler();
this.onTokenRefreshListener = firebase.messaging().onTokenRefresh(() => {
store.dispatch(register());
});
this.notificationListener = firebase.notifications().onNotification((notification) => {
Alert.alert(notification.title, notification.body, [
{ text: 'OK' },
]);
});
}
componentWillUnmount() {
this.notificationListener();
this.onTokenRefreshListener();
Linking.removeEventListener('url', this.handleOpenURL);
}
......
import { call, takeEvery, select } from 'redux-saga/effects';
import { Platform } from 'react-native';
import FCM from 'react-native-fcm';
import firebase from 'react-native-firebase';
import { Sentry } from 'react-native-sentry';
import { apiRequest, tokenSelector } from '../utils/url';
import * as pushNotificationsActions from '../actions/pushNotifications';
const register = function* register(action) {
const messaging = firebase.messaging();
const token = yield select(tokenSelector);
const { categories } = action;
......@@ -15,18 +16,20 @@ const register = function* register(action) {
return;
}
const hasPermission = yield call([messaging, 'hasPermission']);
let pushToken;
if (Platform.OS === 'ios') {
if (Platform.OS === 'ios' && !hasPermission) {
try {
// this throws an error when the permissions are denied
yield call(FCM.requestPermissions);
pushToken = yield call(FCM.getFCMToken);
yield call([messaging, 'requestPermission']);
pushToken = yield call([messaging, 'getToken']);
} catch (err) {
// return and do nothing since we have no token
return;
}
} else {
pushToken = yield call(FCM.getFCMToken);
pushToken = yield call([messaging, 'getToken']);
}
const body = {
......@@ -57,7 +60,7 @@ const register = function* register(action) {
};
const invalidate = function* invalidate() {
yield call(FCM.deleteInstanceId);
yield call([firebase.iid(), 'delete']);
};
const pushNotificationsSaga = function* pushNotificationsSaga() {
......
......@@ -22,13 +22,11 @@ const pairsToObject = (obj, pair) => {
return obj2;
};
const getStoredItems = () => AsyncStorage.multiGet([
USERNAMEKEY, TOKENKEY, DISPLAYNAMEKEY, PHOTOKEY, PUSHCATEGORYKEY,
]);
function* init() {
try {
const result = yield call(getStoredItems);
const result = yield call([AsyncStorage, 'multiGet'], [
USERNAMEKEY, TOKENKEY, DISPLAYNAMEKEY, PHOTOKEY, PUSHCATEGORYKEY,
]);
const values = result.reduce(pairsToObject, {});
const username = values[USERNAMEKEY];
......
......@@ -6,8 +6,8 @@ target 'ThaliApp' do
# use_frameworks!
# Pods for ThaliApp
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'Firebase/Core', '~> 5.3.0'
pod 'Firebase/Messaging', '~> 5.3.0'
target 'ThaliAppTests' do
inherit! :search_paths
......
PODS:
- Firebase/Core (4.8.0):
- FirebaseAnalytics (= 4.0.5)
- FirebaseCore (= 4.0.13)
- Firebase/Messaging (4.8.0):
- Firebase/Core
- FirebaseMessaging (= 2.0.8)
- FirebaseAnalytics (4.0.5):
- FirebaseCore (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- Firebase/Core (5.3.0):
- Firebase/CoreOnly
- FirebaseAnalytics (= 5.0.1)
- Firebase/CoreOnly (5.3.0):
- FirebaseCore (= 5.0.4)
- Firebase/Messaging (5.3.0):
- Firebase/CoreOnly
- FirebaseMessaging (= 3.0.2)
- FirebaseAnalytics (5.0.1):
- FirebaseCore (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- nanopb (~> 0.3)
- FirebaseCore (4.0.13):
- FirebaseCore (5.0.4):
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- FirebaseInstanceID (2.0.8):
- FirebaseCore (~> 4.0)
- FirebaseMessaging (2.0.8):
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- FirebaseInstanceID (3.1.1):
- FirebaseCore (~> 5.0)
- FirebaseMessaging (3.0.2):
- FirebaseCore (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- Protobuf (~> 3.1)
- GoogleToolboxForMac/Defines (2.1.3)
- GoogleToolboxForMac/Logger (2.1.3):
- GoogleToolboxForMac/Defines (= 2.1.3)
- "GoogleToolboxForMac/NSData+zlib (2.1.3)":
- GoogleToolboxForMac/Defines (= 2.1.3)
- GoogleToolboxForMac/Defines (2.1.4)
- GoogleToolboxForMac/Logger (2.1.4):
- GoogleToolboxForMac/Defines (= 2.1.4)
- "GoogleToolboxForMac/NSData+zlib (2.1.4)":
- GoogleToolboxForMac/Defines (= 2.1.4)
- nanopb (0.3.8):
- nanopb/decode (= 0.3.8)
- nanopb/encode (= 0.3.8)
- nanopb/decode (0.3.8)
- nanopb/encode (0.3.8)
- Protobuf (3.5.0)
- Protobuf (3.6.0)
DEPENDENCIES:
- Firebase/Core
- Firebase/Messaging
- Firebase/Core (~> 5.3.0)
- Firebase/Messaging (~> 5.3.0)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
......@@ -48,15 +49,15 @@ SPEC REPOS:
- Protobuf
SPEC CHECKSUMS:
Firebase: 710decbbc6d9d48530e9a5dba3209740c3532e05
FirebaseAnalytics: 5b02a63ead2c3f0259cfc7f15e053e440587ecf8
FirebaseCore: 3c02ec652db3d03fdc8bc6d9154af3e20d64b6f5
FirebaseInstanceID: 81df5805a08001e69138664bdd02c6719a9ac80f
FirebaseMessaging: dfdcd307c2382290a1e297a81d0f18370f5b1bcd
GoogleToolboxForMac: 2501e2ad72a52eb3dfe7bd9aee7dad11b858bd20
Firebase: 68afeeb05461db02d7c9e3215cda28068670f4aa
FirebaseAnalytics: b3628aea54c50464c32c393fb2ea032566e7ecc2
FirebaseCore: 62f1b792a49bb9e8b4073f24606d2c93ffc352f0
FirebaseInstanceID: f3f0657372592ecdfdfe2cac604a5a75758376a6
FirebaseMessaging: 6894b8fe0a0cf26c3b13dad729f1131654ae0bdb
GoogleToolboxForMac: 91c824d21e85b31c2aae9bb011c5027c9b4e738f
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
Protobuf: 8a9838fba8dae3389230e1b7f8c104aa32389c03
Protobuf: 0fc0ad8bec688b2a3017a139953e01374fedbd5f
PODFILE CHECKSUM: 81d414439f1f341b58c306e954d202374221992d
PODFILE CHECKSUM: 940ed21b3453ddbab84e4d5d26bc938a052d9f59
COCOAPODS: 1.5.3
This diff is collapsed.
......@@ -7,19 +7,22 @@
#import "AppDelegate.h"
#import <Firebase.h>
#import "RNFirebaseNotifications.h"
#import "RNFirebaseMessaging.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RNSentry.h>
#import <React/RCTLinkingManager.h>
#import "RNFIRMessaging.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
[RNFirebaseNotifications configure];
NSURL *jsCodeLocation;
......@@ -58,32 +61,19 @@ RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
return YES;
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
[RNFIRMessaging willPresentNotification:notification withCompletionHandler:completionHandler];
}
#if defined(__IPHONE_11_0)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
[RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
#else
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler
{
[RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
#endif
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[RNFIRMessaging didReceiveLocalNotification:notification];
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[RNFIRMessaging didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
......
......@@ -30,6 +30,12 @@
"modulePaths": [
".yarn/"
],
"setupFiles": [
"<rootDir>/__tests__/setup.js"
],
"testPathIgnorePatterns": [
"<rootDir>/__tests__/setup.js"
],
"transform": {
"^.+\\.js$": "<rootDir>/jest/preprocessor.js"
},
......@@ -50,7 +56,7 @@
"react-native": "0.56.0",
"react-native-dotenv": "^0.2.0",
"react-native-drawer": "^2.3.0",
"react-native-fcm": "^16.0.0",
"react-native-firebase": "5.0.0-rc0",
"react-native-linear-gradient": "^2.4.0",
"react-native-locale-detector": "^1.0.1",
"react-native-render-html": "^3.10.0",
......
......@@ -1416,6 +1416,14 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
babel-polyfill@6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
dependencies:
babel-runtime "^6.22.0"
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
babel-preset-es2015-node@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz#60b23157024b0cfebf3a63554cb05ee035b4e55f"
......@@ -1751,7 +1759,7 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
......@@ -2650,7 +2658,7 @@ extend@^3.0.0, extend@~3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
external-editor@^2.0.4, external-editor@^2.1.0:
external-editor@^2.0.1, external-editor@^2.0.4, external-editor@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
dependencies:
......@@ -3352,6 +3360,24 @@ ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
inquirer@3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347"
dependencies:
ansi-escapes "^1.1.0"
chalk "^1.0.0"
cli-cursor "^2.1.0"
cli-width "^2.0.0"
external-editor "^2.0.1"
figures "^2.0.0"
lodash "^4.3.0"
mute-stream "0.0.7"
run-async "^2.2.0"
rx "^4.1.0"
string-width "^2.0.0"
strip-ansi "^3.0.0"
through "^2.3.6"