From 627d503d43af7ccc5bede83347f30d337880345c Mon Sep 17 00:00:00 2001 From: SleepWalker Date: Sun, 30 Jun 2019 16:32:50 +0300 Subject: [PATCH] Major deps updates: router, redux, intl, react-transition-group, flow-type, testing deps --- flow-typed/npm/react-intl_v2.x.x.js | 239 +- flow-typed/npm/react-redux_v5.x.x.js | 334 ++- flow-typed/npm/react-router-dom_v5.x.x.js | 176 ++ flow-typed/npm/react-router_v4.x.x.js | 139 - flow-typed/npm/redux_v3.x.x.js | 109 - flow-typed/npm/redux_v4.x.x.js | 100 + package.json | 29 +- src/components/accounts/actions.test.js | 11 +- src/components/accounts/reducer.test.js | 2 +- src/components/auth/PanelTransition.js | 67 +- src/components/auth/actions.js | 20 +- src/components/auth/actions.test.js | 2 +- src/components/auth/reducer.js | 43 +- src/components/auth/reducer.test.js | 2 +- src/components/contact/ContactForm.js | 5 +- src/components/contact/ContactForm.test.js | 2 +- src/components/contact/ContactLink.js | 17 +- .../apps/applicationForm/ApplicationForm.js | 2 +- .../dev/apps/list/ApplicationItem.js | 2 +- src/components/dev/apps/reducer.js | 11 +- src/components/footerMenu/FooterMenu.js | 14 +- .../languageSwitcher/LanguageSwitcher.js | 29 +- .../changeLanguageLink/ChangeLanguageLink.js | 28 +- src/components/profile/Profile.js | 15 +- .../changePassword/ChangePassword.test.js | 2 +- src/components/ui/bsod/BsodMiddleware.js | 2 +- src/components/ui/bsod/BsodMiddleware.test.js | 2 +- src/components/ui/form/Captcha.js | 8 +- src/components/ui/form/Checkbox.js | 8 +- src/components/ui/form/Form.js | 16 +- src/components/ui/form/FormComponent.js | 2 +- src/components/ui/form/FormInputComponent.js | 6 - src/components/ui/form/FormModel.js | 10 +- src/components/ui/form/Input.js | 10 +- src/components/ui/form/Input.test.js | 2 +- src/components/ui/form/LinkButton.js | 7 +- src/components/ui/form/Radio.js | 8 +- src/components/ui/form/TextArea.js | 10 +- src/components/ui/popup/PopupStack.js | 78 +- src/components/ui/popup/PopupStack.test.js | 2 +- src/components/ui/popup/actions.js | 11 +- src/components/ui/popup/popup.scss | 4 +- src/components/ui/popup/reducer.test.js | 14 +- src/components/ui/scroll/ScrollIntoView.js | 5 +- .../bearerHeaderMiddleware.test.js | 2 +- .../refreshTokenMiddleware.test.js | 2 +- src/containers/AuthFlowRouteContents.test.js | 25 +- src/containers/PrivateRoute.js | 37 +- src/pages/auth/AuthPage.js | 24 +- src/pages/dev/ApplicationsListPage.js | 20 +- src/pages/dev/UpdateApplicationPage.js | 13 +- src/pages/profile/ChangeEmailPage.js | 27 +- src/pages/profile/ChangePasswordPage.js | 8 +- src/pages/profile/ChangeUsernamePage.js | 13 +- src/pages/profile/MultiFactorAuthPage.js | 14 +- src/pages/profile/ProfilePage.js | 8 +- src/pages/root/RootPage.js | 2 +- src/pages/rules/RulesPage.test.js | 2 +- src/polyfills.test.js | 2 +- src/services/api/accounts.js | 12 +- src/services/api/activate.test.js | 2 +- src/services/api/authentication.test.js | 2 +- src/services/api/oauth.js | 55 +- src/services/api/options.test.js | 2 +- .../authFlow/AuthFlow.functional.test.js | 2 +- src/services/authFlow/AuthFlow.test.js | 6 +- src/services/authFlow/CompleteState.test.js | 2 +- src/services/authFlow/MfaState.test.js | 2 +- src/services/authFlow/PasswordState.test.js | 2 +- src/services/history.js | 15 +- .../request/PromiseMiddlewareLayer.test.js | 2 +- src/services/request/request.js | 3 +- src/services/request/request.test.js | 2 +- src/test.js | 2 - src/test/unexpected.js | 7 + yarn.lock | 2600 +++++++++++------ 76 files changed, 2819 insertions(+), 1703 deletions(-) create mode 100644 flow-typed/npm/react-router-dom_v5.x.x.js delete mode 100644 flow-typed/npm/react-router_v4.x.x.js delete mode 100644 flow-typed/npm/redux_v3.x.x.js create mode 100644 flow-typed/npm/redux_v4.x.x.js create mode 100644 src/test/unexpected.js diff --git a/flow-typed/npm/react-intl_v2.x.x.js b/flow-typed/npm/react-intl_v2.x.x.js index f7785f0..b9a7638 100644 --- a/flow-typed/npm/react-intl_v2.x.x.js +++ b/flow-typed/npm/react-intl_v2.x.x.js @@ -1,5 +1,5 @@ -// flow-typed signature: e68caa23426dedefced5662fb92b4638 -// flow-typed version: d13a175635/react-intl_v2.x.x/flow_>=v0.57.x +// flow-typed signature: 3902298e28ed22d8cd8d49828801a760 +// flow-typed version: eb50783110/react-intl_v2.x.x/flow_>=v0.63.x /** * Original implementation of this file by @marudor at https://github.com/marudor/flowInterfaces @@ -7,112 +7,110 @@ * https://github.com/marudor/flowInterfaces/issues/6 */ // Mostly from https://github.com/yahoo/react-intl/wiki/API#react-intl-api - -import type { Element, ChildrenArray } from "react"; - -type $npm$ReactIntl$LocaleData = { - locale: string, - [key: string]: any -}; - -type $npm$ReactIntl$MessageDescriptor = { - id: string, - description?: string, - defaultMessage?: string -}; - -type $npm$ReactIntl$IntlConfig = { - locale: string, - formats: Object, - messages: { [id: string]: string }, - - defaultLocale?: string, - defaultFormats?: Object -}; - -type $npm$ReactIntl$IntlProviderConfig = { - locale?: string, - formats?: Object, - messages?: { [id: string]: string }, - - defaultLocale?: string, - defaultFormats?: Object -}; - -type $npm$ReactIntl$IntlFormat = { - formatDate: (value: any, options?: Object) => string, - formatTime: (value: any, options?: Object) => string, - formatRelative: (value: any, options?: Object) => string, - formatNumber: (value: any, options?: Object) => string, - formatPlural: (value: any, options?: Object) => string, - formatMessage: ( - messageDescriptor: $npm$ReactIntl$MessageDescriptor, - values?: Object - ) => string, - formatHTMLMessage: ( - messageDescriptor: $npm$ReactIntl$MessageDescriptor, - values?: Object - ) => string -}; - -type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig & - $npm$ReactIntl$IntlFormat & { now: () => number }; - -type $npm$ReactIntl$DateTimeFormatOptions = { - localeMatcher?: "best fit" | "lookup", - formatMatcher?: "basic" | "best fit", - - timeZone?: string, - hour12?: boolean, - - weekday?: "narrow" | "short" | "long", - era?: "narrow" | "short" | "long", - year?: "numeric" | "2-digit", - month?: "numeric" | "2-digit" | "narrow" | "short" | "long", - day?: "numeric" | "2-digit", - hour?: "numeric" | "2-digit", - minute?: "numeric" | "2-digit", - second?: "numeric" | "2-digit", - timeZoneName?: "short" | "long" -}; - -type $npm$ReactIntl$RelativeFormatOptions = { - style?: "best fit" | "numeric", - units?: "second" | "minute" | "hour" | "day" | "month" | "year" -}; - -type $npm$ReactIntl$NumberFormatOptions = { - localeMatcher?: "best fit" | "lookup", - - style?: "decimal" | "currency" | "percent", - - currency?: string, - currencyDisplay?: "symbol" | "code" | "name", - - useGrouping?: boolean, - - minimumIntegerDigits?: number, - minimumFractionDigits?: number, - maximumFractionDigits?: number, - minimumSignificantDigits?: number, - maximumSignificantDigits?: number -}; - -type $npm$ReactIntl$PluralFormatOptions = { - style?: "cardinal" | "ordinal" -}; - -type $npm$ReactIntl$PluralCategoryString = - | "zero" - | "one" - | "two" - | "few" - | "many" - | "other"; - -type $npm$ReactIntl$DateParseable = number | string | Date; - declare module "react-intl" { + import type { Element, ChildrenArray } from "react"; + + declare type $npm$ReactIntl$LocaleData = { + locale: string, + [key: string]: any + }; + + declare type $npm$ReactIntl$MessageDescriptor = { + id: string, + description?: string, + defaultMessage?: string + }; + + declare type $npm$ReactIntl$IntlConfig = { + locale: string, + formats: Object, + messages: { [id: string]: string }, + + defaultLocale?: string, + defaultFormats?: Object + }; + + declare type $npm$ReactIntl$IntlProviderConfig = { + locale?: string, + formats?: Object, + messages?: { [id: string]: string }, + + defaultLocale?: string, + defaultFormats?: Object + }; + + declare type $npm$ReactIntl$IntlFormat = { + formatDate: (value: any, options?: Object) => string, + formatTime: (value: any, options?: Object) => string, + formatRelative: (value: any, options?: Object) => string, + formatNumber: (value: any, options?: Object) => string, + formatPlural: (value: any, options?: Object) => string, + formatMessage: ( + messageDescriptor: $npm$ReactIntl$MessageDescriptor, + values?: Object + ) => string, + formatHTMLMessage: ( + messageDescriptor: $npm$ReactIntl$MessageDescriptor, + values?: Object + ) => string + }; + + declare type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig & + $npm$ReactIntl$IntlFormat & { now: () => number }; + + declare type $npm$ReactIntl$DateTimeFormatOptions = { + localeMatcher?: "best fit" | "lookup", + formatMatcher?: "basic" | "best fit", + + timeZone?: string, + hour12?: boolean, + + weekday?: "narrow" | "short" | "long", + era?: "narrow" | "short" | "long", + year?: "numeric" | "2-digit", + month?: "numeric" | "2-digit" | "narrow" | "short" | "long", + day?: "numeric" | "2-digit", + hour?: "numeric" | "2-digit", + minute?: "numeric" | "2-digit", + second?: "numeric" | "2-digit", + timeZoneName?: "short" | "long" + }; + + declare type $npm$ReactIntl$RelativeFormatOptions = { + style?: "best fit" | "numeric", + units?: "second" | "minute" | "hour" | "day" | "month" | "year" + }; + + declare type $npm$ReactIntl$NumberFormatOptions = { + localeMatcher?: "best fit" | "lookup", + + style?: "decimal" | "currency" | "percent", + + currency?: string, + currencyDisplay?: "symbol" | "code" | "name", + + useGrouping?: boolean, + + minimumIntegerDigits?: number, + minimumFractionDigits?: number, + maximumFractionDigits?: number, + minimumSignificantDigits?: number, + maximumSignificantDigits?: number + }; + + declare type $npm$ReactIntl$PluralFormatOptions = { + style?: "cardinal" | "ordinal" + }; + + declare type $npm$ReactIntl$PluralCategoryString = + | "zero" + | "one" + | "two" + | "few" + | "many" + | "other"; + + declare type $npm$ReactIntl$DateParseable = number | string | Date; // PropType checker declare function intlShape( props: Object, @@ -123,7 +121,7 @@ declare module "react-intl" { data: $npm$ReactIntl$LocaleData | Array<$npm$ReactIntl$LocaleData> ): void; declare function defineMessages< - T: { [key: string]: $npm$ReactIntl$MessageDescriptor } + T: { [key: string]: $Exact<$npm$ReactIntl$MessageDescriptor> } >( messageDescriptors: T ): T; @@ -132,6 +130,10 @@ declare module "react-intl" { intl: $npm$ReactIntl$IntlShape } + declare type InjectIntlVoidProps = { + intl: $npm$ReactIntl$IntlShape | void + } + declare type ComponentWithDefaultProps = | React$ComponentType | React$StatelessFunctionalComponent @@ -152,19 +154,12 @@ declare module "react-intl" { IntlInjectedComponent >; - declare function injectIntl - ( - component: ComponentWithDefaultProps, + declare function injectIntl>( + WrappedComponent: Component, options?: InjectIntlOptions, - ): - IntlInjectedComponentClass<$Diff, DefaultProps> - - declare function injectIntl - ( - component: React$ComponentType, - options?: InjectIntlOptions, - ): - IntlInjectedComponentClass<$Diff>; + ): React$ComponentType< + $Diff, InjectIntlVoidProps> + >; declare function formatMessage( messageDescriptor: $npm$ReactIntl$MessageDescriptor, @@ -202,7 +197,9 @@ declare module "react-intl" { $npm$ReactIntl$MessageDescriptor & { values?: Object, tagName?: string, - children?: (...formattedMessage: Array) => React$Node + children?: + | ((...formattedMessage: Array) => React$Node) + | (string => React$Node) } > {} declare class FormattedHTMLMessage extends React$Component< diff --git a/flow-typed/npm/react-redux_v5.x.x.js b/flow-typed/npm/react-redux_v5.x.x.js index 7f7cb78..eeeab17 100644 --- a/flow-typed/npm/react-redux_v5.x.x.js +++ b/flow-typed/npm/react-redux_v5.x.x.js @@ -1,114 +1,276 @@ -// flow-typed signature: c5fac64666f9589a0c1b2de956dc7919 -// flow-typed version: 81d6274128/react-redux_v5.x.x/flow_>=v0.53.x +// flow-typed signature: f06f00c3ad0cfedb90c0c6de04b219f3 +// flow-typed version: 3a6d556e4b/react-redux_v5.x.x/flow_>=v0.89.x -// flow-typed signature: 8db7b853f57c51094bf0ab8b2650fd9c -// flow-typed version: ab8db5f14d/react-redux_v5.x.x/flow_>=v0.30.x +/** +The order of type arguments for connect() is as follows: -import type { Dispatch, Store } from "redux"; +connect(…) + +In Flow v0.89 only the first two are mandatory to specify. Other 4 can be repaced with the new awesome type placeholder: + +connect(…) + +But beware, in case of weird type errors somewhere in random places +just type everything and get to a green field and only then try to +remove the definitions you see bogus. + +Decrypting the abbreviations: + WC = Component being wrapped + S = State + D = Dispatch + OP = OwnProps + SP = StateProps + DP = DispatchProps + MP = Merge props + RSP = Returned state props + RDP = Returned dispatch props + RMP = Returned merge props + CP = Props for returned component + Com = React Component + ST = Static properties of Com + EFO = Extra factory options (used only in connectAdvanced) +*/ declare module "react-redux" { - /* + // ------------------------------------------------------------ + // Typings for connect() + // ------------------------------------------------------------ - S = State - A = Action - OP = OwnProps - SP = StateProps - DP = DispatchProps + declare export type Options = {| + pure?: boolean, + withRef?: boolean, + areStatesEqual?: (next: S, prev: S) => boolean, + areOwnPropsEqual?: (next: OP, prev: OP) => boolean, + areStatePropsEqual?: (next: SP, prev: SP) => boolean, + areMergedPropsEqual?: (next: MP, prev: MP) => boolean, + storeKey?: string, + |}; - */ + declare type MapStateToProps<-S, -OP, +SP> = + | ((state: S, ownProps: OP) => SP) + // If you want to use the factory function but get a strange error + // like "function is not an object" then just type the factory function + // like this: + // const factory: (State, OwnProps) => (State, OwnProps) => StateProps + // and provide the StateProps type to the SP type parameter. + | ((state: S, ownProps: OP) => (state: S, ownProps: OP) => SP); - declare type MapStateToProps = ( - state: S, - ownProps: OP - ) => SP | MapStateToProps; + declare type Bind = ((...A) => R) => (...A) => $Call; - declare type MapDispatchToProps = - | ((dispatch: Dispatch, ownProps: OP) => DP) - | DP; + declare type MapDispatchToPropsFn = + | ((dispatch: D, ownProps: OP) => DP) + // If you want to use the factory function but get a strange error + // like "function is not an object" then just type the factory function + // like this: + // const factory: (Dispatch, OwnProps) => (Dispatch, OwnProps) => DispatchProps + // and provide the DispatchProps type to the DP type parameter. + | ((dispatch: D, ownProps: OP) => (dispatch: D, ownProps: OP) => DP); - declare type MergeProps = ( + declare class ConnectedComponent extends React$Component { + static +WrappedComponent: WC; + getWrappedInstance(): React$ElementRef; + } + // The connection of the Wrapped Component and the Connected Component + // happens here in `MP: P`. It means that type wise MP belongs to P, + // so to say MP >= P. + declare type Connector = >( + WC, + ) => Class> & WC; + + // No `mergeProps` argument + + // Got error like inexact OwnProps is incompatible with exact object type? + // Just make the OP parameter for `connect()` an exact object. + declare type MergeOP = {| ...$Exact, dispatch: D |}; + declare type MergeOPSP = {| ...$Exact, ...SP, dispatch: D |}; + declare type MergeOPDP = {| ...$Exact, ...DP |}; + declare type MergeOPSPDP = {| ...$Exact, ...SP, ...DP |}; + + declare export function connect<-P, -OP, -SP, -DP, -S, -D>( + mapStateToProps?: null | void, + mapDispatchToProps?: null | void, + mergeProps?: null | void, + options?: ?Options>, + ): Connector>; + + declare export function connect<-P, -OP, -SP, -DP, -S, -D>( + // If you get error here try adding return type to your mapStateToProps function + mapStateToProps: MapStateToProps, + mapDispatchToProps?: null | void, + mergeProps?: null | void, + options?: ?Options>, + ): Connector>; + + // In this case DP is an object of functions which has been bound to dispatch + // by the given mapDispatchToProps function. + declare export function connect<-P, -OP, -SP, -DP, S, D>( + mapStateToProps: null | void, + mapDispatchToProps: MapDispatchToPropsFn, + mergeProps?: null | void, + options?: ?Options>, + ): Connector>; + + // In this case DP is an object of action creators not yet bound to dispatch, + // this difference is not important in the vanila redux, + // but in case of usage with redux-thunk, the return type may differ. + declare export function connect<-P, -OP, -SP, -DP, S, D>( + mapStateToProps: null | void, + mapDispatchToProps: DP, + mergeProps?: null | void, + options?: ?Options>, + ): Connector>>>; + + declare export function connect<-P, -OP, -SP, -DP, S, D>( + // If you get error here try adding return type to your mapStateToProps function + mapStateToProps: MapStateToProps, + mapDispatchToProps: MapDispatchToPropsFn, + mergeProps?: null | void, + options?: ?Options, + ): Connector; + + declare export function connect<-P, -OP, -SP, -DP, S, D>( + // If you get error here try adding return type to your mapStateToProps function + mapStateToProps: MapStateToProps, + mapDispatchToProps: DP, + mergeProps?: null | void, + options?: ?Options>, + ): Connector>>>; + + // With `mergeProps` argument + + declare type MergeProps<+P, -OP, -SP, -DP> = ( stateProps: SP, dispatchProps: DP, - ownProps: OP + ownProps: OP, ) => P; - declare type Context = { store: Store<*, *> }; + declare export function connect<-P, -OP, -SP: {||}, -DP: {||}, S, D>( + mapStateToProps: null | void, + mapDispatchToProps: null | void, + // If you get error here try adding return type to you mapStateToProps function + mergeProps: MergeProps, + options?: ?Options, + ): Connector; - declare class ConnectedComponent extends React$Component { - static WrappedComponent: Class>, - getWrappedInstance(): React$Component

, - props: OP, - state: void - } + declare export function connect<-P, -OP, -SP, -DP: {||}, S, D>( + mapStateToProps: MapStateToProps, + mapDispatchToProps: null | void, + // If you get error here try adding return type to you mapStateToProps function + mergeProps: MergeProps, + options?: ?Options, + ): Connector; - declare type ConnectedComponentClass = Class< - ConnectedComponent - >; + // In this case DP is an object of functions which has been bound to dispatch + // by the given mapDispatchToProps function. + declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>( + mapStateToProps: null | void, + mapDispatchToProps: MapDispatchToPropsFn, + mergeProps: MergeProps, + options?: ?Options, + ): Connector; - declare type Connector = ( - component: React$ComponentType

- ) => ConnectedComponentClass; + // In this case DP is an object of action creators not yet bound to dispatch, + // this difference is not important in the vanila redux, + // but in case of usage with redux-thunk, the return type may differ. + declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>( + mapStateToProps: null | void, + mapDispatchToProps: DP, + mergeProps: MergeProps>>, + options?: ?Options, + ): Connector; - declare class Provider extends React$Component<{ - store: Store, - children?: any + // In this case DP is an object of functions which has been bound to dispatch + // by the given mapDispatchToProps function. + declare export function connect<-P, -OP, -SP, -DP, S, D>( + mapStateToProps: MapStateToProps, + mapDispatchToProps: MapDispatchToPropsFn, + mergeProps: MergeProps, + options?: ?Options, + ): Connector; + + // In this case DP is an object of action creators not yet bound to dispatch, + // this difference is not important in the vanila redux, + // but in case of usage with redux-thunk, the return type may differ. + declare export function connect<-P, -OP, -SP, -DP, S, D>( + mapStateToProps: MapStateToProps, + mapDispatchToProps: DP, + mergeProps: MergeProps>>, + options?: ?Options, + ): Connector; + + // ------------------------------------------------------------ + // Typings for Provider + // ------------------------------------------------------------ + + declare export class Provider extends React$Component<{ + store: Store, + children?: React$Node, }> {} - declare function createProvider( + declare export function createProvider( storeKey?: string, - subKey?: string - ): Provider<*, *>; + subKey?: string, + ): Class>; - declare type ConnectOptions = { - pure?: boolean, - withRef?: boolean + // ------------------------------------------------------------ + // Typings for connectAdvanced() + // ------------------------------------------------------------ + + declare type ConnectAdvancedOptions = { + getDisplayName?: (name: string) => string, + methodName?: string, + renderCountProp?: string, + shouldHandleStateChanges?: boolean, + storeKey?: string, + withRef?: boolean, }; - declare type Null = null | void; + declare type SelectorFactoryOptions = { + getDisplayName: (name: string) => string, + methodName: string, + renderCountProp: ?string, + shouldHandleStateChanges: boolean, + storeKey: string, + withRef: boolean, + displayName: string, + wrappedComponentName: string, + WrappedComponent: Com, + }; - declare function connect( - ...rest: Array // <= workaround for https://github.com/facebook/flow/issues/2360 - ): Connector } & OP>>; + declare type MapStateToPropsEx = ( + state: S, + props: SP, + ) => RSP; - declare function connect( - mapStateToProps: Null, - mapDispatchToProps: Null, - mergeProps: Null, - options: ConnectOptions - ): Connector } & OP>>; + declare type SelectorFactory< + Com: React$ComponentType<*>, + Dispatch, + S: Object, + OP: Object, + EFO: Object, + CP: Object, + > = ( + dispatch: Dispatch, + factoryOptions: SelectorFactoryOptions & EFO, + ) => MapStateToPropsEx; - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: Null, - mergeProps: Null, - options?: ConnectOptions - ): Connector } & OP>>; + declare export function connectAdvanced< + Com: React$ComponentType<*>, + D, + S: Object, + OP: Object, + CP: Object, + EFO: Object, + ST: { [_: $Keys]: any }, + >( + selectorFactory: SelectorFactory, + connectAdvancedOptions: ?(ConnectAdvancedOptions & EFO), + ): (component: Com) => React$ComponentType & $Shape; - declare function connect( - mapStateToProps: Null, - mapDispatchToProps: MapDispatchToProps, - mergeProps: Null, - options?: ConnectOptions - ): Connector>; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: MapDispatchToProps, - mergeProps: Null, - options?: ConnectOptions - ): Connector>; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: Null, - mergeProps: MergeProps, - options?: ConnectOptions - ): Connector; - - declare function connect( - mapStateToProps: MapStateToProps, - mapDispatchToProps: MapDispatchToProps, - mergeProps: MergeProps, - options?: ConnectOptions - ): Connector; + declare export default { + Provider: typeof Provider, + createProvider: typeof createProvider, + connect: typeof connect, + connectAdvanced: typeof connectAdvanced, + }; } diff --git a/flow-typed/npm/react-router-dom_v5.x.x.js b/flow-typed/npm/react-router-dom_v5.x.x.js new file mode 100644 index 0000000..048fc19 --- /dev/null +++ b/flow-typed/npm/react-router-dom_v5.x.x.js @@ -0,0 +1,176 @@ +// flow-typed signature: 9987f80c12a2cad7dfa2b08cc14d2edc +// flow-typed version: 2973a15489/react-router-dom_v5.x.x/flow_>=v0.98.x + +declare module "react-router-dom" { + declare export var BrowserRouter: React$ComponentType<{| + basename?: string, + forceRefresh?: boolean, + getUserConfirmation?: GetUserConfirmation, + keyLength?: number, + children?: React$Node + |}> + + declare export var HashRouter: React$ComponentType<{| + basename?: string, + getUserConfirmation?: GetUserConfirmation, + hashType?: "slash" | "noslash" | "hashbang", + children?: React$Node + |}> + + declare export var Link: React$ComponentType<{ + className?: string, + to: string | LocationShape, + replace?: boolean, + children?: React$Node + }> + + declare export var NavLink: React$ComponentType<{ + to: string | LocationShape, + activeClassName?: string, + className?: string, + activeStyle?: { +[string]: mixed }, + style?: { +[string]: mixed }, + isActive?: (match: Match, location: Location) => boolean, + children?: React$Node, + exact?: boolean, + strict?: boolean + }> + + // NOTE: Below are duplicated from react-router. If updating these, please + // update the react-router and react-router-native types as well. + declare export type Location = { + pathname: string, + search: string, + hash: string, + state?: any, + key?: string + }; + + declare export type LocationShape = { + pathname?: string, + search?: string, + hash?: string, + state?: any + }; + + declare export type HistoryAction = "PUSH" | "REPLACE" | "POP"; + + declare export type RouterHistory = { + length: number, + location: Location, + action: HistoryAction, + listen( + callback: (location: Location, action: HistoryAction) => void + ): () => void, + push(path: string | LocationShape, state?: any): void, + replace(path: string | LocationShape, state?: any): void, + go(n: number): void, + goBack(): void, + goForward(): void, + canGo?: (n: number) => boolean, + block( + callback: string | (location: Location, action: HistoryAction) => ?string + ): () => void, + // createMemoryHistory + index?: number, + entries?: Array + }; + + declare export type Match = { + params: { [key: string]: ?string }, + isExact: boolean, + path: string, + url: string + }; + + declare export type ContextRouter = {| + history: RouterHistory, + location: Location, + match: Match, + staticContext?: StaticRouterContext + |}; + + declare type ContextRouterVoid = { + history: RouterHistory | void, + location: Location | void, + match: Match | void, + staticContext?: StaticRouterContext | void + }; + + declare export type GetUserConfirmation = ( + message: string, + callback: (confirmed: boolean) => void + ) => void; + + declare export type StaticRouterContext = { + url?: string + }; + + declare export var StaticRouter: React$ComponentType<{| + basename?: string, + location?: string | Location, + context: StaticRouterContext, + children?: React$Node + |}> + + declare export var MemoryRouter: React$ComponentType<{| + initialEntries?: Array, + initialIndex?: number, + getUserConfirmation?: GetUserConfirmation, + keyLength?: number, + children?: React$Node + |}> + + declare export var Router: React$ComponentType<{| + history: RouterHistory, + children?: React$Node + |}> + + declare export var Prompt: React$ComponentType<{| + message: string | ((location: Location) => string | boolean), + when?: boolean + |}> + + declare export var Redirect: React$ComponentType<{| + to: string | LocationShape, + push?: boolean, + from?: string, + exact?: boolean, + strict?: boolean + |}> + + declare export var Route: React$ComponentType<{| + component?: React$ComponentType<*>, + render?: (router: ContextRouter) => React$Node, + children?: React$ComponentType | React$Node, + path?: string | Array, + exact?: boolean, + strict?: boolean, + location?: LocationShape, + sensitive?: boolean + |}> + + declare export var Switch: React$ComponentType<{| + children?: React$Node, + location?: Location + |}> + + declare export function withRouter>( + WrappedComponent: Component + ): React$ComponentType<$Diff, ContextRouterVoid>>; + + declare type MatchPathOptions = { + path?: string, + exact?: boolean, + sensitive?: boolean, + strict?: boolean + }; + + declare export function matchPath( + pathname: string, + options?: MatchPathOptions | string, + parent?: Match + ): null | Match; + + declare export function generatePath(pattern?: string, params?: { +[string]: mixed }): string; +} diff --git a/flow-typed/npm/react-router_v4.x.x.js b/flow-typed/npm/react-router_v4.x.x.js deleted file mode 100644 index c456f47..0000000 --- a/flow-typed/npm/react-router_v4.x.x.js +++ /dev/null @@ -1,139 +0,0 @@ -// flow-typed signature: b45080e7e6a55f1c9092f07c205cd527 -// flow-typed version: 3e35e41eb5/react-router_v4.x.x/flow_v0.53.x - -// flow-typed signature: b701192ca557cf27adf1b295517299fd -// flow-typed version: b43dff3e0e/react-router_v4.x.x/flow_>=v0.53.x -import * as React from "react"; - -declare module "react-router" { - // NOTE: many of these are re-exported by react-router-dom and - // react-router-native, so when making changes, please be sure to update those - // as well. - declare export type Location = { - pathname: string, - search: string, - hash: string, - state?: any, - key?: string - }; - - declare export type LocationShape = { - pathname?: string, - search?: string, - hash?: string, - state?: any - }; - - declare export type HistoryAction = "PUSH" | "REPLACE" | "POP"; - - declare export type RouterHistory = { - length: number, - location: Location, - action: HistoryAction, - listen( - callback: (location: Location, action: HistoryAction) => void - ): () => void, - push(path: string | LocationShape, state?: any): void, - replace(path: string | LocationShape, state?: any): void, - go(n: number): void, - goBack(): void, - goForward(): void, - canGo?: (n: number) => boolean, - block( - callback: (location: Location, action: HistoryAction) => boolean - ): void, - // createMemoryHistory - index?: number, - entries?: Array - }; - - declare export type Match = { - params: { [key: string]: ?string }, - isExact: boolean, - path: string, - url: string - }; - - declare export type ContextRouter = { - history: RouterHistory, - location: Location, - match: Match - }; - - declare export type GetUserConfirmation = ( - message: string, - callback: (confirmed: boolean) => void - ) => void; - - declare type StaticRouterContext = { - url?: string - }; - - declare type StaticRouterProps = { - basename?: string, - location?: string | Location, - context: StaticRouterContext, - children?: React$Element<*> - }; - declare export class StaticRouter extends React$Component< - StaticRouterProps - > {} - - declare type MemoryRouterProps = { - initialEntries?: Array, - initialIndex?: number, - getUserConfirmation?: GetUserConfirmation, - keyLength?: number, - children?: React$Element<*> - }; - declare export class MemoryRouter extends React$Component< - MemoryRouterProps - > {} - - declare type RouterProps = { - history: RouterHistory, - children?: React$Element<*> - }; - declare export class Router extends React$Component {} - - declare type PromptProps = { - message: string | ((location: Location) => string | true), - when?: boolean - }; - declare export class Prompt extends React$Component {} - - declare type RedirectProps = { - to: string | LocationShape, - push?: boolean - }; - declare export class Redirect extends React$Component {} - - declare type RouteProps = { - component?: React$ComponentType<*>, - render?: (router: ContextRouter) => React$Element<*>, - children?: (router: ContextRouter) => React$Element<*>, - path?: string, - exact?: boolean, - strict?: boolean - }; - declare export class Route extends React$Component {} - - declare type SwithcProps = { - children?: Array> - }; - declare export class Switch extends React$Component {} - - declare export function withRouter

( - Component: React$ComponentType - ): React$ComponentType

; - - declare type MatchPathOptions = { - exact?: boolean, - strict?: boolean - }; - declare export function matchPath( - pathname: string, - path: string, - options?: MatchPathOptions - ): null | Match; -} diff --git a/flow-typed/npm/redux_v3.x.x.js b/flow-typed/npm/redux_v3.x.x.js deleted file mode 100644 index f6445d9..0000000 --- a/flow-typed/npm/redux_v3.x.x.js +++ /dev/null @@ -1,109 +0,0 @@ -// flow-typed signature: 86993bd000012d3e1ef10d757d16952d -// flow-typed version: a165222d28/redux_v3.x.x/flow_>=v0.33.x - -declare module 'redux' { - - /* - - S = State - A = Action - D = Dispatch - - */ - - declare type DispatchAPI = (action: A) => A; - declare type Dispatch }> = DispatchAPI; - - declare type MiddlewareAPI> = { - dispatch: D; - getState(): S; - }; - - declare type Store> = { - // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages) - dispatch: D; - getState(): S; - subscribe(listener: () => void): () => void; - replaceReducer(nextReducer: Reducer): void - }; - - declare type Reducer = (state: S, action: A) => S; - - declare type CombinedReducer = (state: $Shape & {} | void, action: A) => S; - - declare type Middleware> = - (api: MiddlewareAPI) => - (next: D) => D; - - declare type StoreCreator> = { - (reducer: Reducer, enhancer?: StoreEnhancer): Store; - (reducer: Reducer, preloadedState: S, enhancer?: StoreEnhancer): Store; - }; - - declare type StoreEnhancer> = (next: StoreCreator) => StoreCreator; - - declare function createStore(reducer: Reducer, enhancer?: StoreEnhancer): Store; - declare function createStore(reducer: Reducer, preloadedState: S, enhancer?: StoreEnhancer): Store; - - declare function applyMiddleware(...middlewares: Array>): StoreEnhancer; - - declare type ActionCreator = (...args: Array) => A; - declare type ActionCreators = { [key: K]: ActionCreator }; - - declare function bindActionCreators, D: DispatchAPI>(actionCreator: C, dispatch: D): C; - declare function bindActionCreators, D: DispatchAPI>(actionCreators: C, dispatch: D): C; - - declare function combineReducers(reducers: O): CombinedReducer<$ObjMap(r: Reducer) => S>, A>; - - declare function compose(ab: (a: A) => B): (a: A) => B - declare function compose( - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => C - declare function compose( - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => D - declare function compose( - de: (d: D) => E, - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => E - declare function compose( - ef: (e: E) => F, - de: (d: D) => E, - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => F - declare function compose( - fg: (f: F) => G, - ef: (e: E) => F, - de: (d: D) => E, - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => G - declare function compose( - gh: (g: G) => H, - fg: (f: F) => G, - ef: (e: E) => F, - de: (d: D) => E, - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => H - declare function compose( - hi: (h: H) => I, - gh: (g: G) => H, - fg: (f: F) => G, - ef: (e: E) => F, - de: (d: D) => E, - cd: (c: C) => D, - bc: (b: B) => C, - ab: (a: A) => B - ): (a: A) => I - -} diff --git a/flow-typed/npm/redux_v4.x.x.js b/flow-typed/npm/redux_v4.x.x.js new file mode 100644 index 0000000..2ba2c8b --- /dev/null +++ b/flow-typed/npm/redux_v4.x.x.js @@ -0,0 +1,100 @@ +// flow-typed signature: a49a6c96fe8a8bb3330cce2028588f4c +// flow-typed version: de5b3a01c6/redux_v4.x.x/flow_>=v0.89.x + +declare module 'redux' { + /* + + S = State + A = Action + D = Dispatch + + */ + + declare export type Action = { + type: T + } + + declare export type DispatchAPI = (action: A) => A; + + declare export type Dispatch = DispatchAPI; + + declare export type MiddlewareAPI> = { + dispatch: D, + getState(): S, + }; + + declare export type Store> = { + // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages) + dispatch: D, + getState(): S, + subscribe(listener: () => void): () => void, + replaceReducer(nextReducer: Reducer): void, + }; + + declare export type Reducer = (state: S | void, action: A) => S; + + declare export type CombinedReducer = ( + state: ($Shape & {}) | void, + action: A + ) => S; + + declare export type Middleware> = ( + api: MiddlewareAPI + ) => (next: D) => D; + + declare export type StoreCreator> = { + (reducer: Reducer, enhancer?: StoreEnhancer): Store, + ( + reducer: Reducer, + preloadedState: S, + enhancer?: StoreEnhancer + ): Store, + }; + + declare export type StoreEnhancer> = ( + next: StoreCreator + ) => StoreCreator; + + declare export function createStore( + reducer: Reducer, + enhancer?: StoreEnhancer + ): Store; + declare export function createStore( + reducer: Reducer, + preloadedState?: S, + enhancer?: StoreEnhancer + ): Store; + + declare export function applyMiddleware( + ...middlewares: Array> + ): StoreEnhancer; + + declare export type ActionCreator = (...args: Array) => A; + declare export type ActionCreators = { + [key: K]: ActionCreator, + }; + + declare export function bindActionCreators< + A, + C: ActionCreator, + D: DispatchAPI + >( + actionCreator: C, + dispatch: D + ): C; + declare export function bindActionCreators< + A, + K, + C: ActionCreators, + D: DispatchAPI + >( + actionCreators: C, + dispatch: D + ): C; + + declare export function combineReducers( + reducers: O + ): CombinedReducer<$ObjMap(r: Reducer) => S>, A>; + + declare export var compose: $Compose; +} diff --git a/package.json b/package.json index ab3494c..9f9f2b2 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "scripts": { "start": "yarn run clean && yarn run build:dll && NODE_PATH=./src webpack-dev-server --progress --colors", "clean": "rm -rf dist/", + "e2e": "yarn --cwd ./tests-e2e test", "test": "yarn run build:dll && NODE_PATH=./src karma start ./karma.conf.js", "lint": "eslint ./src", "flow": "flow", @@ -39,9 +40,7 @@ "copy-to-clipboard": "^3.0.8", "debounce": "^1.0.0", "flag-icon-css": "^2.8.0", - "intl": "^1.2.2", - "intl-format-cache": "^2.0.4", - "intl-messageformat": "^2.1.0", + "intl": "^1.2.5", "promise.prototype.finally": "3.1.0", "prop-types": "^15.6.2", "raf": "^3.4.1", @@ -51,14 +50,14 @@ "react-helmet": "^5.0.0", "react-intl": "^2.7.2", "react-motion": "^0.5.0", - "react-redux": "^5.0.6", - "react-router-dom": "^4.3.1", + "react-redux": "^7.1.0", + "react-router-dom": "^5.0.1", "react-textarea-autosize": "^6.0.0", - "react-transition-group": "^1.1.3", - "redux": "^3.0.4", + "react-transition-group": "^4.2.0", + "redux": "^4.0.1", "redux-localstorage": "^0.4.1", "redux-thunk": "^2.0.0", - "url-search-params-polyfill": "^5.0.0", + "url-search-params-polyfill": "^6.0.0", "webfontloader": "^1.6.26", "whatwg-fetch": "^3.0.0" }, @@ -90,22 +89,22 @@ "exports-loader": "^0.6.3", "extract-text-webpack-plugin": "^1.0.0", "file-loader": "^0.11.0", - "flow-bin": "~0.80.0", + "flow-bin": "~0.102.0", "fontgen-loader": "^0.2.1", "html-loader": "^0.4.3", "html-webpack-plugin": "^2.0.0", "imports-loader": "^0.7.0", - "jsdom": "^9.8.3", + "jsdom": "^15.1.1", "json-loader": "^0.5.4", - "karma": "^1.1.0", - "karma-jsdom-launcher": "^6.0.0", + "karma": "^4.1.0", + "karma-jsdom-launcher": "^7.1.1", "karma-mocha": "^1.0.0", "karma-nyan-reporter": "^0.2.3", "karma-sinon": "^1.0.4", "karma-sourcemap-loader": "*", "karma-webpack": "^2.0.0", "loader-utils": "^1.0.0", - "mocha": "^3.0.2", + "mocha": "^6.1.4", "node-sass": "^4.7.2", "postcss-import": "^9.0.0", "postcss-loader": "^1.2.0", @@ -115,10 +114,10 @@ "react-test-renderer": "^16.7.0", "sass-loader": "^4.0.0", "scripts": "file:./scripts", - "sinon": "^3.2.1", + "sinon": "^7.3.2", "sitemap-webpack-plugin": "^0.5.1", "style-loader": "^0.18.0", - "unexpected": "^10.33.2", + "unexpected": "^11.6.1", "unexpected-sinon": "^10.5.1", "url-loader": "^0.5.7", "webpack": "^1.12.9", diff --git a/src/components/accounts/actions.test.js b/src/components/accounts/actions.test.js index 7255945..96b51c0 100644 --- a/src/components/accounts/actions.test.js +++ b/src/components/accounts/actions.test.js @@ -1,4 +1,4 @@ -import expect from 'unexpected'; +import expect from 'test/unexpected'; import sinon from 'sinon'; import { browserHistory } from 'services/history'; @@ -445,8 +445,9 @@ describe('components/accounts/actions', () => { return logoutStrangers()(dispatch, getState) .then(() => - expect(dispatch, 'was always called with', - expect.it('not to satisfy', activate(account))) + expect(dispatch, 'not to have calls satisfying', + [activate(account)] + ) ); }); @@ -511,8 +512,8 @@ describe('components/accounts/actions', () => { }); it('should not log out', () => - expect(dispatch, 'was always called with', - expect.it('not to equal', {payload: foreignAccount}) + expect(dispatch, 'not to have calls satisfying', + [{payload: foreignAccount}] ) ); }); diff --git a/src/components/accounts/reducer.test.js b/src/components/accounts/reducer.test.js index 989f8cf..7746c96 100644 --- a/src/components/accounts/reducer.test.js +++ b/src/components/accounts/reducer.test.js @@ -1,4 +1,4 @@ -import expect from 'unexpected'; +import expect from 'test/unexpected'; import accounts from 'components/accounts/reducer'; import { diff --git a/src/components/auth/PanelTransition.js b/src/components/auth/PanelTransition.js index c3d5361..4c5a2ad 100644 --- a/src/components/auth/PanelTransition.js +++ b/src/components/auth/PanelTransition.js @@ -1,7 +1,7 @@ // @flow import type { User } from 'components/user'; import type { AccountsState } from 'components/accounts'; -import type { Node, Element } from 'react'; +import type { Element } from 'react'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; @@ -24,6 +24,8 @@ const opacitySpringConfig = {stiffness: 300, damping: 20}; const transformSpringConfig = {stiffness: 500, damping: 50, precision: 0.5}; const changeContextSpringConfig = {stiffness: 500, damping: 20, precision: 0.5}; +type PanelId = string; + /** * Definition of relation between contexts and panels * @@ -35,7 +37,7 @@ const changeContextSpringConfig = {stiffness: 500, damping: 20, precision: 0.5}; * - Panel index defines the direction of X transition of both panels * (e.g. the panel with lower index will slide from left side, and with greater from right side) */ -const contexts = [ +const contexts: Array = [ ['login', 'password', 'forgotPassword', 'mfa', 'recoverPassword'], ['register', 'activation', 'resendActivation'], ['acceptRules'], @@ -71,18 +73,27 @@ type AnimationProps = {| |}; type AnimationContext = { - key: string, + key: PanelId, style: AnimationProps, data: { - Title: Node, + Title: Element, Body: Element, - Footer: Node, - Links: Node, + Footer: Element, + Links: Element, hasBackButton: bool, } }; +type OwnProps = {| + Title: Element, + Body: Element, + Footer: Element, + Links: Element, + children?: Element +|}; + type Props = { + ...OwnProps, // context props auth: { error: string | { @@ -98,20 +109,12 @@ type Props = { clearErrors: () => void, resolve: () => void, reject: () => void, - - - // local props - Title: Node, - Body: typeof Component, - Footer: Node, - Links: Node, - children: Node }; type State = { contextHeight: number, - panelId: string | void, - prevPanelId: string | void, + panelId: PanelId | void, + prevPanelId: PanelId | void, isHeightDirty: bool, forceHeight: 1 | 0, direction: 'X' | 'Y', @@ -187,7 +190,7 @@ class PanelTransition extends Component { return { auth: this.props.auth, user: this.props.user, - requestRedraw: () => + requestRedraw: (): Promise => new Promise((resolve) => this.setState( {isHeightDirty: true}, @@ -207,9 +210,9 @@ class PanelTransition extends Component { }; } - componentWillReceiveProps(nextProps) { - const nextPanel = nextProps.Body && (nextProps.Body: any).type.panelId; - const prevPanel = this.props.Body && (this.props.Body: any).type.panelId; + componentWillReceiveProps(nextProps: Props) { + const nextPanel: PanelId = nextProps.Body && (nextProps.Body: any).type.panelId; + const prevPanel: PanelId = this.props.Body && (this.props.Body: any).type.panelId; if (nextPanel !== prevPanel) { const direction = this.getDirection(nextPanel, prevPanel); @@ -250,7 +253,7 @@ class PanelTransition extends Component { } const {panelId, hasGoBack}: { - panelId: string, + panelId: PanelId, hasGoBack: bool, } = (Body: any).type; @@ -336,10 +339,10 @@ class PanelTransition extends Component { } }; - onFormInvalid = (errors) => this.props.setErrors(errors); + onFormInvalid = (errors: { [key: string]: ValidationError }) => this.props.setErrors(errors); - willEnter = (config) => this.getTransitionStyles(config); - willLeave = (config) => this.getTransitionStyles(config, {isLeave: true}); + willEnter = (config: AnimationContext) => this.getTransitionStyles(config); + willLeave = (config: AnimationContext) => this.getTransitionStyles(config, {isLeave: true}); /** * @param {object} config @@ -349,7 +352,7 @@ class PanelTransition extends Component { * * @return {object} */ - getTransitionStyles({key}, options = {}): {| + getTransitionStyles({key}: AnimationContext, options: { isLeave?: bool } = {}): {| transformSpring: number, opacitySpring: number, |} { @@ -380,7 +383,7 @@ class PanelTransition extends Component { }; } - getDirection(next, prev): 'X' | 'Y' { + getDirection(next: PanelId, prev: PanelId): 'X' | 'Y' { const context = contexts.find((context) => context.includes(prev)); if (!context) { @@ -390,7 +393,7 @@ class PanelTransition extends Component { return context.includes(next) ? 'X' : 'Y'; } - onUpdateHeight = (height, key) => { + onUpdateHeight = (height: number, key: PanelId) => { const heightKey = `formHeight${key}`; this.setState({ @@ -398,13 +401,13 @@ class PanelTransition extends Component { }); }; - onUpdateContextHeight = (height) => { + onUpdateContextHeight = (height: number) => { this.setState({ contextHeight: height }); }; - onGoBack = (event) => { + onGoBack = (event: SyntheticEvent) => { event.preventDefault(); authFlow.goBack(); @@ -415,7 +418,7 @@ class PanelTransition extends Component { * * @param {number} length number of panels transitioned */ - tryToAutoFocus(length) { + tryToAutoFocus(length: number) { if (!this.body) { return; } @@ -588,7 +591,7 @@ class PanelTransition extends Component { * * @return {object} */ - translate(value, direction = 'X', unit = '%') { + translate(value: number, direction: 'X' | 'Y' = 'X', unit: '%' | 'px' = '%') { return { WebkitTransform: `translate${direction}(${value}${unit})`, transform: `translate${direction}(${value}${unit})` @@ -596,7 +599,7 @@ class PanelTransition extends Component { } } -export default connect((state) => { +export default connect((state) => { const login = getLogin(state); let user = { ...state.user diff --git a/src/components/auth/actions.js b/src/components/auth/actions.js index 089c933..a8aaa0f 100644 --- a/src/components/auth/actions.js +++ b/src/components/auth/actions.js @@ -1,5 +1,5 @@ // @flow -import type { OauthData } from 'services/api/oauth'; +import type { OauthData, Client, Scope } from 'services/api/oauth'; import type { OAuthResponse } from 'services/api/authentication'; import { browserHistory } from 'services/history'; import logger from 'services/logger'; @@ -19,8 +19,14 @@ import signup from 'services/api/signup'; import dispatchBsod from 'components/ui/bsod/dispatchBsod'; import { create as createPopup } from 'components/ui/popup/actions'; import ContactForm from 'components/contact/ContactForm'; + import { getCredentials } from './reducer'; +type ValidationError = string | { + type: string, + payload: { [key: string]: any }, +}; + export { updateUser } from 'components/user/actions'; export { authenticate, @@ -212,7 +218,7 @@ export function resendActivation({ } export function contactUs() { - return createPopup(ContactForm); + return createPopup({ Popup: ContactForm }); } export const SET_CREDENTIALS = 'auth:setCredentials'; @@ -283,7 +289,7 @@ export function setAccountSwitcher(isOn: bool) { } export const ERROR = 'auth:error'; -export function setErrors(errors: ?{[key: string]: string}) { +export function setErrors(errors: ?{[key: string]: ValidationError}) { return { type: ERROR, payload: errors, @@ -413,11 +419,7 @@ export function setClient({ id, name, description -}: { - id: string, - name: string, - description: string -}) { +}: Client) { return { type: SET_CLIENT, payload: {id, name, description} @@ -502,7 +504,7 @@ export function requirePermissionsAccept() { } export const SET_SCOPES = 'set_scopes'; -export function setScopes(scopes: Array) { +export function setScopes(scopes: Scope[]) { if (!(scopes instanceof Array)) { throw new Error('Scopes must be array'); } diff --git a/src/components/auth/actions.test.js b/src/components/auth/actions.test.js index 8fda580..ca1afa1 100644 --- a/src/components/auth/actions.test.js +++ b/src/components/auth/actions.test.js @@ -1,5 +1,5 @@ import sinon from 'sinon'; -import expect from 'unexpected'; +import expect from 'test/unexpected'; import request from 'services/request'; diff --git a/src/components/auth/reducer.js b/src/components/auth/reducer.js index c31ca35..c8a4d79 100644 --- a/src/components/auth/reducer.js +++ b/src/components/auth/reducer.js @@ -19,10 +19,10 @@ type Credentials = { rememberMe?: bool, returnUrl?: string, isRelogin?: bool, - isTotpRequired?: bool, + isTotpRequired?: bool }; -export default combineReducers({ +export default combineReducers<_, { action: string, payload?: mixed }>({ credentials, error, isLoading, @@ -32,10 +32,7 @@ export default combineReducers({ scopes }); -function error( - state = null, - {type, payload = null, error = false} -) { +function error(state = null, { type, payload = null, error = false }) { switch (type) { case ERROR: if (!error) { @@ -51,15 +48,16 @@ function error( function credentials( state = {}, - {type, payload}: { + { + type, + payload + }: { type: string, payload: ?Credentials } ) { if (type === SET_CREDENTIALS) { - if (payload - && typeof payload === 'object' - ) { + if (payload && typeof payload === 'object') { return { ...payload }; @@ -71,10 +69,7 @@ function credentials( return state; } -function isSwitcherEnabled( - state = true, - {type, payload = false} -) { +function isSwitcherEnabled(state = true, { type, payload = false }) { switch (type) { case SET_SWITCHER: if (typeof payload !== 'boolean') { @@ -88,10 +83,7 @@ function isSwitcherEnabled( } } -function isLoading( - state = false, - {type, payload = null} -) { +function isLoading(state = false, { type, payload = null }) { switch (type) { case SET_LOADING_STATE: return !!payload; @@ -101,10 +93,7 @@ function isLoading( } } -function client( - state = null, - {type, payload = {}} -) { +function client(state = null, { type, payload = {} }) { switch (type) { case SET_CLIENT: return { @@ -118,10 +107,7 @@ function client( } } -function oauth( - state = null, - {type, payload = {}} -) { +function oauth(state = null, { type, payload = {} }) { switch (type) { case SET_OAUTH: return { @@ -153,10 +139,7 @@ function oauth( } } -function scopes( - state = [], - {type, payload = []} -) { +function scopes(state = [], { type, payload = [] }) { switch (type) { case SET_SCOPES: return payload; diff --git a/src/components/auth/reducer.test.js b/src/components/auth/reducer.test.js index 4961712..d32dae6 100644 --- a/src/components/auth/reducer.test.js +++ b/src/components/auth/reducer.test.js @@ -1,4 +1,4 @@ -import expect from 'unexpected'; +import expect from 'test/unexpected'; import auth from 'components/auth/reducer'; import { diff --git a/src/components/contact/ContactForm.js b/src/components/contact/ContactForm.js index 832d16d..de8ab3d 100644 --- a/src/components/contact/ContactForm.js +++ b/src/components/contact/ContactForm.js @@ -1,9 +1,8 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; - +import { connect } from 'react-redux'; import classNames from 'classnames'; import { FormattedMessage as Message } from 'react-intl'; - import { Input, TextArea, Button, Form, FormModel, Dropdown } from 'components/ui/form'; import feedback from 'services/api/feedback'; import icons from 'components/ui/icons.scss'; @@ -174,8 +173,6 @@ export class ContactForm extends Component { }; } -import { connect } from 'react-redux'; - export default connect((state) => ({ user: state.user }))(ContactForm); diff --git a/src/components/contact/ContactForm.test.js b/src/components/contact/ContactForm.test.js index 6c1b157..fc933d2 100644 --- a/src/components/contact/ContactForm.test.js +++ b/src/components/contact/ContactForm.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import expect from 'unexpected'; +import expect from 'test/unexpected'; import sinon from 'sinon'; import { shallow, mount } from 'enzyme'; diff --git a/src/components/contact/ContactLink.js b/src/components/contact/ContactLink.js index a7f20bd..27498cc 100644 --- a/src/components/contact/ContactLink.js +++ b/src/components/contact/ContactLink.js @@ -1,16 +1,21 @@ // @flow +import type { ElementConfig } from 'react'; import React from 'react'; import { connect } from 'react-redux'; import { create as createPopup } from 'components/ui/popup/actions'; import ContactForm from './ContactForm'; +type OwnProps = $Exact>; + +type Props = { + ...OwnProps, + createContactPopup: () => void, +}; + function ContactLink({ createContactPopup, ...props -}: { - createContactPopup: () => void, - props: Object -}) { +}: Props) { return ( ( null, { - createContactPopup: () => createPopup(ContactForm) + createContactPopup: () => createPopup({ Popup: ContactForm }) } )(ContactLink); diff --git a/src/components/dev/apps/applicationForm/ApplicationForm.js b/src/components/dev/apps/applicationForm/ApplicationForm.js index 12a2618..282a3f8 100644 --- a/src/components/dev/apps/applicationForm/ApplicationForm.js +++ b/src/components/dev/apps/applicationForm/ApplicationForm.js @@ -97,7 +97,7 @@ export default class ApplicationForm extends Component<{ - {FormComponent && ( + {!!FormComponent && (