diff --git a/packages/app/App.tsx b/packages/app/App.tsx deleted file mode 100644 index 0c98ed0..0000000 --- a/packages/app/App.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { hot } from 'react-hot-loader/root'; -import { Provider as ReduxProvider } from 'react-redux'; -import { Router, Route, Switch } from 'react-router-dom'; -import { IntlProvider } from 'app/components/i18n'; -import { Store } from 'redux'; -import AuthFlowRoute from 'app/containers/AuthFlowRoute'; -import RootPage from 'app/pages/root/RootPage'; -import SuccessOauthPage from 'app/pages/auth/SuccessOauthPage'; - -const App = ({ - store, - browserHistory, -}: { - store: Store; - browserHistory: any; -}) => ( - - - - - - null} - /> - - - - - -); - -export default hot(App); diff --git a/packages/app/components/auth/reducer.ts b/packages/app/components/auth/reducer.ts index 9bc7ab1..b9a5313 100644 --- a/packages/app/components/auth/reducer.ts +++ b/packages/app/components/auth/reducer.ts @@ -1,4 +1,5 @@ import { combineReducers } from 'redux'; +import { RootState } from 'app/reducers'; import { ERROR, @@ -27,9 +28,25 @@ export interface Client { description: string; } +interface OAuthState { + clientId: string; + redirectUrl: string; + responseType: string; + description?: string; + scope: string; + prompt: string; + loginHint: string; + state: string; + success?: boolean; + code?: string; + displayCode?: string; + acceptRequired?: boolean; +} + export interface State { credentials: Credentials; error: + | null | string | { type: string; @@ -38,25 +55,11 @@ export interface State { isLoading: boolean; isSwitcherEnabled: boolean; client: Client | null; - login: string; - oauth: { - clientId: string; - redirectUrl: string; - responseType: string; - description: string; - scope: string; - prompt: string; - loginHint: string; - state: string; - success?: boolean; - code?: string; - displayCode?: string; - acceptRequired?: boolean; - } | null; + oauth: OAuthState | null; scopes: string[]; } -export default combineReducers({ +export default combineReducers({ credentials, error, isLoading, @@ -66,7 +69,10 @@ export default combineReducers({ scopes, }); -function error(state = null, { type, payload = null, error = false }) { +function error( + state = null, + { type, payload = null, error = false }, +): State['error'] { switch (type) { case ERROR: if (!error) { @@ -89,7 +95,7 @@ function credentials( type: string; payload: Credentials | null; }, -) { +): State['credentials'] { if (type === SET_CREDENTIALS) { if (payload && typeof payload === 'object') { return { @@ -103,7 +109,10 @@ function credentials( return state; } -function isSwitcherEnabled(state = true, { type, payload = false }) { +function isSwitcherEnabled( + state = true, + { type, payload = false }, +): State['isSwitcherEnabled'] { switch (type) { case SET_SWITCHER: if (typeof payload !== 'boolean') { @@ -117,7 +126,10 @@ function isSwitcherEnabled(state = true, { type, payload = false }) { } } -function isLoading(state = false, { type, payload = null }) { +function isLoading( + state = false, + { type, payload = null }, +): State['isLoading'] { switch (type) { case SET_LOADING_STATE: return !!payload; @@ -127,7 +139,7 @@ function isLoading(state = false, { type, payload = null }) { } } -function client(state = null, { type, payload }) { +function client(state = null, { type, payload }): State['client'] { switch (type) { case SET_CLIENT: return { @@ -141,7 +153,10 @@ function client(state = null, { type, payload }) { } } -function oauth(state: State | null = null, { type, payload }) { +function oauth( + state: State['oauth'] = null, + { type, payload }, +): State['oauth'] { switch (type) { case SET_OAUTH: return { @@ -156,7 +171,7 @@ function oauth(state: State | null = null, { type, payload }) { case SET_OAUTH_RESULT: return { - ...state, + ...(state as OAuthState), success: payload.success, code: payload.code, displayCode: payload.displayCode, @@ -164,7 +179,7 @@ function oauth(state: State | null = null, { type, payload }) { case REQUIRE_PERMISSIONS_ACCEPT: return { - ...state, + ...(state as OAuthState), acceptRequired: true, }; @@ -173,7 +188,7 @@ function oauth(state: State | null = null, { type, payload }) { } } -function scopes(state = [], { type, payload = [] }) { +function scopes(state = [], { type, payload = [] }): State['scopes'] { switch (type) { case SET_SCOPES: return payload; @@ -183,10 +198,10 @@ function scopes(state = [], { type, payload = [] }) { } } -export function getLogin(state: { [key: string]: any }): string | null { +export function getLogin(state: RootState): string | null { return state.auth.credentials.login || null; } -export function getCredentials(state: { [key: string]: any }): Credentials { +export function getCredentials(state: RootState): Credentials { return state.auth.credentials; } diff --git a/packages/app/components/ui/bsod/reducer.js b/packages/app/components/ui/bsod/reducer.ts similarity index 50% rename from packages/app/components/ui/bsod/reducer.js rename to packages/app/components/ui/bsod/reducer.ts index 048a893..df930db 100644 --- a/packages/app/components/ui/bsod/reducer.js +++ b/packages/app/components/ui/bsod/reducer.ts @@ -1,6 +1,8 @@ import { BSOD } from './actions'; -export default function(state = false, { type }) { +export type State = boolean; + +export default function(state: State = false, { type }): State { if (type === BSOD) { return true; } diff --git a/packages/app/index.tsx b/packages/app/index.tsx index 716fc8b..7165d76 100644 --- a/packages/app/index.tsx +++ b/packages/app/index.tsx @@ -14,7 +14,7 @@ import history, { browserHistory } from 'app/services/history'; import i18n from 'app/services/i18n'; import { loadScript, debounce } from 'app/functions'; -import App from './App'; +import App from './shell'; const win: { [key: string]: any } = window as any; @@ -35,7 +35,7 @@ Promise.all([ i18n.ensureIntl(), // ensure, that intl is polyfilled before any rendering ]).then(() => { ReactDOM.render( - , + , document.getElementById('app'), ); diff --git a/packages/app/reducers.ts b/packages/app/reducers.ts index f204bc8..bf337ae 100644 --- a/packages/app/reducers.ts +++ b/packages/app/reducers.ts @@ -7,13 +7,14 @@ import accounts, { } from 'app/components/accounts/reducer'; import i18n, { State as I18nState } from 'app/components/i18n/reducer'; import popup, { State as PopupState } from 'app/components/ui/popup/reducer'; -import bsod from 'app/components/ui/bsod/reducer'; +import bsod, { State as BsodState } from 'app/components/ui/bsod/reducer'; import apps, { Apps } from 'app/components/dev/apps/reducer'; import { ThunkDispatch, ThunkAction as ReduxThunkAction } from 'redux-thunk'; import { Store as ReduxStore } from 'redux'; export interface RootState { auth: AuthState; + bsod: BsodState; accounts: AccountsState; user: User; popup: PopupState; @@ -41,7 +42,7 @@ export type Store = ReduxStore & { dispatch: Dispatch; }; -export default combineReducers({ +export default combineReducers({ bsod, auth, user, diff --git a/packages/app/services/api/oauth.ts b/packages/app/services/api/oauth.ts index 30c9096..5bb99fc 100644 --- a/packages/app/services/api/oauth.ts +++ b/packages/app/services/api/oauth.ts @@ -33,7 +33,7 @@ type OauthRequestData = { client_id: string; redirect_uri: string; response_type: string; - description: string; + description?: string; scope: string; prompt: string; login_hint?: string; @@ -44,7 +44,7 @@ export type OauthData = { clientId: string; redirectUrl: string; responseType: string; - description: string; + description?: string; scope: string; prompt: string; // comma separated list of 'none' | 'consent' | 'select_account'; loginHint?: string; diff --git a/packages/app/shell/App.tsx b/packages/app/shell/App.tsx new file mode 100644 index 0000000..28a54af --- /dev/null +++ b/packages/app/shell/App.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { hot } from 'react-hot-loader/root'; +import { Route, Switch } from 'react-router-dom'; +import { Store } from 'app/reducers'; +import AuthFlowRoute from 'app/containers/AuthFlowRoute'; +import RootPage from 'app/pages/root/RootPage'; +import SuccessOauthPage from 'app/pages/auth/SuccessOauthPage'; + +import ContextProvider from './ContextProvider'; + +const App = ({ store, history }: { store: Store; history: any }) => ( + + + + null} + /> + + + +); + +export default hot(App); diff --git a/packages/app/shell/ContextProvider.tsx b/packages/app/shell/ContextProvider.tsx new file mode 100644 index 0000000..a4c62de --- /dev/null +++ b/packages/app/shell/ContextProvider.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Provider as ReduxProvider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { IntlProvider } from 'app/components/i18n'; +import { Store } from 'app/reducers'; + +function ContextProvider({ + children, + store, + history, +}: { + children: React.ReactNode; + store: Store; + history: any; +}) { + return ( + + + {children} + + + ); +} + +export default ContextProvider; diff --git a/packages/app/shell/index.ts b/packages/app/shell/index.ts new file mode 100644 index 0000000..8df1f26 --- /dev/null +++ b/packages/app/shell/index.ts @@ -0,0 +1,2 @@ +export { default } from './App'; +export { default as ContextProvider } from './ContextProvider'; diff --git a/packages/app/storeFactory.js b/packages/app/storeFactory.ts similarity index 84% rename from packages/app/storeFactory.js rename to packages/app/storeFactory.ts index 8d5b236..540594b 100644 --- a/packages/app/storeFactory.js +++ b/packages/app/storeFactory.ts @@ -6,26 +6,25 @@ import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import persistState from 'redux-localstorage'; -import reducers from 'app/reducers'; +import reducers, { Store } from 'app/reducers'; -export default function storeFactory() { +export default function storeFactory(): Store { const middlewares = applyMiddleware(thunk); const persistStateEnhancer = persistState(['accounts', 'user'], { key: 'redux-storage', }); - /* global process: false */ let enhancer; if (process.env.NODE_ENV === 'production') { enhancer = compose(middlewares, persistStateEnhancer); } else { const composeEnhancers = - window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; enhancer = composeEnhancers(middlewares, persistStateEnhancer); } - const store = createStore(reducers, {}, enhancer); + const store = createStore(reducers, {}, enhancer) as Store; // Hot reload reducers if (module.hot && typeof module.hot.accept === 'function') {