mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-26 16:52:06 +05:30
Major deps updates: router, redux, intl, react-transition-group, flow-type, testing deps
This commit is contained in:
parent
6821bcfe40
commit
627d503d43
79
flow-typed/npm/react-intl_v2.x.x.js
vendored
79
flow-typed/npm/react-intl_v2.x.x.js
vendored
@ -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,39 +7,39 @@
|
||||
* https://github.com/marudor/flowInterfaces/issues/6
|
||||
*/
|
||||
// Mostly from https://github.com/yahoo/react-intl/wiki/API#react-intl-api
|
||||
declare module "react-intl" {
|
||||
import type { Element, ChildrenArray } from "react";
|
||||
|
||||
import type { Element, ChildrenArray } from "react";
|
||||
|
||||
type $npm$ReactIntl$LocaleData = {
|
||||
declare type $npm$ReactIntl$LocaleData = {
|
||||
locale: string,
|
||||
[key: string]: any
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$MessageDescriptor = {
|
||||
declare type $npm$ReactIntl$MessageDescriptor = {
|
||||
id: string,
|
||||
description?: string,
|
||||
defaultMessage?: string
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$IntlConfig = {
|
||||
declare type $npm$ReactIntl$IntlConfig = {
|
||||
locale: string,
|
||||
formats: Object,
|
||||
messages: { [id: string]: string },
|
||||
|
||||
defaultLocale?: string,
|
||||
defaultFormats?: Object
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$IntlProviderConfig = {
|
||||
declare type $npm$ReactIntl$IntlProviderConfig = {
|
||||
locale?: string,
|
||||
formats?: Object,
|
||||
messages?: { [id: string]: string },
|
||||
|
||||
defaultLocale?: string,
|
||||
defaultFormats?: Object
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$IntlFormat = {
|
||||
declare type $npm$ReactIntl$IntlFormat = {
|
||||
formatDate: (value: any, options?: Object) => string,
|
||||
formatTime: (value: any, options?: Object) => string,
|
||||
formatRelative: (value: any, options?: Object) => string,
|
||||
@ -53,12 +53,12 @@ type $npm$ReactIntl$IntlFormat = {
|
||||
messageDescriptor: $npm$ReactIntl$MessageDescriptor,
|
||||
values?: Object
|
||||
) => string
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig &
|
||||
declare type $npm$ReactIntl$IntlShape = $npm$ReactIntl$IntlConfig &
|
||||
$npm$ReactIntl$IntlFormat & { now: () => number };
|
||||
|
||||
type $npm$ReactIntl$DateTimeFormatOptions = {
|
||||
declare type $npm$ReactIntl$DateTimeFormatOptions = {
|
||||
localeMatcher?: "best fit" | "lookup",
|
||||
formatMatcher?: "basic" | "best fit",
|
||||
|
||||
@ -74,14 +74,14 @@ type $npm$ReactIntl$DateTimeFormatOptions = {
|
||||
minute?: "numeric" | "2-digit",
|
||||
second?: "numeric" | "2-digit",
|
||||
timeZoneName?: "short" | "long"
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$RelativeFormatOptions = {
|
||||
declare type $npm$ReactIntl$RelativeFormatOptions = {
|
||||
style?: "best fit" | "numeric",
|
||||
units?: "second" | "minute" | "hour" | "day" | "month" | "year"
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$NumberFormatOptions = {
|
||||
declare type $npm$ReactIntl$NumberFormatOptions = {
|
||||
localeMatcher?: "best fit" | "lookup",
|
||||
|
||||
style?: "decimal" | "currency" | "percent",
|
||||
@ -96,13 +96,13 @@ type $npm$ReactIntl$NumberFormatOptions = {
|
||||
maximumFractionDigits?: number,
|
||||
minimumSignificantDigits?: number,
|
||||
maximumSignificantDigits?: number
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$PluralFormatOptions = {
|
||||
declare type $npm$ReactIntl$PluralFormatOptions = {
|
||||
style?: "cardinal" | "ordinal"
|
||||
};
|
||||
};
|
||||
|
||||
type $npm$ReactIntl$PluralCategoryString =
|
||||
declare type $npm$ReactIntl$PluralCategoryString =
|
||||
| "zero"
|
||||
| "one"
|
||||
| "two"
|
||||
@ -110,9 +110,7 @@ type $npm$ReactIntl$PluralCategoryString =
|
||||
| "many"
|
||||
| "other";
|
||||
|
||||
type $npm$ReactIntl$DateParseable = number | string | Date;
|
||||
|
||||
declare module "react-intl" {
|
||||
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<DefaultProps: {}, Props: {}> =
|
||||
| React$ComponentType<Props>
|
||||
| React$StatelessFunctionalComponent<Props>
|
||||
@ -152,19 +154,12 @@ declare module "react-intl" {
|
||||
IntlInjectedComponent<TOwnProps, TDefaultProps>
|
||||
>;
|
||||
|
||||
declare function injectIntl<OriginalProps: InjectIntlProvidedProps, DefaultProps: {}>
|
||||
(
|
||||
component: ComponentWithDefaultProps<DefaultProps, OriginalProps>,
|
||||
declare function injectIntl<P: {}, Component: React$ComponentType<P>>(
|
||||
WrappedComponent: Component,
|
||||
options?: InjectIntlOptions,
|
||||
):
|
||||
IntlInjectedComponentClass<$Diff<OriginalProps, InjectIntlProvidedProps>, DefaultProps>
|
||||
|
||||
declare function injectIntl<OriginalProps: InjectIntlProvidedProps>
|
||||
(
|
||||
component: React$ComponentType<OriginalProps>,
|
||||
options?: InjectIntlOptions,
|
||||
):
|
||||
IntlInjectedComponentClass<$Diff<OriginalProps, InjectIntlProvidedProps>>;
|
||||
): React$ComponentType<
|
||||
$Diff<React$ElementConfig<Component>, 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>) => React$Node
|
||||
children?:
|
||||
| ((...formattedMessage: Array<React$Node>) => React$Node)
|
||||
| (string => React$Node)
|
||||
}
|
||||
> {}
|
||||
declare class FormattedHTMLMessage extends React$Component<
|
||||
|
328
flow-typed/npm/react-redux_v5.x.x.js
vendored
328
flow-typed/npm/react-redux_v5.x.x.js
vendored
@ -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<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(…)
|
||||
|
||||
declare module "react-redux" {
|
||||
/*
|
||||
In Flow v0.89 only the first two are mandatory to specify. Other 4 can be repaced with the new awesome type placeholder:
|
||||
|
||||
connect<Props, OwnProps, _, _, _, _>(…)
|
||||
|
||||
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
|
||||
A = Action
|
||||
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()
|
||||
// ------------------------------------------------------------
|
||||
|
||||
declare type MapStateToProps<S, OP: Object, SP: Object> = (
|
||||
state: S,
|
||||
ownProps: OP
|
||||
) => SP | MapStateToProps<S, OP, SP>;
|
||||
declare export type Options<S, OP, SP, MP> = {|
|
||||
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 MapDispatchToProps<A, OP: Object, DP: Object> =
|
||||
| ((dispatch: Dispatch<A>, ownProps: OP) => DP)
|
||||
| DP;
|
||||
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 MergeProps<SP, DP: Object, OP: Object, P: Object> = (
|
||||
declare type Bind<D> = <A, R>((...A) => R) => (...A) => $Call<D, R>;
|
||||
|
||||
declare type MapDispatchToPropsFn<D, -OP, +DP> =
|
||||
| ((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 class ConnectedComponent<OP, +WC> extends React$Component<OP> {
|
||||
static +WrappedComponent: WC;
|
||||
getWrappedInstance(): React$ElementRef<WC>;
|
||||
}
|
||||
// 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<P, OP, MP: P> = <WC: React$ComponentType<P>>(
|
||||
WC,
|
||||
) => Class<ConnectedComponent<OP, WC>> & 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<OP, D> = {| ...$Exact<OP>, dispatch: D |};
|
||||
declare type MergeOPSP<OP, SP, D> = {| ...$Exact<OP>, ...SP, dispatch: D |};
|
||||
declare type MergeOPDP<OP, DP> = {| ...$Exact<OP>, ...DP |};
|
||||
declare type MergeOPSPDP<OP, SP, DP> = {| ...$Exact<OP>, ...SP, ...DP |};
|
||||
|
||||
declare export function connect<-P, -OP, -SP, -DP, -S, -D>(
|
||||
mapStateToProps?: null | void,
|
||||
mapDispatchToProps?: null | void,
|
||||
mergeProps?: null | void,
|
||||
options?: ?Options<S, OP, {||}, MergeOP<OP, D>>,
|
||||
): Connector<P, OP, MergeOP<OP, D>>;
|
||||
|
||||
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<S, OP, SP>,
|
||||
mapDispatchToProps?: null | void,
|
||||
mergeProps?: null | void,
|
||||
options?: ?Options<S, OP, SP, MergeOPSP<OP, SP, D>>,
|
||||
): Connector<P, OP, MergeOPSP<OP, SP, D>>;
|
||||
|
||||
// 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<D, OP, DP>,
|
||||
mergeProps?: null | void,
|
||||
options?: ?Options<S, OP, {||}, MergeOPDP<OP, DP>>,
|
||||
): Connector<P, OP, MergeOPDP<OP, DP>>;
|
||||
|
||||
// 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<S, OP, {||}, MergeOPDP<OP, DP>>,
|
||||
): Connector<P, OP, MergeOPDP<OP, $ObjMap<DP, Bind<D>>>>;
|
||||
|
||||
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<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||
mergeProps?: null | void,
|
||||
options?: ?Options<S, OP, SP, {| ...OP, ...SP, ...DP |}>,
|
||||
): Connector<P, OP, {| ...OP, ...SP, ...DP |}>;
|
||||
|
||||
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<S, OP, SP>,
|
||||
mapDispatchToProps: DP,
|
||||
mergeProps?: null | void,
|
||||
options?: ?Options<S, OP, SP, MergeOPSPDP<OP, SP, DP>>,
|
||||
): Connector<P, OP, MergeOPSPDP<OP, SP, $ObjMap<DP, Bind<D>>>>;
|
||||
|
||||
// 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<P, OP, {||}, {| dispatch: D |}>,
|
||||
options?: ?Options<S, OP, {||}, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
declare class ConnectedComponent<OP, P> extends React$Component<OP> {
|
||||
static WrappedComponent: Class<React$Component<P>>,
|
||||
getWrappedInstance(): React$Component<P>,
|
||||
props: OP,
|
||||
state: void
|
||||
}
|
||||
declare export function connect<-P, -OP, -SP, -DP: {||}, S, D>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: null | void,
|
||||
// If you get error here try adding return type to you mapStateToProps function
|
||||
mergeProps: MergeProps<P, OP, SP, {| dispatch: D |}>,
|
||||
options?: ?Options<S, OP, SP, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
declare type ConnectedComponentClass<OP, P> = Class<
|
||||
ConnectedComponent<OP, P>
|
||||
>;
|
||||
// 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<D, OP, DP>,
|
||||
mergeProps: MergeProps<P, OP, {||}, DP>,
|
||||
options?: ?Options<S, OP, {||}, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
declare type Connector<OP, P> = (
|
||||
component: React$ComponentType<P>
|
||||
) => ConnectedComponentClass<OP, P>;
|
||||
// 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<P, OP, {||}, $ObjMap<DP, Bind<D>>>,
|
||||
options?: ?Options<S, OP, {||}, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
declare class Provider<S, A> extends React$Component<{
|
||||
store: Store<S, A>,
|
||||
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<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,
|
||||
mergeProps: MergeProps<P, OP, SP, DP>,
|
||||
options?: ?Options<S, OP, SP, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
// 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<S, OP, SP>,
|
||||
mapDispatchToProps: DP,
|
||||
mergeProps: MergeProps<P, OP, SP, $ObjMap<DP, Bind<D>>>,
|
||||
options?: ?Options<S, OP, SP, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Typings for Provider
|
||||
// ------------------------------------------------------------
|
||||
|
||||
declare export class Provider<Store> extends React$Component<{
|
||||
store: Store,
|
||||
children?: React$Node,
|
||||
}> {}
|
||||
|
||||
declare function createProvider(
|
||||
declare export function createProvider(
|
||||
storeKey?: string,
|
||||
subKey?: string
|
||||
): Provider<*, *>;
|
||||
subKey?: string,
|
||||
): Class<Provider<*>>;
|
||||
|
||||
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<Com> = {
|
||||
getDisplayName: (name: string) => string,
|
||||
methodName: string,
|
||||
renderCountProp: ?string,
|
||||
shouldHandleStateChanges: boolean,
|
||||
storeKey: string,
|
||||
withRef: boolean,
|
||||
displayName: string,
|
||||
wrappedComponentName: string,
|
||||
WrappedComponent: Com,
|
||||
};
|
||||
|
||||
declare function connect<A, OP>(
|
||||
...rest: Array<void> // <= workaround for https://github.com/facebook/flow/issues/2360
|
||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
||||
declare type MapStateToPropsEx<S: Object, SP: Object, RSP: Object> = (
|
||||
state: S,
|
||||
props: SP,
|
||||
) => RSP;
|
||||
|
||||
declare function connect<A, OP>(
|
||||
mapStateToProps: Null,
|
||||
mapDispatchToProps: Null,
|
||||
mergeProps: Null,
|
||||
options: ConnectOptions
|
||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
||||
declare type SelectorFactory<
|
||||
Com: React$ComponentType<*>,
|
||||
Dispatch,
|
||||
S: Object,
|
||||
OP: Object,
|
||||
EFO: Object,
|
||||
CP: Object,
|
||||
> = (
|
||||
dispatch: Dispatch,
|
||||
factoryOptions: SelectorFactoryOptions<Com> & EFO,
|
||||
) => MapStateToPropsEx<S, OP, CP>;
|
||||
|
||||
declare function connect<S, A, OP, SP>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: Null,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
|
||||
declare export function connectAdvanced<
|
||||
Com: React$ComponentType<*>,
|
||||
D,
|
||||
S: Object,
|
||||
OP: Object,
|
||||
CP: Object,
|
||||
EFO: Object,
|
||||
ST: { [_: $Keys<Com>]: any },
|
||||
>(
|
||||
selectorFactory: SelectorFactory<Com, D, S, OP, EFO, CP>,
|
||||
connectAdvancedOptions: ?(ConnectAdvancedOptions & EFO),
|
||||
): (component: Com) => React$ComponentType<OP> & $Shape<ST>;
|
||||
|
||||
declare function connect<A, OP, DP>(
|
||||
mapStateToProps: Null,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<DP & OP>>;
|
||||
|
||||
declare function connect<S, A, OP, SP, DP>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<SP & DP & OP>>;
|
||||
|
||||
declare function connect<S, A, OP, SP, DP, P>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: Null,
|
||||
mergeProps: MergeProps<SP, DP, OP, P>,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, P>;
|
||||
|
||||
declare function connect<S, A, OP, SP, DP, P>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: MergeProps<SP, DP, OP, P>,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, P>;
|
||||
declare export default {
|
||||
Provider: typeof Provider,
|
||||
createProvider: typeof createProvider,
|
||||
connect: typeof connect,
|
||||
connectAdvanced: typeof connectAdvanced,
|
||||
};
|
||||
}
|
||||
|
176
flow-typed/npm/react-router-dom_v5.x.x.js
vendored
Normal file
176
flow-typed/npm/react-router-dom_v5.x.x.js
vendored
Normal file
@ -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<Location>
|
||||
};
|
||||
|
||||
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<LocationShape | string>,
|
||||
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<ContextRouter> | React$Node,
|
||||
path?: string | Array<string>,
|
||||
exact?: boolean,
|
||||
strict?: boolean,
|
||||
location?: LocationShape,
|
||||
sensitive?: boolean
|
||||
|}>
|
||||
|
||||
declare export var Switch: React$ComponentType<{|
|
||||
children?: React$Node,
|
||||
location?: Location
|
||||
|}>
|
||||
|
||||
declare export function withRouter<Props: {}, Component: React$ComponentType<Props>>(
|
||||
WrappedComponent: Component
|
||||
): React$ComponentType<$Diff<React$ElementConfig<Component>, 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;
|
||||
}
|
139
flow-typed/npm/react-router_v4.x.x.js
vendored
139
flow-typed/npm/react-router_v4.x.x.js
vendored
@ -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<Location>
|
||||
};
|
||||
|
||||
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<LocationShape | string>,
|
||||
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<RouterProps> {}
|
||||
|
||||
declare type PromptProps = {
|
||||
message: string | ((location: Location) => string | true),
|
||||
when?: boolean
|
||||
};
|
||||
declare export class Prompt extends React$Component<PromptProps> {}
|
||||
|
||||
declare type RedirectProps = {
|
||||
to: string | LocationShape,
|
||||
push?: boolean
|
||||
};
|
||||
declare export class Redirect extends React$Component<RedirectProps> {}
|
||||
|
||||
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<RouteProps> {}
|
||||
|
||||
declare type SwithcProps = {
|
||||
children?: Array<React$Element<*>>
|
||||
};
|
||||
declare export class Switch extends React$Component<SwithcProps> {}
|
||||
|
||||
declare export function withRouter<P>(
|
||||
Component: React$ComponentType<ContextRouter & P>
|
||||
): React$ComponentType<P>;
|
||||
|
||||
declare type MatchPathOptions = {
|
||||
exact?: boolean,
|
||||
strict?: boolean
|
||||
};
|
||||
declare export function matchPath(
|
||||
pathname: string,
|
||||
path: string,
|
||||
options?: MatchPathOptions
|
||||
): null | Match;
|
||||
}
|
109
flow-typed/npm/redux_v3.x.x.js
vendored
109
flow-typed/npm/redux_v3.x.x.js
vendored
@ -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<A> = (action: A) => A;
|
||||
declare type Dispatch<A: { type: $Subtype<string> }> = DispatchAPI<A>;
|
||||
|
||||
declare type MiddlewareAPI<S, A, D = Dispatch<A>> = {
|
||||
dispatch: D;
|
||||
getState(): S;
|
||||
};
|
||||
|
||||
declare type Store<S, A, D = Dispatch<A>> = {
|
||||
// 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<S, A>): void
|
||||
};
|
||||
|
||||
declare type Reducer<S, A> = (state: S, action: A) => S;
|
||||
|
||||
declare type CombinedReducer<S, A> = (state: $Shape<S> & {} | void, action: A) => S;
|
||||
|
||||
declare type Middleware<S, A, D = Dispatch<A>> =
|
||||
(api: MiddlewareAPI<S, A, D>) =>
|
||||
(next: D) => D;
|
||||
|
||||
declare type StoreCreator<S, A, D = Dispatch<A>> = {
|
||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
};
|
||||
|
||||
declare type StoreEnhancer<S, A, D = Dispatch<A>> = (next: StoreCreator<S, A, D>) => StoreCreator<S, A, D>;
|
||||
|
||||
declare function createStore<S, A, D>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
declare function createStore<S, A, D>(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
|
||||
declare function applyMiddleware<S, A, D>(...middlewares: Array<Middleware<S, A, D>>): StoreEnhancer<S, A, D>;
|
||||
|
||||
declare type ActionCreator<A, B> = (...args: Array<B>) => A;
|
||||
declare type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> };
|
||||
|
||||
declare function bindActionCreators<A, C: ActionCreator<A, any>, D: DispatchAPI<A>>(actionCreator: C, dispatch: D): C;
|
||||
declare function bindActionCreators<A, K, C: ActionCreators<K, A>, D: DispatchAPI<A>>(actionCreators: C, dispatch: D): C;
|
||||
|
||||
declare function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
|
||||
declare function compose<A, B>(ab: (a: A) => B): (a: A) => B
|
||||
declare function compose<A, B, C>(
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => C
|
||||
declare function compose<A, B, C, D>(
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => D
|
||||
declare function compose<A, B, C, D, E>(
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => E
|
||||
declare function compose<A, B, C, D, E, F>(
|
||||
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<A, B, C, D, E, F, G>(
|
||||
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<A, B, C, D, E, F, G, H>(
|
||||
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<A, B, C, D, E, F, G, H, I>(
|
||||
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
|
||||
|
||||
}
|
100
flow-typed/npm/redux_v4.x.x.js
vendored
Normal file
100
flow-typed/npm/redux_v4.x.x.js
vendored
Normal file
@ -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<T> = {
|
||||
type: T
|
||||
}
|
||||
|
||||
declare export type DispatchAPI<A> = (action: A) => A;
|
||||
|
||||
declare export type Dispatch<A: { type: * }> = DispatchAPI<A>;
|
||||
|
||||
declare export type MiddlewareAPI<S, A, D = Dispatch<A>> = {
|
||||
dispatch: D,
|
||||
getState(): S,
|
||||
};
|
||||
|
||||
declare export type Store<S, A, D = Dispatch<A>> = {
|
||||
// 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<S, A>): void,
|
||||
};
|
||||
|
||||
declare export type Reducer<S, A> = (state: S | void, action: A) => S;
|
||||
|
||||
declare export type CombinedReducer<S, A> = (
|
||||
state: ($Shape<S> & {}) | void,
|
||||
action: A
|
||||
) => S;
|
||||
|
||||
declare export type Middleware<S, A, D = Dispatch<A>> = (
|
||||
api: MiddlewareAPI<S, A, D>
|
||||
) => (next: D) => D;
|
||||
|
||||
declare export type StoreCreator<S, A, D = Dispatch<A>> = {
|
||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>,
|
||||
(
|
||||
reducer: Reducer<S, A>,
|
||||
preloadedState: S,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>,
|
||||
};
|
||||
|
||||
declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (
|
||||
next: StoreCreator<S, A, D>
|
||||
) => StoreCreator<S, A, D>;
|
||||
|
||||
declare export function createStore<S, A, D>(
|
||||
reducer: Reducer<S, A>,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>;
|
||||
declare export function createStore<S, A, D>(
|
||||
reducer: Reducer<S, A>,
|
||||
preloadedState?: S,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>;
|
||||
|
||||
declare export function applyMiddleware<S, A, D>(
|
||||
...middlewares: Array<Middleware<S, A, D>>
|
||||
): StoreEnhancer<S, A, D>;
|
||||
|
||||
declare export type ActionCreator<A, B> = (...args: Array<B>) => A;
|
||||
declare export type ActionCreators<K, A> = {
|
||||
[key: K]: ActionCreator<A, any>,
|
||||
};
|
||||
|
||||
declare export function bindActionCreators<
|
||||
A,
|
||||
C: ActionCreator<A, any>,
|
||||
D: DispatchAPI<A>
|
||||
>(
|
||||
actionCreator: C,
|
||||
dispatch: D
|
||||
): C;
|
||||
declare export function bindActionCreators<
|
||||
A,
|
||||
K,
|
||||
C: ActionCreators<K, A>,
|
||||
D: DispatchAPI<A>
|
||||
>(
|
||||
actionCreators: C,
|
||||
dispatch: D
|
||||
): C;
|
||||
|
||||
declare export function combineReducers<O: {}, A>(
|
||||
reducers: O
|
||||
): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
|
||||
declare export var compose: $Compose;
|
||||
}
|
29
package.json
29
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",
|
||||
|
@ -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}]
|
||||
)
|
||||
);
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import accounts from 'components/accounts/reducer';
|
||||
import {
|
||||
|
@ -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<PanelId[]> = [
|
||||
['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<any>,
|
||||
Body: Element<any>,
|
||||
Footer: Node,
|
||||
Links: Node,
|
||||
Footer: Element<any>,
|
||||
Links: Element<any>,
|
||||
hasBackButton: bool,
|
||||
}
|
||||
};
|
||||
|
||||
type OwnProps = {|
|
||||
Title: Element<any>,
|
||||
Body: Element<any>,
|
||||
Footer: Element<any>,
|
||||
Links: Element<any>,
|
||||
children?: Element<any>
|
||||
|};
|
||||
|
||||
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<Props, State> {
|
||||
return {
|
||||
auth: this.props.auth,
|
||||
user: this.props.user,
|
||||
requestRedraw: () =>
|
||||
requestRedraw: (): Promise<void> =>
|
||||
new Promise((resolve) =>
|
||||
this.setState(
|
||||
{isHeightDirty: true},
|
||||
@ -207,9 +210,9 @@ class PanelTransition extends Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
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<Props, State> {
|
||||
}
|
||||
|
||||
const {panelId, hasGoBack}: {
|
||||
panelId: string,
|
||||
panelId: PanelId,
|
||||
hasGoBack: bool,
|
||||
} = (Body: any).type;
|
||||
|
||||
@ -336,10 +339,10 @@ class PanelTransition extends Component<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
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<Props, State> {
|
||||
*
|
||||
* @return {object}
|
||||
*/
|
||||
getTransitionStyles({key}, options = {}): {|
|
||||
getTransitionStyles({key}: AnimationContext, options: { isLeave?: bool } = {}): {|
|
||||
transformSpring: number,
|
||||
opacitySpring: number,
|
||||
|} {
|
||||
@ -380,7 +383,7 @@ class PanelTransition extends Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
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<Props, State> {
|
||||
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<Props, State> {
|
||||
});
|
||||
};
|
||||
|
||||
onUpdateContextHeight = (height) => {
|
||||
onUpdateContextHeight = (height: number) => {
|
||||
this.setState({
|
||||
contextHeight: height
|
||||
});
|
||||
};
|
||||
|
||||
onGoBack = (event) => {
|
||||
onGoBack = (event: SyntheticEvent<HTMLElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
authFlow.goBack();
|
||||
@ -415,7 +418,7 @@ class PanelTransition extends Component<Props, State> {
|
||||
*
|
||||
* @param {number} length number of panels transitioned
|
||||
*/
|
||||
tryToAutoFocus(length) {
|
||||
tryToAutoFocus(length: number) {
|
||||
if (!this.body) {
|
||||
return;
|
||||
}
|
||||
@ -588,7 +591,7 @@ class PanelTransition extends Component<Props, State> {
|
||||
*
|
||||
* @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<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((state) => {
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => {
|
||||
const login = getLogin(state);
|
||||
let user = {
|
||||
...state.user
|
||||
|
@ -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<string>) {
|
||||
export function setScopes(scopes: Scope[]) {
|
||||
if (!(scopes instanceof Array)) {
|
||||
throw new Error('Scopes must be array');
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import request from 'services/request';
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import auth from 'components/auth/reducer';
|
||||
import {
|
||||
|
@ -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);
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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<ElementConfig<'a'>>;
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
createContactPopup: () => void,
|
||||
};
|
||||
|
||||
function ContactLink({
|
||||
createContactPopup,
|
||||
...props
|
||||
}: {
|
||||
createContactPopup: () => void,
|
||||
props: Object
|
||||
}) {
|
||||
}: Props) {
|
||||
return (
|
||||
<a
|
||||
href="#"
|
||||
@ -25,9 +30,9 @@ function ContactLink({
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
export default connect<Props, OwnProps, _, _, _, _>(
|
||||
null,
|
||||
{
|
||||
createContactPopup: () => createPopup(ContactForm)
|
||||
createContactPopup: () => createPopup({ Popup: ContactForm })
|
||||
}
|
||||
)(ContactLink);
|
||||
|
@ -97,7 +97,7 @@ export default class ApplicationForm extends Component<{
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{FormComponent && (
|
||||
{!!FormComponent && (
|
||||
<Button
|
||||
color={COLOR_GREEN}
|
||||
block
|
||||
|
@ -63,7 +63,7 @@ export default class ApplicationItem extends Component<
|
||||
[styles.appExpanded]: expand
|
||||
})}
|
||||
data-e2e="appItem"
|
||||
data-e2e-app={app.clientId}
|
||||
data-e2e-app-name={app.name}
|
||||
>
|
||||
<div className={styles.appItemTile} onClick={this.onTileToggle}>
|
||||
<div className={styles.appTileTitle}>
|
||||
|
@ -1,10 +1,11 @@
|
||||
// @flow
|
||||
import type { OauthAppResponse } from 'services/api/oauth';
|
||||
|
||||
import type { Action } from './actions';
|
||||
|
||||
export type Apps = {
|
||||
+available: Array<OauthAppResponse>,
|
||||
};
|
||||
export type Apps = {|
|
||||
+available: OauthAppResponse[],
|
||||
|};
|
||||
|
||||
const defaults: Apps = {
|
||||
available: [],
|
||||
@ -13,7 +14,7 @@ const defaults: Apps = {
|
||||
export default function apps(
|
||||
state: Apps = defaults,
|
||||
action: Action
|
||||
) {
|
||||
): Apps {
|
||||
switch (action.type) {
|
||||
case 'apps:setAvailable':
|
||||
return {
|
||||
@ -23,7 +24,7 @@ export default function apps(
|
||||
|
||||
case 'apps:addApp': {
|
||||
const { payload } = action;
|
||||
const available: Array<OauthAppResponse> = [...state.available];
|
||||
const available = [...state.available];
|
||||
let index = available.findIndex((app) => app.clientId === payload.clientId);
|
||||
|
||||
if (index === -1) {
|
||||
|
@ -10,10 +10,16 @@ import { ContactLink } from 'components/contact';
|
||||
import styles from './footerMenu.scss';
|
||||
import messages from './footerMenu.intl.json';
|
||||
|
||||
class FooterMenu extends Component<{
|
||||
type OwnProps = {|
|
||||
createContactPopup: () => void,
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
createLanguageSwitcherPopup: () => void,
|
||||
}> {
|
||||
};
|
||||
|
||||
class FooterMenu extends Component<Props> {
|
||||
static displayName = 'FooterMenu';
|
||||
|
||||
render() {
|
||||
@ -50,6 +56,6 @@ class FooterMenu extends Component<{
|
||||
|
||||
// mark this component, as not pure, because it is stateless,
|
||||
// but should be re-rendered, if current lang was changed
|
||||
export default connect(null, {
|
||||
createLanguageSwitcherPopup: () => createPopup(LanguageSwitcher),
|
||||
export default connect<Props, OwnProps, _, _, _, _>(null, {
|
||||
createLanguageSwitcherPopup: () => createPopup({ Popup: LanguageSwitcher }),
|
||||
}, null, {pure: false})(FooterMenu);
|
||||
|
@ -2,11 +2,13 @@
|
||||
import React, { Component } from 'react';
|
||||
import { FormattedMessage as Message, intlShape } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { changeLang } from 'components/user/actions';
|
||||
import LANGS from 'i18n/index.json';
|
||||
import formStyles from 'components/ui/form/form.scss';
|
||||
import popupStyles from 'components/ui/popup/popup.scss';
|
||||
import icons from 'components/ui/icons.scss';
|
||||
|
||||
import styles from './languageSwitcher.scss';
|
||||
import messages from './languageSwitcher.intl.json';
|
||||
import LanguageList from './LanguageList';
|
||||
@ -23,21 +25,27 @@ export type LocaleData = {
|
||||
|
||||
export type LocalesMap = {[code: string]: LocaleData};
|
||||
|
||||
class LanguageSwitcher extends Component<{
|
||||
onClose: Function,
|
||||
selectedLocale: string,
|
||||
changeLang: (lang: string) => void,
|
||||
type OwnProps = {|
|
||||
onClose: () => void,
|
||||
langs: LocalesMap,
|
||||
emptyCaptions: Array<{
|
||||
src: string,
|
||||
caption: string,
|
||||
}>,
|
||||
}, {
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
selectedLocale: string,
|
||||
changeLang: (lang: string) => void,
|
||||
};
|
||||
|
||||
class LanguageSwitcher extends Component<Props, {
|
||||
filter: string,
|
||||
filteredLangs: LocalesMap,
|
||||
}> {
|
||||
static contextTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
intl: intlShape,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -108,7 +116,7 @@ class LanguageSwitcher extends Component<{
|
||||
|
||||
onChangeLang = this.changeLang.bind(this);
|
||||
|
||||
changeLang(lang) {
|
||||
changeLang(lang: string) {
|
||||
this.props.changeLang(lang);
|
||||
|
||||
setTimeout(this.props.onClose, 300);
|
||||
@ -153,10 +161,7 @@ class LanguageSwitcher extends Component<{
|
||||
}
|
||||
}
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { changeLang } from 'components/user/actions';
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
selectedLocale: state.i18n.locale,
|
||||
}), {
|
||||
changeLang,
|
||||
|
@ -3,17 +3,27 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { localeFlags } from 'components/i18n';
|
||||
import LANGS from 'i18n/index.json';
|
||||
import { connect } from 'react-redux';
|
||||
import { create as createPopup } from 'components/ui/popup/actions';
|
||||
import LanguageSwitcher from 'components/languageSwitcher';
|
||||
|
||||
import styles from './link.scss';
|
||||
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
userLang: string;
|
||||
interfaceLocale: string;
|
||||
showLanguageSwitcherPopup: Function;
|
||||
};
|
||||
|
||||
function LanguageLink({
|
||||
userLang,
|
||||
interfaceLocale,
|
||||
showLanguageSwitcherPopup,
|
||||
}: {
|
||||
userLang: string;
|
||||
interfaceLocale: string;
|
||||
showLanguageSwitcherPopup: Function;
|
||||
}) {
|
||||
}: Props) {
|
||||
const localeDefinition = LANGS[userLang] || LANGS[interfaceLocale];
|
||||
|
||||
return (
|
||||
@ -31,13 +41,9 @@ function LanguageLink({
|
||||
);
|
||||
}
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { create as createPopup } from 'components/ui/popup/actions';
|
||||
import LanguageSwitcher from 'components/languageSwitcher';
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
userLang: state.user.lang,
|
||||
interfaceLocale: state.i18n.locale,
|
||||
}), {
|
||||
showLanguageSwitcherPopup: () => createPopup(LanguageSwitcher),
|
||||
showLanguageSwitcherPopup: () => createPopup({ Popup: LanguageSwitcher }),
|
||||
})(LanguageLink);
|
||||
|
@ -13,10 +13,16 @@ import RulesPage from 'pages/rules/RulesPage';
|
||||
|
||||
import type { User } from 'components/user';
|
||||
|
||||
class Profile extends Component<{
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
user: User;
|
||||
interfaceLocale: string;
|
||||
}> {
|
||||
};
|
||||
|
||||
class Profile extends Component<Props> {
|
||||
UUID: ?HTMLElement;
|
||||
|
||||
render() {
|
||||
@ -150,10 +156,7 @@ class Profile extends Component<{
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(({ user, i18n }): {
|
||||
user: User;
|
||||
interfaceLocale: string;
|
||||
} => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>(({ user, i18n }) => ({
|
||||
user,
|
||||
interfaceLocale: i18n.locale,
|
||||
}))(Profile);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
|
@ -8,7 +8,7 @@ const ABORT_ERR = 20;
|
||||
|
||||
export default function BsodMiddleware(dispatchBsod: Function, logger: Logger) {
|
||||
return {
|
||||
catch<T: Resp<*> | InternalServerError | Error>(resp?: T): Promise<T> {
|
||||
catch<T: Resp<any> | InternalServerError | Error>(resp?: T): Promise<T> {
|
||||
const originalResponse: Object = (resp && resp.originalResponse) || {};
|
||||
|
||||
if (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import BsodMiddleware from 'components/ui/bsod/BsodMiddleware';
|
||||
|
@ -16,7 +16,7 @@ export default class Captcha extends FormInputComponent<{
|
||||
}, {
|
||||
code: string,
|
||||
}> {
|
||||
el: ?HTMLDivElement;
|
||||
elRef = React.createRef<HTMLDivElement>();
|
||||
captchaId: CaptchaID;
|
||||
|
||||
static defaultProps = {
|
||||
@ -26,7 +26,9 @@ export default class Captcha extends FormInputComponent<{
|
||||
|
||||
componentDidMount() {
|
||||
setTimeout(() => {
|
||||
this.el && captcha.render(this.el, {
|
||||
const {current: el} = this.elRef;
|
||||
|
||||
el && captcha.render(el, {
|
||||
skin: this.props.skin,
|
||||
onSetCode: this.setCode
|
||||
})
|
||||
@ -48,7 +50,7 @@ export default class Captcha extends FormInputComponent<{
|
||||
<ComponentLoader />
|
||||
</div>
|
||||
|
||||
<div ref={this.setEl} className={classNames(
|
||||
<div ref={this.elRef} className={classNames(
|
||||
styles.captcha,
|
||||
styles[`${skin}Captcha`]
|
||||
)} />
|
||||
|
@ -19,6 +19,8 @@ export default class Checkbox extends FormInputComponent<{
|
||||
skin: SKIN_DARK,
|
||||
};
|
||||
|
||||
elRef = React.createRef<HTMLInputElement>();
|
||||
|
||||
render() {
|
||||
const { color, skin } = this.props;
|
||||
let { label } = this.props;
|
||||
@ -30,7 +32,7 @@ export default class Checkbox extends FormInputComponent<{
|
||||
return (
|
||||
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
||||
<label className={styles.markableContainer}>
|
||||
<input ref={this.setEl}
|
||||
<input ref={this.elRef}
|
||||
className={styles.markableInput}
|
||||
type="checkbox"
|
||||
{...props}
|
||||
@ -44,13 +46,13 @@ export default class Checkbox extends FormInputComponent<{
|
||||
}
|
||||
|
||||
getValue() {
|
||||
const { el } = this;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
return el && el.checked ? 1 : 0;
|
||||
}
|
||||
|
||||
focus() {
|
||||
const { el } = this;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
el && el.focus();
|
||||
}
|
||||
|
@ -1,22 +1,20 @@
|
||||
// @flow
|
||||
import type { Node } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import logger from 'services/logger';
|
||||
|
||||
import type FormModel from './FormModel';
|
||||
import styles from './form.scss';
|
||||
|
||||
import type FormModel from './FormModel';
|
||||
|
||||
type Props = {
|
||||
type Props = {|
|
||||
id: string,
|
||||
isLoading: bool,
|
||||
form?: FormModel,
|
||||
onSubmit: Function,
|
||||
onSubmit: (form: FormModel | FormData) => void | Promise<void>,
|
||||
onInvalid: (errors: {[errorKey: string]: string}) => void,
|
||||
children: *
|
||||
};
|
||||
children: Node
|
||||
|};
|
||||
type State = {
|
||||
isTouched: bool,
|
||||
isLoading: bool
|
||||
@ -130,7 +128,7 @@ export default class Form extends Component<Props, State> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const invalidEls = form.querySelectorAll(':invalid');
|
||||
const invalidEls: NodeList<InputElement> = (form.querySelectorAll(':invalid'): any);
|
||||
const errors = {};
|
||||
invalidEls[0].focus(); // focus on first error
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { intlShape } from 'react-intl';
|
||||
|
||||
export default class FormComponent<P, S = void> extends Component<P, S> {
|
||||
static contextTypes = {
|
||||
intl: intlShape.isRequired
|
||||
intl: intlShape,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -12,8 +12,6 @@ export default class FormInputComponent<P, S = void> extends FormComponent<P & {
|
||||
}, S & {
|
||||
error?: Error,
|
||||
}> {
|
||||
el: ?HTMLDivElement;
|
||||
|
||||
componentWillReceiveProps() {
|
||||
if (this.state && this.state.error) {
|
||||
Reflect.deleteProperty(this.state, 'error');
|
||||
@ -22,10 +20,6 @@ export default class FormInputComponent<P, S = void> extends FormComponent<P & {
|
||||
}
|
||||
}
|
||||
|
||||
setEl = (el: ?HTMLDivElement) => {
|
||||
this.el = el;
|
||||
};
|
||||
|
||||
renderError() {
|
||||
const error = this.state && this.state.error || this.props.error;
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
// @flow
|
||||
import FormInputComponent from './FormInputComponent';
|
||||
|
||||
type LoadingListener = (isLoading: bool) => void;
|
||||
|
||||
export default class FormModel {
|
||||
fields = {};
|
||||
errors = {};
|
||||
handlers = [];
|
||||
handlers: LoadingListener[] = [];
|
||||
renderErrors: bool;
|
||||
_isLoading: bool;
|
||||
|
||||
@ -145,7 +147,7 @@ export default class FormModel {
|
||||
*
|
||||
* @return {object}
|
||||
*/
|
||||
serialize() {
|
||||
serialize(): {[key: string]: any} {
|
||||
return Object.keys(this.fields).reduce((acc, fieldId) => {
|
||||
const field = this.fields[fieldId];
|
||||
|
||||
@ -164,7 +166,7 @@ export default class FormModel {
|
||||
*
|
||||
* @param {function} fn
|
||||
*/
|
||||
addLoadingListener(fn: Function) {
|
||||
addLoadingListener(fn: LoadingListener) {
|
||||
this.removeLoadingListener(fn);
|
||||
this.handlers.push(fn);
|
||||
}
|
||||
@ -174,7 +176,7 @@ export default class FormModel {
|
||||
*
|
||||
* @param {function} fn
|
||||
*/
|
||||
removeLoadingListener(fn: Function) {
|
||||
removeLoadingListener(fn: LoadingListener) {
|
||||
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ export default class Input extends FormInputComponent<{
|
||||
wasCopied: false,
|
||||
};
|
||||
|
||||
elRef = React.createRef<HTMLInputElement>();
|
||||
|
||||
render() {
|
||||
const { color, skin, center } = this.props;
|
||||
let { icon, label, copy } = this.props;
|
||||
@ -89,7 +91,7 @@ export default class Input extends FormInputComponent<{
|
||||
<div className={baseClass}>
|
||||
{label}
|
||||
<div className={styles.textFieldContainer}>
|
||||
<input ref={this.setEl}
|
||||
<input ref={this.elRef}
|
||||
className={classNames(
|
||||
styles[`${skin}TextField`],
|
||||
styles[`${color}TextField`],
|
||||
@ -108,11 +110,13 @@ export default class Input extends FormInputComponent<{
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.el && this.el.value;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
return el && el.value;
|
||||
}
|
||||
|
||||
focus() {
|
||||
const el = this.el;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
if (!el) {
|
||||
return;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
|
||||
import Input from './Input';
|
||||
|
@ -1,12 +1,15 @@
|
||||
// @flow
|
||||
import type { ElementProps } from 'react';
|
||||
import type { ElementConfig } from 'react';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Button from './Button';
|
||||
|
||||
export default function LinkButton(
|
||||
props: ElementProps<typeof Button> & ElementProps<typeof Link>
|
||||
props: {
|
||||
...$Exact<ElementConfig<typeof Button>>,
|
||||
...$Exact<ElementConfig<typeof Link>>
|
||||
}
|
||||
) {
|
||||
const { to, ...restProps } = props;
|
||||
|
||||
|
@ -19,6 +19,8 @@ export default class Radio extends FormInputComponent<{
|
||||
skin: SKIN_DARK,
|
||||
};
|
||||
|
||||
elRef = React.createRef<HTMLInputElement>();
|
||||
|
||||
render() {
|
||||
const { color, skin } = this.props;
|
||||
let { label } = this.props;
|
||||
@ -30,7 +32,7 @@ export default class Radio extends FormInputComponent<{
|
||||
return (
|
||||
<div className={classNames(styles[`${color}MarkableRow`], styles[`${skin}MarkableRow`])}>
|
||||
<label className={styles.markableContainer}>
|
||||
<input ref={this.setEl}
|
||||
<input ref={this.elRef}
|
||||
className={styles.markableInput}
|
||||
type="radio"
|
||||
{...props}
|
||||
@ -44,13 +46,13 @@ export default class Radio extends FormInputComponent<{
|
||||
}
|
||||
|
||||
getValue() {
|
||||
const { el } = this;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
return el && el.checked ? 1 : 0;
|
||||
}
|
||||
|
||||
focus() {
|
||||
const { el } = this;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
el && el.focus();
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ export default class TextArea extends FormInputComponent<{
|
||||
skin: SKIN_DARK,
|
||||
};
|
||||
|
||||
elRef = React.createRef<HTMLTextAreaElement>();
|
||||
|
||||
render() {
|
||||
const { color, skin } = this.props;
|
||||
let { label } = this.props;
|
||||
@ -59,7 +61,7 @@ export default class TextArea extends FormInputComponent<{
|
||||
<div className={styles.formRow}>
|
||||
{label}
|
||||
<div className={styles.textAreaContainer}>
|
||||
<TextareaAutosize inputRef={this.setEl}
|
||||
<TextareaAutosize inputRef={this.elRef}
|
||||
className={classNames(
|
||||
styles.textArea,
|
||||
styles[`${skin}TextField`],
|
||||
@ -74,11 +76,13 @@ export default class TextArea extends FormInputComponent<{
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.el && this.el.value;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
return el && el.value;
|
||||
}
|
||||
|
||||
focus() {
|
||||
const { el } = this;
|
||||
const { current: el } = this.elRef;
|
||||
|
||||
if (!el) {
|
||||
return;
|
||||
|
@ -1,19 +1,20 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { CSSTransitionGroup } from 'react-transition-group';
|
||||
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
||||
import { browserHistory } from 'services/history';
|
||||
import { connect } from 'react-redux';
|
||||
import { destroy } from 'components/ui/popup/actions';
|
||||
|
||||
import styles from './popup.scss';
|
||||
|
||||
export class PopupStack extends Component {
|
||||
static displayName = 'PopupStack';
|
||||
|
||||
static propTypes = {
|
||||
popups: PropTypes.arrayOf(PropTypes.shape({
|
||||
popups: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
type: PropTypes.func,
|
||||
props: PropTypes.oneOfType([PropTypes.object, PropTypes.func])
|
||||
})),
|
||||
})
|
||||
),
|
||||
destroy: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@ -28,31 +29,34 @@ export class PopupStack extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {popups} = this.props;
|
||||
const { popups } = this.props;
|
||||
|
||||
return (
|
||||
<CSSTransitionGroup
|
||||
transitionName={{
|
||||
<TransitionGroup>
|
||||
{popups.map((popup, index) => {
|
||||
const { Popup } = popup;
|
||||
|
||||
return (
|
||||
<CSSTransition
|
||||
key={index}
|
||||
classNames={{
|
||||
enter: styles.trEnter,
|
||||
enterActive: styles.trEnterActive,
|
||||
leave: styles.trLeave,
|
||||
leaveActive: styles.trLeaveActive
|
||||
exit: styles.trExit,
|
||||
exitActive: styles.trExitActive
|
||||
}}
|
||||
transitionEnterTimeout={500}
|
||||
transitionLeaveTimeout={500}
|
||||
timeout={500}
|
||||
>
|
||||
{popups.map((popup, index) => {
|
||||
const {Popup} = popup;
|
||||
|
||||
return (
|
||||
<div className={styles.overlay} key={index}
|
||||
<div
|
||||
className={styles.overlay}
|
||||
onClick={this.onOverlayClick(popup)}
|
||||
>
|
||||
<Popup onClose={this.onClose(popup)} />
|
||||
</div>
|
||||
</CSSTransition>
|
||||
);
|
||||
})}
|
||||
</CSSTransitionGroup>
|
||||
</TransitionGroup>
|
||||
);
|
||||
}
|
||||
|
||||
@ -62,7 +66,10 @@ export class PopupStack extends Component {
|
||||
|
||||
onOverlayClick(popup) {
|
||||
return (event) => {
|
||||
if (event.target !== event.currentTarget || popup.disableOverlayClose) {
|
||||
if (
|
||||
event.target !== event.currentTarget
|
||||
|| popup.disableOverlayClose
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -81,7 +88,8 @@ export class PopupStack extends Component {
|
||||
}
|
||||
|
||||
onKeyPress = (event) => {
|
||||
if (event.which === 27) { // ESC key
|
||||
if (event.which === 27) {
|
||||
// ESC key
|
||||
this.popStack();
|
||||
}
|
||||
};
|
||||
@ -93,11 +101,11 @@ export class PopupStack extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { destroy } from 'components/ui/popup/actions';
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect(
|
||||
(state) => ({
|
||||
...state.popup
|
||||
}), {
|
||||
}),
|
||||
{
|
||||
destroy
|
||||
})(PopupStack);
|
||||
}
|
||||
)(PopupStack);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// @flow
|
||||
import type { ElementType } from 'react';
|
||||
|
||||
export const POPUP_CREATE = 'POPUP_CREATE';
|
||||
|
||||
/**
|
||||
@ -9,16 +10,10 @@ export const POPUP_CREATE = 'POPUP_CREATE';
|
||||
*
|
||||
* @return {object}
|
||||
*/
|
||||
export function create(payload: ElementType | {
|
||||
export function create(payload: {
|
||||
Popup: ElementType,
|
||||
disableOverlayClose?: bool,
|
||||
disableOverlayClose?: bool
|
||||
}) {
|
||||
if (typeof payload === 'function') {
|
||||
payload = {
|
||||
Popup: payload
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: POPUP_CREATE,
|
||||
payload
|
||||
|
@ -141,7 +141,7 @@ $popupInitPosition: translateY(10%) rotateX(-8deg);
|
||||
}
|
||||
}
|
||||
|
||||
.trLeave {
|
||||
.trExit {
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
|
||||
@ -163,7 +163,7 @@ $popupInitPosition: translateY(10%) rotateX(-8deg);
|
||||
}
|
||||
|
||||
.trEnter,
|
||||
.trLeave {
|
||||
.trExit {
|
||||
.close {
|
||||
// do not show close during transition, because transform forces position: fixed
|
||||
// to layout relative container, instead of body
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import reducer from 'components/ui/popup/reducer';
|
||||
import {create, destroy} from 'components/ui/popup/actions';
|
||||
@ -22,14 +22,6 @@ describe('popup/reducer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should support shortcut popup creation', () => {
|
||||
const actual = reducer(undefined, create(FakeComponent));
|
||||
|
||||
expect(actual.popups[0], 'to equal', {
|
||||
Popup: FakeComponent
|
||||
});
|
||||
});
|
||||
|
||||
it('should create multiple popups', () => {
|
||||
let actual = reducer(undefined, create({
|
||||
Popup: FakeComponent
|
||||
@ -44,7 +36,7 @@ describe('popup/reducer', () => {
|
||||
});
|
||||
|
||||
it('throws when no type provided', () => {
|
||||
expect(() => reducer(undefined, create()), 'to throw', 'Popup is required');
|
||||
expect(() => reducer(undefined, create({})), 'to throw', 'Popup is required');
|
||||
});
|
||||
});
|
||||
|
||||
@ -53,7 +45,7 @@ describe('popup/reducer', () => {
|
||||
let popup;
|
||||
|
||||
beforeEach(() => {
|
||||
state = reducer(state, create(FakeComponent));
|
||||
state = reducer(state, create({ Popup: FakeComponent }));
|
||||
popup = state.popups[0];
|
||||
});
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
// @flow
|
||||
import type { Location } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { restoreScroll } from './scroll';
|
||||
|
||||
class ScrollIntoView extends React.Component<{
|
||||
location: string,
|
||||
class ScrollIntoView extends React.PureComponent<{
|
||||
location: Location,
|
||||
top?: bool, // do not touch any DOM and simply scroll to top on location change
|
||||
}> {
|
||||
componentDidMount() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import bearerHeaderMiddleware from 'components/user/middlewares/bearerHeaderMiddleware';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import refreshTokenMiddleware from 'components/user/middlewares/refreshTokenMiddleware';
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import sinon from 'sinon';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import { mount } from 'enzyme';
|
||||
|
||||
import authFlow from 'services/authFlow';
|
||||
@ -18,15 +17,13 @@ describe('AuthFlowRouteContents', () => {
|
||||
});
|
||||
|
||||
function Component() {
|
||||
return (
|
||||
<div />
|
||||
);
|
||||
return <div />;
|
||||
}
|
||||
|
||||
it('should render component if route allowed', () => {
|
||||
const request = {
|
||||
path: '/path',
|
||||
params: {foo: 1},
|
||||
params: { foo: 1 },
|
||||
query: new URLSearchParams()
|
||||
};
|
||||
|
||||
@ -36,23 +33,25 @@ describe('AuthFlowRouteContents', () => {
|
||||
query: request.query
|
||||
},
|
||||
match: {
|
||||
params: request.params,
|
||||
params: request.params
|
||||
}
|
||||
};
|
||||
|
||||
authFlow.handleRequest.callsArg(2);
|
||||
|
||||
const wrapper = mount(<AuthFlowRouteContents
|
||||
const wrapper = mount(
|
||||
<AuthFlowRouteContents
|
||||
routerProps={routerProps}
|
||||
component={Component}
|
||||
/>);
|
||||
/>
|
||||
);
|
||||
|
||||
const component = wrapper.find(Component);
|
||||
|
||||
expect(authFlow.handleRequest, 'to have a call satisfying', [
|
||||
request,
|
||||
function() {},
|
||||
function() {}
|
||||
expect.it('to be a function'),
|
||||
expect.it('to be a function')
|
||||
]);
|
||||
|
||||
expect(component.exists(), 'to be true');
|
||||
|
@ -1,26 +1,35 @@
|
||||
// @flow
|
||||
import type { ComponentType, ElementConfig } from 'react';
|
||||
import type { Account } from 'components/accounts';
|
||||
import type { Location } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
import { Route, Redirect } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { getActiveAccount } from 'components/accounts/reducer';
|
||||
import type { ComponentType } from 'react';
|
||||
import type { Account } from 'components/accounts';
|
||||
|
||||
const PrivateRoute = ({account, component: Component, ...rest}: {
|
||||
type OwnProps = {|
|
||||
...$Exact<ElementConfig<typeof Route>>,
|
||||
component: ComponentType<any>,
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
account: ?Account
|
||||
}) => (
|
||||
<Route {...rest} render={(props: {location: string}) => (
|
||||
};
|
||||
|
||||
const PrivateRoute = ({ account, component: Component, ...rest }: Props) => (
|
||||
<Route
|
||||
{...rest}
|
||||
render={(props: { location: Location }) =>
|
||||
!account || !account.token ? (
|
||||
<Redirect to="/login" />
|
||||
) : (
|
||||
<Component {...props}/>
|
||||
<Component {...props} />
|
||||
)
|
||||
)}/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
export default connect((state): {
|
||||
account: ?Account,
|
||||
} => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
account: getActiveAccount(state)
|
||||
}))(PrivateRoute);
|
||||
|
@ -18,6 +18,8 @@ import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword';
|
||||
import RecoverPassword from 'components/auth/recoverPassword/RecoverPassword';
|
||||
import Mfa from 'components/auth/mfa/Mfa';
|
||||
import Finish from 'components/auth/finish/Finish';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import styles from './auth.scss';
|
||||
|
||||
@ -27,13 +29,19 @@ import styles from './auth.scss';
|
||||
// so that it persist disregarding remounts
|
||||
let isSidebarHiddenCache = false;
|
||||
|
||||
class AuthPage extends Component<{
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
client: {
|
||||
id: string,
|
||||
name: string,
|
||||
description: string
|
||||
}
|
||||
}, {
|
||||
};
|
||||
|
||||
class AuthPage extends Component<Props, {
|
||||
isSidebarHidden: bool
|
||||
}> {
|
||||
state = {
|
||||
@ -91,20 +99,10 @@ function renderPanelTransition(factory) {
|
||||
Body={<Body {...props} />}
|
||||
Footer={<Footer />}
|
||||
Links={<Links />}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
export default withRouter(connect((state): {
|
||||
client: {
|
||||
id: string,
|
||||
name: string,
|
||||
description: string
|
||||
}
|
||||
} => ({
|
||||
export default withRouter(connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
client: state.auth.client
|
||||
}))(AuthPage));
|
||||
|
@ -1,5 +1,5 @@
|
||||
// @flow
|
||||
import type { Location, RouterHistory } from 'react-router';
|
||||
import type { Location, RouterHistory } from 'react-router-dom';
|
||||
import type { User } from 'components/user';
|
||||
import type { OauthAppResponse } from 'services/api/oauth';
|
||||
import React, { Component } from 'react';
|
||||
@ -11,17 +11,21 @@ import {
|
||||
} from 'components/dev/apps/actions';
|
||||
import ApplicationsIndex from 'components/dev/apps/ApplicationsIndex';
|
||||
|
||||
interface Props {
|
||||
type OwnProps = {|
|
||||
location: Location;
|
||||
history: RouterHistory;
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
user: User;
|
||||
apps: Array<OauthAppResponse>;
|
||||
apps: OauthAppResponse[];
|
||||
fetchAvailableApps: () => Promise<void>;
|
||||
deleteApp: string => Promise<void>;
|
||||
resetApp: (string, bool) => Promise<void>;
|
||||
}
|
||||
|
||||
interface State {
|
||||
type State = {
|
||||
isLoading: bool;
|
||||
forceUpdate: bool;
|
||||
}
|
||||
@ -36,7 +40,7 @@ class ApplicationsListPage extends Component<Props, State> {
|
||||
!this.props.user.isGuest && this.loadApplicationsList();
|
||||
}
|
||||
|
||||
componentDidUpdate({ user }) {
|
||||
componentDidUpdate({ user }: Props) {
|
||||
if (this.props.user !== user) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState({ forceUpdate: true });
|
||||
@ -80,10 +84,12 @@ class ApplicationsListPage extends Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
user: state.user,
|
||||
apps: state.apps.available,
|
||||
}), {
|
||||
}),
|
||||
// $FlowFixMe: we need a better action typings for thunks
|
||||
{
|
||||
fetchAvailableApps,
|
||||
resetApp,
|
||||
deleteApp,
|
||||
|
@ -11,18 +11,21 @@ import PageNotFound from 'pages/404/PageNotFound';
|
||||
import { getApp, fetchApp } from 'components/dev/apps/actions';
|
||||
import ApplicationForm from 'components/dev/apps/applicationForm/ApplicationForm';
|
||||
|
||||
type MatchType = {
|
||||
type OwnProps = {|
|
||||
match: {
|
||||
params: {
|
||||
clientId: string,
|
||||
},
|
||||
},
|
||||
};
|
||||
|}
|
||||
|
||||
class UpdateApplicationPage extends Component<{
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
app: ?OauthAppResponse,
|
||||
fetchApp: (string) => Promise<void>,
|
||||
} & MatchType, {
|
||||
}
|
||||
|
||||
class UpdateApplicationPage extends Component<Props, {
|
||||
isNotFound: bool,
|
||||
}> {
|
||||
form: FormModel = new FormModel();
|
||||
@ -104,7 +107,7 @@ class UpdateApplicationPage extends Component<{
|
||||
goToMainPage = (hash?: string) => browserHistory.push(`/dev/applications${hash ? `#${hash}` : ''}`);
|
||||
}
|
||||
|
||||
export default connect((state, props: MatchType) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state, props) => ({
|
||||
app: getApp(state, props.match.params.clientId),
|
||||
}), {
|
||||
fetchApp,
|
||||
|
@ -1,15 +1,13 @@
|
||||
// @flow
|
||||
import type { RouterHistory, Match } from 'react-router';
|
||||
import type { RouterHistory, Match } from 'react-router-dom';
|
||||
import type FormModel from 'components/ui/form/FormModel';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import ChangeEmail from 'components/profile/changeEmail/ChangeEmail';
|
||||
|
||||
import { requestEmailChange, setNewEmail, confirmNewEmail } from 'services/api/accounts';
|
||||
|
||||
interface Props {
|
||||
lang: string;
|
||||
email: string;
|
||||
type OwnProps = {|
|
||||
history: RouterHistory;
|
||||
match: {
|
||||
...Match;
|
||||
@ -18,6 +16,12 @@ interface Props {
|
||||
code: string;
|
||||
};
|
||||
};
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
lang: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
class ChangeEmailPage extends Component<Props> {
|
||||
@ -53,11 +57,11 @@ class ChangeEmailPage extends Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
onChangeStep = (step) => {
|
||||
onChangeStep = (step: number) => {
|
||||
this.props.history.push(`/profile/change-email/step${++step}`);
|
||||
};
|
||||
|
||||
onSubmit = (step: number, form) => {
|
||||
onSubmit = (step: number, form: FormModel) => {
|
||||
return this.context.onSubmit({
|
||||
form,
|
||||
sendData: () => {
|
||||
@ -102,10 +106,7 @@ function handleErrors(repeatUrl) {
|
||||
};
|
||||
}
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
email: state.user.email,
|
||||
lang: state.user.lang
|
||||
}), {
|
||||
})(ChangeEmailPage);
|
||||
}))(ChangeEmailPage);
|
||||
|
@ -7,7 +7,11 @@ import { changePassword } from 'services/api/accounts';
|
||||
import { FormModel } from 'components/ui/form';
|
||||
import ChangePassword from 'components/profile/changePassword/ChangePassword';
|
||||
|
||||
interface Props {
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
updateUser: (fields: $Shape<User>) => void;
|
||||
}
|
||||
|
||||
@ -45,6 +49,6 @@ class ChangePasswordPage extends Component<Props> {
|
||||
import { connect } from 'react-redux';
|
||||
import { updateUser } from 'components/user/actions';
|
||||
|
||||
export default connect(null, {
|
||||
export default connect<Props, OwnProps, _, _, _, _>(null, {
|
||||
updateUser,
|
||||
})(ChangePasswordPage);
|
||||
|
@ -6,14 +6,15 @@ import { changeUsername } from 'services/api/accounts';
|
||||
import { FormModel } from 'components/ui/form';
|
||||
import ChangeUsername from 'components/profile/changeUsername/ChangeUsername';
|
||||
|
||||
interface Props {
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
username: string;
|
||||
updateUsername: (username: string) => void;
|
||||
}
|
||||
};
|
||||
|
||||
class ChangeUsernamePage extends Component<Props> {
|
||||
static displayName = 'ChangeUsernamePage';
|
||||
|
||||
static contextTypes = {
|
||||
userId: PropTypes.number.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
@ -42,7 +43,7 @@ class ChangeUsernamePage extends Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
onUsernameChange = (username) => {
|
||||
onUsernameChange = (username: string) => {
|
||||
this.props.updateUsername(username);
|
||||
};
|
||||
|
||||
@ -70,7 +71,7 @@ class ChangeUsernamePage extends Component<Props> {
|
||||
import { connect } from 'react-redux';
|
||||
import { updateUser } from 'components/user/actions';
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
username: state.user.username,
|
||||
}), {
|
||||
updateUsername: (username) => updateUser({username}),
|
||||
|
@ -1,5 +1,5 @@
|
||||
// @flow
|
||||
import type { RouterHistory, Match } from 'react-router';
|
||||
import type { RouterHistory, Match } from 'react-router-dom';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
@ -9,8 +9,7 @@ import type { MfaStep } from 'components/profile/multiFactorAuth';
|
||||
import type { FormModel } from 'components/ui/form';
|
||||
import type { User } from 'components/user';
|
||||
|
||||
interface Props {
|
||||
user: User;
|
||||
type OwnProps = {|
|
||||
history: RouterHistory;
|
||||
match: {
|
||||
...Match;
|
||||
@ -18,6 +17,11 @@ interface Props {
|
||||
step?: '1' | '2' | '3';
|
||||
};
|
||||
};
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
user: User;
|
||||
}
|
||||
|
||||
class MultiFactorAuthPage extends Component<Props> {
|
||||
@ -86,4 +90,6 @@ class MultiFactorAuthPage extends Component<Props> {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(({user}): { user: User } => ({user}))(MultiFactorAuthPage);
|
||||
export default connect<Props, OwnProps, _, _, _, _>(
|
||||
({user}) => ({user})
|
||||
)(MultiFactorAuthPage);
|
||||
|
@ -20,7 +20,11 @@ import styles from './profile.scss';
|
||||
|
||||
import type { FormModel } from 'components/ui/form';
|
||||
|
||||
interface Props {
|
||||
type OwnProps = {|
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
...OwnProps,
|
||||
userId: number;
|
||||
onSubmit: ({form: FormModel, sendData: () => Promise<*>}) => void;
|
||||
fetchUserData: () => Promise<*>;
|
||||
@ -65,7 +69,7 @@ class ProfilePage extends Component<Props> {
|
||||
goToProfile = () => browserHistory.push('/');
|
||||
}
|
||||
|
||||
export default connect((state) => ({
|
||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
|
||||
userId: state.user.id,
|
||||
}), {
|
||||
fetchUserData,
|
||||
|
@ -4,7 +4,7 @@ import type { Account } from 'components/accounts/reducer';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { resetAuth } from 'components/auth/actions';
|
||||
import { withRouter } from 'react-router';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Route, Link, Switch } from 'react-router-dom';
|
||||
import Helmet from 'react-helmet';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import sinon from 'sinon';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import RulesPage from './RulesPage';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
describe('promise.prototype.finally', () => {
|
||||
it('should be invoked after promise resolved', () =>
|
||||
|
@ -41,37 +41,37 @@ export function changePassword(id: number, {
|
||||
});
|
||||
}
|
||||
|
||||
export function acceptRules(id: number) {
|
||||
export function acceptRules(id: number): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/rules`);
|
||||
}
|
||||
|
||||
export function changeUsername(id: number, username: ?string, password: ?string) {
|
||||
export function changeUsername(id: number, username: ?string, password: ?string): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/username`, {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
}
|
||||
|
||||
export function changeLang(id: number, lang: string) {
|
||||
export function changeLang(id: number, lang: string): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/language`, {
|
||||
lang,
|
||||
});
|
||||
}
|
||||
|
||||
export function requestEmailChange(id: number, password: string) {
|
||||
export function requestEmailChange(id: number, password: string): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/email-verification`, {
|
||||
password,
|
||||
});
|
||||
}
|
||||
|
||||
export function setNewEmail(id: number, email: string, key: string) {
|
||||
export function setNewEmail(id: number, email: string, key: string): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/new-email-verification`, {
|
||||
email,
|
||||
key,
|
||||
});
|
||||
}
|
||||
|
||||
export function confirmNewEmail(id: number, key: string) {
|
||||
export function confirmNewEmail(id: number, key: string): Promise<{ success: bool }> {
|
||||
return request.post(`/api/v1/accounts/${id}/email`, {
|
||||
key,
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import request from 'services/request';
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* eslint-disable camelcase */
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import request from 'services/request';
|
||||
|
@ -4,6 +4,18 @@ import type { Resp } from 'services/request';
|
||||
import type { ApplicationType } from 'components/dev/apps';
|
||||
import request from 'services/request';
|
||||
|
||||
export type Scope =
|
||||
| 'minecraft_server_session'
|
||||
| 'offline_access'
|
||||
| 'account_info'
|
||||
| 'account_email';
|
||||
|
||||
export type Client = {|
|
||||
id: string,
|
||||
name: string,
|
||||
description: string
|
||||
|};
|
||||
|
||||
export type OauthAppResponse = {
|
||||
clientId: string,
|
||||
clientSecret: string,
|
||||
@ -24,7 +36,7 @@ type OauthRequestData = {
|
||||
redirect_uri: string,
|
||||
response_type: string,
|
||||
description: string,
|
||||
scope: string,
|
||||
scope: Scope,
|
||||
prompt: string,
|
||||
login_hint?: string,
|
||||
state?: string,
|
||||
@ -35,7 +47,7 @@ export type OauthData = {
|
||||
redirectUrl: string,
|
||||
responseType: string,
|
||||
description: string,
|
||||
scope: string,
|
||||
scope: Scope,
|
||||
prompt: 'none' | 'consent' | 'select_account',
|
||||
loginHint?: string,
|
||||
state?: string
|
||||
@ -51,19 +63,28 @@ type FormPayloads = {
|
||||
|
||||
const api = {
|
||||
validate(oauthData: OauthData) {
|
||||
return request.get(
|
||||
return request.get<{|
|
||||
session: {|
|
||||
scopes: Scope[],
|
||||
|},
|
||||
client: Client,
|
||||
oAuth: {||},
|
||||
|}>(
|
||||
'/api/oauth2/v1/validate',
|
||||
getOAuthRequest(oauthData)
|
||||
).catch(handleOauthParamsValidation);
|
||||
},
|
||||
|
||||
complete(oauthData: OauthData, params: {accept?: bool} = {}): Promise<Resp<{
|
||||
complete(oauthData: OauthData, params: {accept?: bool} = {}): Promise<{
|
||||
success: bool,
|
||||
redirectUri: string,
|
||||
}>> {
|
||||
}> {
|
||||
const query = request.buildQuery(getOAuthRequest(oauthData));
|
||||
|
||||
return request.post(
|
||||
return request.post<{
|
||||
success: bool,
|
||||
redirectUri: string,
|
||||
}>(
|
||||
`/api/oauth2/v1/complete?${query}`,
|
||||
typeof params.accept === 'undefined' ? {} : {accept: params.accept}
|
||||
).catch((resp = {}) => {
|
||||
@ -92,28 +113,28 @@ const api = {
|
||||
});
|
||||
},
|
||||
|
||||
create(type: string, formParams: FormPayloads): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
||||
return request.post(`/api/v1/oauth2/${type}`, formParams);
|
||||
create(type: string, formParams: FormPayloads) {
|
||||
return request.post<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${type}`, formParams);
|
||||
},
|
||||
|
||||
update(clientId: string, formParams: FormPayloads): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
||||
return request.put(`/api/v1/oauth2/${clientId}`, formParams);
|
||||
update(clientId: string, formParams: FormPayloads) {
|
||||
return request.put<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${clientId}`, formParams);
|
||||
},
|
||||
|
||||
getApp(clientId: string): Promise<Resp<OauthAppResponse>> {
|
||||
return request.get(`/api/v1/oauth2/${clientId}`);
|
||||
getApp(clientId: string) {
|
||||
return request.get<OauthAppResponse>(`/api/v1/oauth2/${clientId}`);
|
||||
},
|
||||
|
||||
getAppsByUser(userId: number): Promise<Resp<Array<OauthAppResponse>>> {
|
||||
getAppsByUser(userId: number): Promise<OauthAppResponse[]> {
|
||||
return request.get(`/api/v1/accounts/${userId}/oauth2/clients`);
|
||||
},
|
||||
|
||||
reset(clientId: string, regenerateSecret: bool = false): Promise<Resp<{success: bool, data: OauthAppResponse}>> {
|
||||
return request.post(`/api/v1/oauth2/${clientId}/reset${regenerateSecret ? '?regenerateSecret' : ''}`);
|
||||
reset(clientId: string, regenerateSecret: bool = false) {
|
||||
return request.post<{success: bool, data: OauthAppResponse}>(`/api/v1/oauth2/${clientId}/reset${regenerateSecret ? '?regenerateSecret' : ''}`);
|
||||
},
|
||||
|
||||
delete(clientId: string): Promise<Resp<{success: bool}>> {
|
||||
return request.delete(`/api/v1/oauth2/${clientId}`);
|
||||
delete(clientId: string) {
|
||||
return request.delete<{success: bool}>(`/api/v1/oauth2/${clientId}`);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
import request from 'services/request';
|
||||
import options from './options';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import AuthFlow from 'services/authFlow/AuthFlow';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import AuthFlow from 'services/authFlow/AuthFlow';
|
||||
@ -354,9 +354,9 @@ describe('AuthFlow', () => {
|
||||
|
||||
flow.handleRequest(request);
|
||||
|
||||
expect(flow.getRequest(), 'to equal', {
|
||||
expect(flow.getRequest(), 'to satisfy', {
|
||||
...request,
|
||||
query: new URLSearchParams(),
|
||||
query: expect.it('to be an', URLSearchParams),
|
||||
params: {}
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import CompleteState from 'services/authFlow/CompleteState';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import MfaState from './MfaState';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import PasswordState from 'services/authFlow/PasswordState';
|
||||
|
@ -2,7 +2,7 @@
|
||||
* A helper wrapper service around window.history
|
||||
*/
|
||||
|
||||
import createBrowserHistory from 'history/createBrowserHistory';
|
||||
import { createBrowserHistory } from 'history';
|
||||
|
||||
export const browserHistory = createBrowserHistory();
|
||||
|
||||
@ -11,9 +11,9 @@ browserHistory.listen(() => {
|
||||
});
|
||||
|
||||
function patchHistory(history) {
|
||||
Object.assign(history.location,
|
||||
{query: new URLSearchParams(history.location.search)}
|
||||
);
|
||||
Object.assign(history.location, {
|
||||
query: new URLSearchParams(history.location.search)
|
||||
});
|
||||
}
|
||||
|
||||
patchHistory(browserHistory);
|
||||
@ -27,7 +27,10 @@ export default {
|
||||
* @return {bool} - whether history.back() can be safetly called
|
||||
*/
|
||||
canGoBack() {
|
||||
return document.referrer.includes(`${location.protocol}//${location.host}`)
|
||||
|| this.initialLength < window.history.length;
|
||||
return (
|
||||
document.referrer.includes(
|
||||
`${location.protocol}//${location.host}`
|
||||
) || this.initialLength < window.history.length
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon';
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
|
||||
import PromiseMiddlewareLayer from 'services/request/PromiseMiddlewareLayer';
|
||||
|
||||
|
@ -6,8 +6,9 @@ import RequestAbortedError from './RequestAbortedError';
|
||||
const middlewareLayer = new PromiseMiddlewareLayer();
|
||||
|
||||
export type Resp<T> = {
|
||||
...$Exact<T>,
|
||||
originalResponse: Response
|
||||
} & T;
|
||||
};
|
||||
|
||||
type Middleware = {
|
||||
before?: () => Promise<*>,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import expect from 'unexpected';
|
||||
import expect from 'test/unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import request from 'services/request';
|
||||
|
@ -1,9 +1,7 @@
|
||||
import 'polyfills';
|
||||
import { configure } from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
import expect from 'unexpected';
|
||||
|
||||
expect.use(require('unexpected-sinon'));
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
if (!window.localStorage) {
|
||||
|
7
src/test/unexpected.js
Normal file
7
src/test/unexpected.js
Normal file
@ -0,0 +1,7 @@
|
||||
import unexpected from 'unexpected';
|
||||
|
||||
const expect = unexpected.clone();
|
||||
|
||||
expect.use(require('unexpected-sinon'));
|
||||
|
||||
export default expect;
|
Loading…
Reference in New Issue
Block a user