diff --git a/package.json b/package.json index 6805923..54b9764 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "axios": "0.18.0", + "formik": "^1.5.8", "prop-types": "15.7.2", "react": "16.8.3", "react-native": "0.59.8", @@ -22,12 +23,12 @@ "react-native-size-matters": "0.2.1", "react-navigation": "3.11.0", "react-navigation-redux-helpers": "3.0.2", - "react-redux": "5.0.7", - "redux": "4.0.0", - "redux-act": "1.7.4", - "redux-form": "7.4.2", - "redux-persist": "5.10.0", - "redux-saga": "1.0.2" + "react-redux": "7.1.1", + "redux": "4.0.4", + "redux-act": "1.7.7", + "redux-persist": "6.0.0", + "redux-saga": "1.1.1", + "yup": "^0.27.0" }, "devDependencies": { "@babel/core": "^7.4.4", diff --git a/src/App.js b/src/App.js index ef629d0..fc75e96 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; -import { PersistGate } from 'redux-persist/lib/integration/react'; +import { PersistGate } from 'redux-persist/integration/react'; import { Provider } from 'react-redux'; - +import ApiProvider from './utils/apiProvider'; import store, { persistor } from './redux'; import RootNavigator from './navigation'; @@ -14,7 +14,9 @@ export default class App extends Component { persistor={persistor} loading={null} > - + + + ); diff --git a/src/components/AuthFormInput/index.js b/src/components/AuthFormInput/index.js index 5ab6ad1..695dcdd 100644 --- a/src/components/AuthFormInput/index.js +++ b/src/components/AuthFormInput/index.js @@ -9,57 +9,64 @@ import styles from './styles'; const FormInput = (props) => { const { - input, containerStyle, inputContainerStyle, - meta: { error, touched }, inlineImage, + name, + handleChange, + handleBlur, + errors, + touched, + value, ...inputProps } = props; + const hasError = touched[name] && errors[name]; + const renderError = () => { - if (touched && error) { - return {error}; + if (hasError) { + return {errors[name]}; } return null; }; + return ( - { - renderError() - } + {renderError()} ); }; FormInput.propTypes = { + ...DefaultInput.propTypes, input: PropTypes.object, containerStyle: PropTypes.any, - meta: PropTypes.shape({ - touched: PropTypes.bool, - error: PropTypes.any, - }), inlineImage: PropTypes.any, inputContainerStyle: PropTypes.any, + name: PropTypes.string.isRequired, + handleChange: PropTypes.func, + handleBlur: PropTypes.func, + errors: PropTypes.object, + touched: PropTypes.object, + value: DefaultInput.propTypes.value, }; export default FormInput; diff --git a/src/components/DefaultInput/index.js b/src/components/DefaultInput/index.js index 24deb77..7272de6 100644 --- a/src/components/DefaultInput/index.js +++ b/src/components/DefaultInput/index.js @@ -18,7 +18,8 @@ const DefaultInput = ({ inputRef, style, ...rest }) => ( ); DefaultInput.propTypes = { - inputRef: PropTypes.func, + ...TextInput.propTypes, + inputRef: PropTypes.any, style: PropTypes.any, }; diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 71b0fb0..701543f 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -4,4 +4,4 @@ export const SIGN_IN_ENDPOINT = ''; export const SIGN_UP_ENDPOINT = ''; export const TEST_AUTH_ENDPOINT = ''; -export const REFRESH_ACCESS_TOKEN_ENPOINT = ''; +export const REFRESH_ACCESS_TOKEN_ENDPOINT = ''; diff --git a/src/redux/index.js b/src/redux/index.js index 84e9ba9..d8899ba 100644 --- a/src/redux/index.js +++ b/src/redux/index.js @@ -1,8 +1,8 @@ +import { AsyncStorage } from 'react-native'; import { createStore, applyMiddleware, compose } from 'redux'; import createSagaMiddleware from 'redux-saga'; import { persistStore, persistReducer } from 'redux-persist'; -import storage from 'redux-persist/lib/storage'; import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2'; import { navigationMiddleware } from '../navigation'; @@ -17,7 +17,7 @@ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const persistConfig = { key: 'root', - storage, + storage: AsyncStorage, stateReconciler: autoMergeLevel2, blacklist: ['nav', 'form'], whitelist: ['auth'], diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js index 7b654da..f693963 100644 --- a/src/redux/reducers/index.js +++ b/src/redux/reducers/index.js @@ -1,10 +1,8 @@ import { combineReducers } from 'redux'; -import { reducer as form } from 'redux-form'; import nav from '../../navigation/reducer'; import auth from './auth'; const reducer = combineReducers({ - form, nav, auth, }); diff --git a/src/redux/sagas/api.js b/src/redux/sagas/api.js index 921af34..b0bec84 100644 --- a/src/redux/sagas/api.js +++ b/src/redux/sagas/api.js @@ -1,15 +1,11 @@ -import { put as sagaPut, call, select } from 'redux-saga/effects'; +import { call } from 'redux-saga/effects'; import api, { setAuthHeader, resetAuthHeader } from '../../utils/axios'; -import { REFRESH_ACCESS_TOKEN_ENPOINT } from '../../constants/endpoints'; -import * as actions from '../actions'; - -const getRefreshToken = state => state.auth.refreshToken; export function* get(endpoint, options) { try { return yield call(api.get, endpoint, options || {}); } catch (error) { - return yield call(checkForTokenError, error, retryRequest, 'accessToken'); + throw error; } } @@ -17,7 +13,7 @@ export function* post(endpoint, data, options) { try { return yield call(api.post, endpoint, data, options || {}); } catch (error) { - return yield call(checkForTokenError, error, retryRequest, 'accessToken'); + throw error; } } @@ -25,57 +21,8 @@ export function* put(endpoint, data, options) { try { return yield call(api.put, endpoint, data, options || {}); } catch (error) { - return yield call(checkForTokenError, error, retryRequest, 'accessToken'); - } -} - -function* retryRequest(error) { - const newToken = yield call(refreshAccessToken); - const newError = { ...error }; - newError.config.headers.Authorization = `Bearer ${newToken}`; - return yield call(api.request, newError.config); -} - -function* checkForTokenError(error, onAccessTokeErrorCallback, paramToCheck) { - if (error.response) { - const accessTokenError = error.response.data.find(e => e.param === paramToCheck); - if (accessTokenError) { - return yield call(onAccessTokeErrorCallback, error); - } - throw error; - } else if (error.request) { - throw createSimpleErrorObject('Server does not respond'); } - - throw createSimpleErrorObject('Please, check your internet connection'); -} - -function* refreshAccessToken() { - try { - const refreshToken = yield select(getRefreshToken); - const response = yield call(api.post, REFRESH_ACCESS_TOKEN_ENPOINT, { refreshToken }); - setAuthHeader(response.data.accessToken); - yield sagaPut(actions.accessTokenUpdatedAction(response.data)); - return response.data.accessToken; - } catch (error) { - return yield call(checkForTokenError, error, onRefreshTokenError, 'refreshToken'); - } -} - -function* onRefreshTokenError(error) { - yield sagaPut(actions.signOutAction()); - throw error; -} - -function createSimpleErrorObject(error) { - return { - response: { - data: { - _error: error, - }, - }, - }; } export { resetAuthHeader, setAuthHeader }; diff --git a/src/screens/Root.js b/src/screens/Root.js index a424906..10d6234 100644 --- a/src/screens/Root.js +++ b/src/screens/Root.js @@ -1,28 +1,25 @@ -import { Component } from 'react'; +import { useEffect } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { testAuthAction } from '../redux/actions'; -@connect(null, ({ - testAuth: testAuthAction, -})) -class Root extends Component { - static navigationOptions = { - header: null, - } +const Root = ({ testAuth }) => { + useEffect(() => { + testAuth(); + }, []); - static propTypes = { - testAuth: PropTypes.func, - }; + return null; +}; - componentDidMount() { - this.props.testAuth(); - } +Root.navigationOptions = { + header: null, +}; - render() { - return null; - } -} +Root.propTypes = { + testAuth: PropTypes.func, +}; -export default Root; +export default connect(null, ({ + testAuth: testAuthAction, +}))(Root); diff --git a/src/screens/SignInScreen/FormProvider.js b/src/screens/SignInScreen/FormProvider.js new file mode 100644 index 0000000..68f227a --- /dev/null +++ b/src/screens/SignInScreen/FormProvider.js @@ -0,0 +1,45 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Formik } from 'formik'; +import { object, string } from 'yup'; + +const SignInSchema = object().shape({ + email: string() + .email('Invalid email') + .required('Required'), + password: string().required('Required'), +}); + +const INITIAL_SIGN_IN_VALUES = { + email: '', + password: '', +}; + +const FormProvider = ({ children, onSubmit }) => { + /* :: (object, object) -> Promise */ + const handleSignIn = async (formData, actions) => { + try { + onSubmit(formData); + } catch (error) { + actions.resetForm(); + actions.setFieldValue('email', formData.email); + } + }; + + return ( + + {children} + + ); +}; + +FormProvider.propTypes = { + onSubmit: PropTypes.func.isRequired, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired, +}; + +export default FormProvider; diff --git a/src/screens/SignInScreen/SignIn.js b/src/screens/SignInScreen/SignIn.js index 5073523..dd51af3 100644 --- a/src/screens/SignInScreen/SignIn.js +++ b/src/screens/SignInScreen/SignIn.js @@ -1,29 +1,14 @@ -import React, { Component } from 'react'; -import { View, Keyboard } from 'react-native'; -import { reduxForm, Field } from 'redux-form'; +import React, { useRef } from 'react'; +import { View } from 'react-native'; import PropTypes from 'prop-types'; - import KeyboardAvoidingWrapper from '../../components/KeyboardAvoidingWrapper'; import FormInput from '../../components/AuthFormInput'; import DefaultButton from '../../components/DefaultButton'; import DefaultText from '../../components/DefaultText'; - -import validate from '../../validators/auth-validator'; import styles from './styles'; -@reduxForm({ form: 'signin', validate }) -export default class SignIn extends Component { - static propTypes = { - onGoToSignUpPress: PropTypes.func, - handleSubmit: PropTypes.func, - }; - - handleSubmit = (data) => { - Keyboard.dismiss(); - this.props.handleSubmit(data); - } - - renderTitle = () => ( +const SignIn = ({ handleSubmit, values, ...props }) => { + const renderTitle = () => ( ); - render() { - const { - onGoToSignUpPress, - } = this.props; + const passwordRef = useRef(null); + + return ( + + + { renderTitle() } + passwordRef.current.focus()} + keyboardType='email-address' + maxLength={40} + value={values.email} + {...props} + /> + + + + + ); +}; + +SignIn.propTypes = { + handleSubmit: PropTypes.func, + values: PropTypes.object, +}; - return ( - - - { this.renderTitle() } - this.passwordRef.focus()} - keyboardType='email-address' - maxLength={40} - /> - { this.passwordRef = ref; }} - secureTextEntry - onSubmitEditing={this.handleSubmit} - maxLength={20} - /> - - - - ); - } -} +export default SignIn; diff --git a/src/screens/SignInScreen/index.js b/src/screens/SignInScreen/index.js index 696aae5..6828069 100644 --- a/src/screens/SignInScreen/index.js +++ b/src/screens/SignInScreen/index.js @@ -1,31 +1,35 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { Keyboard } from 'react-native'; +import FormProvider from './FormProvider'; import SignIn from './SignIn'; import { signInAction } from '../../redux/actions'; -@connect(null, ({ - signIn: signInAction, -})) -class LoginScreen extends Component { - static propTypes = { - navigation: PropTypes.object, - signIn: PropTypes.func, +const LoginScreen = ({ signIn, navigation }) => { + const handleSubmit = (data) => { + Keyboard.dismiss(); + signIn(data); }; - render() { - const { - navigation, - signIn, - } = this.props; - return ( - navigation.replace('SignUpScreen')} - /> - ); - } -} + return ( + + {props => ( + navigation.replace('SignUpScreen')} + {...props} + /> + )} + + ); +}; + +LoginScreen.propTypes = { + navigation: PropTypes.object, + signIn: PropTypes.func, +}; -export default LoginScreen; +export default connect(null, ({ + signIn: signInAction, +}))(LoginScreen); diff --git a/src/screens/SignUpScreen/FormProvider.js b/src/screens/SignUpScreen/FormProvider.js new file mode 100644 index 0000000..19d7720 --- /dev/null +++ b/src/screens/SignUpScreen/FormProvider.js @@ -0,0 +1,48 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Formik } from 'formik'; +import { object, string } from 'yup'; + +const SignUpSchema = object().shape({ + firstName: string().required('Required'), + lastName: string().required('Required'), + email: string() + .email('Invalid email') + .required('Required'), + password: string().required('Required'), +}); + +const INITIAL_SIGN_UP_VALUES = { + firstName: '', + lastName: '', + email: '', + password: '', +}; + +const FormProvider = ({ children, onSubmit }) => { + /* :: (object, object) -> Promise */ + const handleSignIn = async (formData, actions) => { + try { + onSubmit(formData); + } catch (error) { + actions.resetForm(); + } + }; + + return ( + + {children} + + ); +}; + +FormProvider.propTypes = { + onSubmit: PropTypes.func.isRequired, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired, +}; + +export default FormProvider; diff --git a/src/screens/SignUpScreen/SignUp.js b/src/screens/SignUpScreen/SignUp.js index d738f7e..8e05a75 100644 --- a/src/screens/SignUpScreen/SignUp.js +++ b/src/screens/SignUpScreen/SignUp.js @@ -1,83 +1,79 @@ -import React, { Component } from 'react'; -import { View, Keyboard } from 'react-native'; -import { reduxForm, Field } from 'redux-form'; +import React, { useRef } from 'react'; +import { View } from 'react-native'; import PropTypes from 'prop-types'; import KeyboardAvoidingWrapper from '../../components/KeyboardAvoidingWrapper'; import FormInput from '../../components/AuthFormInput'; import DefaultButton from '../../components/DefaultButton'; - -import validate from '../../validators/auth-validator'; import styles from './styles'; -@reduxForm({ form: 'signup', validate }) -class SignUp extends Component { - static propTypes = { - onGoToLoginPress: PropTypes.func, - handleSubmit: PropTypes.func, - }; - - handleSubmit = (data) => { - Keyboard.dismiss(); - this.props.handleSubmit(data); - } +const SignUp = ({ handleSubmit, values, ...props }) => { + const passwordRef = useRef(null); + const lastNameRef = useRef(null); + const emailRef = useRef(null); - render() { - const { onGoToLoginPress } = this.props; + return ( + + + + lastNameRef.current.focus()} + maxLength={20} + value={values.firstName} + {...props} + /> + emailRef.current.focus()} + inputRef={lastNameRef} + maxLength={20} + value={values.lastName} + {...props} + /> + passwordRef.current.focus()} + inputRef={emailRef} + keyboardType='email-address' + maxLength={40} + value={values.email} + {...props} + /> + + + + + + ); +}; - return ( - - - - this.lastNameRef.focus()} - maxLength={20} - /> - this.emailRef.focus()} - inputRef={(ref) => { this.lastNameRef = ref; }} - maxLength={20} - /> - this.passwordRef.focus()} - inputRef={(ref) => { this.emailRef = ref; }} - keyboardType='email-address' - maxLength={40} - /> - { this.passwordRef = ref; }} - secureTextEntry - onSubmitEditing={this.handleSubmit} - maxLength={20} - /> - - - - - ); - } -} +SignUp.propTypes = { + handleSubmit: PropTypes.func, + values: PropTypes.object, +}; export default SignUp; diff --git a/src/screens/SignUpScreen/index.js b/src/screens/SignUpScreen/index.js index 19c9283..d9f3d56 100644 --- a/src/screens/SignUpScreen/index.js +++ b/src/screens/SignUpScreen/index.js @@ -1,32 +1,35 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { Keyboard } from 'react-native'; +import FormProvider from './FormProvider'; import SignUp from './SignUp'; import { signUpAction } from '../../redux/actions'; -@connect(null, ({ - signUp: signUpAction, -})) -class SignUpScreen extends Component { - static propTypes = { - navigation: PropTypes.object, - signUp: PropTypes.func, +const SignUpScreen = ({ navigation, signUp }) => { + const handleSubmit = (data) => { + Keyboard.dismiss(); + signUp(data); }; - render() { - const { - navigation, - signUp, - } = this.props; + return ( + + {props => ( + navigation.replace('LoginScreen')} + {...props} + /> + )} + + ); +}; - return ( - navigation.replace('LoginScreen')} - onSubmit={signUp} - /> - ); - } -} +SignUpScreen.propTypes = { + navigation: PropTypes.object, + signUp: PropTypes.func, +}; -export default SignUpScreen; +export default connect(null, ({ + signUp: signUpAction, +}))(SignUpScreen); diff --git a/src/utils/apiProvider.js b/src/utils/apiProvider.js new file mode 100644 index 0000000..205a6b5 --- /dev/null +++ b/src/utils/apiProvider.js @@ -0,0 +1,51 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import axios from './axios'; + +export const ApiContext = React.createContext(); + +const ApiProvider = ({ store, children }) => { + axios.setStore(store); + + const value = { + /* GET */ + async get(path, config = {}) { + const response = await axios.get(path, config); + + return response; + }, + + /* POST */ + async post(path, data, config = {}) { + const response = await axios.post( + path, + data, + config, + ); + + return response; + }, + + /* PUT */ + async put(path, data, config = {}) { + const response = await axios.put( + path, + data, + config, + ); + + return response; + }, + }; + + return ( + {children} + ); +}; + +ApiProvider.propTypes = { + children: PropTypes.node, + store: PropTypes.any, +}; + +export default ApiProvider; diff --git a/src/utils/axios.js b/src/utils/axios.js index 92025ea..c03882b 100644 --- a/src/utils/axios.js +++ b/src/utils/axios.js @@ -1,4 +1,6 @@ import axios from 'axios'; +import { REFRESH_ACCESS_TOKEN_ENDPOINT } from '../constants/endpoints'; +import { accessTokenUpdatedAction, signOutAction } from '../redux/actions'; const API_URL = 'YOUR_SERVER_ADDRESS'; @@ -7,6 +9,69 @@ const axiosInstance = axios.create({ timeout: 20000, }); +let store = null; + +axiosInstance.setStore = (providedStore) => { + store = providedStore; +}; + +function checkForTokenError(error, onErrorCallback, paramToCheck) { + if (error.response) { + const errorIsFound = error.response.data.find(e => e.param === paramToCheck); + + if (errorIsFound) { + return onErrorCallback(error); + } + + throw error; + } else if (error.request) { + throw createSimpleErrorObject('Server does not respond'); + } + + throw createSimpleErrorObject('Please, check your internet connection'); +} + +export const refreshTokenSelector = state => state.auth.refreshToken; + +function onRefreshTokenError() { + const { dispatch } = store; + + + dispatch(signOutAction()); +} + +async function refreshAccessToken() { + try { + const state = store.getState(); + const refreshToken = refreshTokenSelector(state); + const response = await axiosInstance.post(REFRESH_ACCESS_TOKEN_ENDPOINT, { refreshToken }); + const { dispatch } = store; + + dispatch(accessTokenUpdatedAction(response.data)); + setAuthHeader(response.data.accessToken); + return response.data.accessToken; + } catch (error) { + return checkForTokenError(error, onRefreshTokenError, 'refreshToken'); + } +} + +axiosInstance.interceptors.response.use(null, async (error) => { + if (error.response && error.response.data.find(e => e.param === 'accessToken')) { + try { + const newToken = await refreshAccessToken(); + + error.config.headers.Authorization = `Bearer ${newToken}`; + + return axiosInstance.request(error.config); + } catch (err) { + onRefreshTokenError(); + throw err; + } + } + + throw error; +}); + export const setAuthHeader = (accessToken) => { axiosInstance.defaults.headers.common.Authorization = `Bearer ${accessToken}`; }; @@ -15,4 +80,22 @@ export const resetAuthHeader = () => { delete axiosInstance.defaults.headers.common.Authorization; }; +export const getFormErrors = (error) => { + const formErrors = {}; + + error.response.data.forEach(({ param, message }) => { formErrors[param] = message; }); + + return formErrors; +}; + +export const createSimpleErrorObject = (error) => { + return { + response: { + data: { + _error: error, + }, + }, + }; +}; + export default axiosInstance; diff --git a/src/utils/useApi.js b/src/utils/useApi.js new file mode 100644 index 0000000..778320f --- /dev/null +++ b/src/utils/useApi.js @@ -0,0 +1,8 @@ +import { useContext } from 'react'; +import { ApiContext } from './apiProvider'; + +export default () => { + const api = useContext(ApiContext); + + return api; +}; diff --git a/src/utils/withApi.js b/src/utils/withApi.js new file mode 100644 index 0000000..2ee6971 --- /dev/null +++ b/src/utils/withApi.js @@ -0,0 +1,20 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { ApiContext } from './apiProvider'; + + +export const withApi = (Component) => { + const WithApi = props => ( + + {api => } + + ); + + return WithApi; +}; + +export const ApiType = PropTypes.shape({ + get: PropTypes.func.isRequired, + post: PropTypes.func.isRequired, + put: PropTypes.func.isRequired, +}); diff --git a/src/validators/auth-validator.js b/src/validators/auth-validator.js deleted file mode 100644 index ad39b2e..0000000 --- a/src/validators/auth-validator.js +++ /dev/null @@ -1,32 +0,0 @@ -export default function validate(values) { - const errors = {}; - const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - const passwordRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,}$/; - const nameRegex = /^(?=.{1,50}$)[a-z]+(?:['_.\s][a-z]+)*$/i; - - if (!values.email) { - errors.email = 'Email field is required'; - } else if (!emailRegex.test(values.email)) { - errors.email = 'Please, enter a valid email address'; - } - - if (!values.password) { - errors.password = 'Password field is required'; - } else if (!passwordRegex.test(values.password)) { - errors.password = 'Password must contain at least 8 characters, including an upper-case letter and a number'; - } - - if (!values.firstName) { - errors.firstName = 'First name field is required'; - } else if (!nameRegex.test(values.firstName)) { - errors.firstName = 'Please, enter a valid first name'; - } - - if (!values.lastName) { - errors.lastName = 'First name field is required'; - } else if (!nameRegex.test(values.lastName)) { - errors.lastName = 'Please, enter a valid first name'; - } - - return errors; -} diff --git a/yarn.lock b/yarn.lock index c1ef3e0..89e582c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -680,6 +680,13 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd" + integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" @@ -961,49 +968,49 @@ react-native-safe-area-view "^0.14.1" react-native-screens "^1.0.0 || ^1.0.0-alpha" -"@redux-saga/core@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.0.2.tgz#4336a5bb4253e5ca69681c25a863fbbc03ea6d88" - integrity sha512-AsJYcpuYfM1cmxJvfhXs9HAFSZVEG17TMsLPlXH7+Hq5a5ZP4GqcbtijEmS2AC7NR5lLJHy8csxpqz22PeW5dw== - dependencies: - "@babel/runtime" "^7.0.0" - "@redux-saga/deferred" "^1.0.1" - "@redux-saga/delay-p" "^1.0.1" - "@redux-saga/is" "^1.0.2" - "@redux-saga/symbols" "^1.0.1" - "@redux-saga/types" "^1.0.2" - redux ">=0.10 <5" - typescript-tuple "^2.1.0" - -"@redux-saga/deferred@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.0.1.tgz#c895445e486bded90acf0b873b4e978fbfe458c2" - integrity sha512-+gW5xQ93QXOOmRLAmX8x2Hx1HpbTG6CM6+HcdTSbJovh4uMWaGyeDECnqXSt8QqA/ja3s2nqYXLqXFKepIQ1hw== +"@redux-saga/core@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.1.tgz#72432130630cca08260086ffc564c2aa5488a0a2" + integrity sha512-WKXfj2cYkP0eh74dE1ueMjVDoGJIkppXiMFgx0buVRkXENeZmRxIjM4lh9LEWWFqay7I/Qkw7+cMossa7xXoAQ== + dependencies: + "@babel/runtime" "^7.6.0" + "@redux-saga/deferred" "^1.1.0" + "@redux-saga/delay-p" "^1.1.0" + "@redux-saga/is" "^1.1.0" + "@redux-saga/symbols" "^1.1.0" + "@redux-saga/types" "^1.1.0" + redux "^4.0.4" + typescript-tuple "^2.2.1" + +"@redux-saga/deferred@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.1.0.tgz#aff018f64a936c288c18bd64ddf9ccfa143db6b4" + integrity sha512-wOCJCby3hx14bvrEeFLJ1JJTjJdXDJyC+B3JQ6eiqgzNghylbf969lIYmS2Arf2QuALfUtRBNPXBIMDKG9km4g== -"@redux-saga/delay-p@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.0.1.tgz#d69fc6103c7509ae80faa144ea17bbc69e51e029" - integrity sha512-0SnNDyDLUyB4NThtptAwiprNOnbCNhoed/Rp5JwS7SB+a/AdWynVgg/E6BmjsggLFNr07KW0bzn05tsPRBuU7Q== +"@redux-saga/delay-p@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.1.0.tgz#4024f979d0f78763d2e90233be8c922781ae4400" + integrity sha512-BcRwXs20kKjgiYEwZARkpVoRIe/hHftW3iwPhdeW4/jPyR9gLv/vG8VsJMF5NDEch+/w/mJtdgSubq+wtOS47g== dependencies: - "@redux-saga/symbols" "^1.0.1" + "@redux-saga/symbols" "^1.1.0" -"@redux-saga/is@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.0.2.tgz#7f4be014c97061898d7efb11d6c9de31e943ed38" - integrity sha512-WnaUOwYvPK2waWjzebT4uhL8zY76XNkzzpJ2EQJe8bN1tByvAjvT7MuJZTSshOhdHL5PsRO0MsH224XIXBJidQ== +"@redux-saga/is@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.1.0.tgz#d74358364ebde160bf1b8bd94903ff7684b12d41" + integrity sha512-0uFXWGSvDCfNBdROHwEVixNhFbI3S+UGBQfcPXQiYL+CjIjyR3DTg2Z+NFH9xzP+H4Oh/yGtTHDhC0GxYp7HQQ== dependencies: - "@redux-saga/symbols" "^1.0.1" - "@redux-saga/types" "^1.0.2" + "@redux-saga/symbols" "^1.1.0" + "@redux-saga/types" "^1.1.0" -"@redux-saga/symbols@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.0.1.tgz#46512ae1275f88df061c42168d0f600ddb170c1e" - integrity sha512-akKkzcVnb1RzJaZV2LQFbi51abvdICMuAKwwLoCjjxLbLAGIw9EJxk5ucNnWSSCEsoEQMeol5tkAcK+Xzuv1Bg== +"@redux-saga/symbols@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.1.0.tgz#676b277cb5deb48ce723b2b394cbae97f82e8319" + integrity sha512-Fzw1wV3j4hbac3MYmgNE18Z53URmQZeilTHZLF7Lm4SQ1jG4fcU47v2kElsEbQXUSaFqj+uJqdRzmDGNb6pRwQ== -"@redux-saga/types@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.0.2.tgz#1d94f02800b094753f9271c206a26c2a06ca14ee" - integrity sha512-8/qcMh15507AnXJ3lBeuhsdFwnWQqnp68EpUuHlYPixJ5vjVmls7/Jq48cnUlrZI8Jd9U1jkhfCl0gaT5KMgVw== +"@redux-saga/types@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" + integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== "@types/babel__core@^7.1.0": version "7.1.2" @@ -1951,6 +1958,14 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" +create-react-context@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3" + integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag== + dependencies: + fbjs "^0.8.0" + gud "^1.0.0" + 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" @@ -2040,6 +2055,11 @@ 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= +deepmerge@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + 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" @@ -2209,11 +2229,6 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" -es6-error@^4.1.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" @@ -2625,7 +2640,7 @@ fbjs-scripts@^1.0.0: semver "^5.1.0" through2 "^2.0.0" -fbjs@^0.8.9: +fbjs@^0.8.0, fbjs@^0.8.9: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -2739,6 +2754,11 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" +fn-name@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + follow-redirects@^1.3.0: version "1.7.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" @@ -2772,6 +2792,21 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +formik@^1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/formik/-/formik-1.5.8.tgz#eee8cd345effe46839bc748c7f920486f12f14b0" + integrity sha512-fNvPe+ddbh+7xiByT25vuso2p2hseG/Yvuj211fV1DbCjljUEG9OpgRpcb7g7O3kxHX/q31cbZDzMxJXPWSNwA== + dependencies: + create-react-context "^0.2.2" + deepmerge "^2.1.1" + hoist-non-react-statics "^3.3.0" + lodash "^4.17.14" + lodash-es "^4.17.14" + prop-types "^15.6.1" + react-fast-compare "^2.0.1" + tiny-warning "^1.0.2" + tslib "^1.9.3" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -2936,6 +2971,11 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + handlebars@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" @@ -3020,7 +3060,7 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0, hoist-non-react-statics@^2.5.4: +hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== @@ -3147,7 +3187,7 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.0, invariant@^2.2.2, 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== @@ -4091,10 +4131,10 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash-es@^4.17.10, lodash-es@^4.17.5: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0" - integrity sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q== +lodash-es@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== lodash.pad@^4.1.0: version "4.5.1" @@ -4121,11 +4161,16 @@ lodash.throttle@^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.2.0, lodash@^4.3.0, lodash@^4.6.1: +lodash@^4.17.11, lodash@^4.17.4, lodash@^4.2.0, 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== +lodash@^4.17.14, lodash@^4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -5324,7 +5369,7 @@ prompts@^2.0.1: kleur "^3.0.2" sisteransi "^1.0.0" -prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2: +prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -5333,6 +5378,11 @@ prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, object-assign "^4.1.1" react-is "^16.8.1" +property-expr@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" + integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -5417,11 +5467,21 @@ react-devtools-core@^3.6.0: shell-quote "^1.6.1" ws "^3.3.1" -react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: +react-fast-compare@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + +react-is@^16.7.0, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== +react-is@^16.8.1, react-is@^16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" + integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw== + react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -5577,17 +5637,17 @@ react-proxy@^1.1.7: lodash "^4.6.1" react-deep-force-update "^1.0.0" -react-redux@5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8" - integrity sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg== +react-redux@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.1.tgz#ce6eee1b734a7a76e0788b3309bf78ff6b34fa0a" + integrity sha512-QsW0vcmVVdNQzEkrgzh2W3Ksvr8cqpAv5FhEk7tNEft+5pp7rXxAudTz3VOPawRkLIepItpkEIyLcN/VVXzjTg== dependencies: - hoist-non-react-statics "^2.5.0" - invariant "^2.0.0" - lodash "^4.17.5" - lodash-es "^4.17.5" - loose-envify "^1.1.0" - prop-types "^15.6.0" + "@babel/runtime" "^7.5.5" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.9.0" react-test-renderer@16.8.3: version "16.8.3" @@ -5671,49 +5731,27 @@ realpath-native@^1.1.0: dependencies: util.promisify "^1.0.0" -redux-act@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/redux-act/-/redux-act-1.7.4.tgz#0dd7c6daaca98649540a3d42c259814b048bd8e1" - integrity sha512-gzpod7iF2sIQAxUjTn/qNmzPGenE3zrFFZlBv8X4Ee8MsvF750jZi0Gucg4Il3KvZ78fsKR2vp6SBuSmD7ex0Q== +redux-act@1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/redux-act/-/redux-act-1.7.7.tgz#0ee8140ade95921b6ebbf70be3fc61c8d6c8a4b1" + integrity sha512-UKa6QJkrgrQauFtEuGjnZaBa6dKwXjeu/qchY8ifbA+i/UdEEtOZ/lfowaXkgfllr9c/5EAmmlvk0C9J2wSTnw== -redux-form@7.4.2: - version "7.4.2" - resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-7.4.2.tgz#d6061088fb682eb9fc5fb9749bd8b102f03154b0" - integrity sha512-QxC36s4Lelx5Cr8dbpxqvl23dwYOydeAX8c6YPmgkz/Dhj053C16S2qoyZN6LO6HJ2oUF00rKsAyE94GwOUhFA== - dependencies: - es6-error "^4.1.1" - hoist-non-react-statics "^2.5.4" - invariant "^2.2.4" - is-promise "^2.1.0" - lodash "^4.17.10" - lodash-es "^4.17.10" - prop-types "^15.6.1" - react-lifecycles-compat "^3.0.4" - -redux-persist@5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b" - integrity sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg== +redux-persist@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" + integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== -redux-saga@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.0.2.tgz#0599703f975438f1b2f9d2b9a965ec58f0fdfcd7" - integrity sha512-dHV256by3eF2AnBPx1l3HqazQFkErZ82HDXgh4jSRpT72OrX31wyg8DA1q8+0HvENRfJAyhT/4qT5yH/vVqFfw== - dependencies: - "@redux-saga/core" "^1.0.2" - -redux@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.0.tgz#aa698a92b729315d22b34a0553d7e6533555cc03" - integrity sha512-NnnHF0h0WVE/hXyrB6OlX67LYRuaf/rJcbWvnHHEPCF/Xa/AZpwhs/20WyqzQae5x4SD2F9nPObgBh2rxAgLiA== +redux-saga@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.1.1.tgz#7e02879beb02c92030b5fbe746fd70e8bda97dfb" + integrity sha512-guSnGJ/uEF8yL8Mn4aNa7HxRGCpVUALCkec9iTTD0fOhQqkF6bRQkBLeS+7/cAH3nFnr299bi/DOurTi1apcCA== dependencies: - loose-envify "^1.1.0" - symbol-observable "^1.2.0" + "@redux-saga/core" "^1.1.1" -"redux@>=0.10 <5": - version "4.0.1" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" - integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg== +redux@4.0.4, redux@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796" + integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q== dependencies: loose-envify "^1.4.0" symbol-observable "^1.2.0" @@ -6427,6 +6465,11 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= +synchronous-promise@^2.0.6: + version "2.0.10" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.10.tgz#e64c6fd3afd25f423963353043f4a68ebd397fd8" + integrity sha512-6PC+JRGmNjiG3kJ56ZMNWDPL8hjyghF5cMXIFOKg+NiwwEZZIvxTWd0pinWKyD227odg9ygF8xVhhz7gb8Uq7A== + table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -6498,6 +6541,11 @@ time-stamp@^1.0.0: resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= +tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6545,6 +6593,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + tough-cookie@^2.3.3, tough-cookie@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -6573,6 +6626,11 @@ trim-right@^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.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -6614,7 +6672,7 @@ typescript-logic@^0.0.0: resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196" integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== -typescript-tuple@^2.1.0: +typescript-tuple@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2" integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== @@ -7029,3 +7087,15 @@ yargs@^9.0.0: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^7.0.0" + +yup@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.27.0.tgz#f8cb198c8e7dd2124beddc2457571329096b06e7" + integrity sha512-v1yFnE4+u9za42gG/b/081E7uNW9mUj3qtkmelLbW5YPROZzSH/KUUyJu9Wt8vxFJcT9otL/eZopS0YK1L5yPQ== + dependencies: + "@babel/runtime" "^7.0.0" + fn-name "~2.0.1" + lodash "^4.17.11" + property-expr "^1.5.0" + synchronous-promise "^2.0.6" + toposort "^2.0.2"