FIX;Auth selector native types

This commit is contained in:
romanjaros 2022-03-25 07:06:09 +01:00 committed by Roman Jaroš
parent c46ec61fd5
commit 46cc148341
14 changed files with 31517 additions and 78283 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.gitignore vendored
View file

@ -15,3 +15,5 @@ tsconfig.tsbuildinfo
tsconfig.build.tsbuildinfo tsconfig.build.tsbuildinfo
typedoc.json typedoc.json
.DS_Store

53169
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,8 @@
"classnames": "2.3.1", "classnames": "2.3.1",
"clipboard": "2.0.10", "clipboard": "2.0.10",
"date-fns": "2.28.0", "date-fns": "2.28.0",
"postcss": "8.4.12", "postcss": "^8.4.7",
"proxy-memoize": "0.3.8",
"ramda": "0.28.0", "ramda": "0.28.0",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
@ -40,7 +41,6 @@
"react-router-dom": "6.3.0", "react-router-dom": "6.3.0",
"redux": "4.2.0", "redux": "4.2.0",
"redux-thunk": "2.4.1", "redux-thunk": "2.4.1",
"typescript": "4.6.3",
"yup": "0.32.11" "yup": "0.32.11"
}, },
"devDependencies": { "devDependencies": {
@ -83,9 +83,11 @@
"postcss-cli": "9.1.0", "postcss-cli": "9.1.0",
"prettier": "2.6.2", "prettier": "2.6.2",
"react-docgen-typescript-loader": "3.7.2", "react-docgen-typescript-loader": "3.7.2",
"tailwindcss": "3.0.23",
"ts-jest": "27.1.4", "ts-jest": "27.1.4",
"ts-node": "10.7.0", "ts-node": "10.7.0",
"tsconfig-paths": "3.14.1", "tsconfig-paths": "3.14.1",
"typescript": "4.6.2",
"typescript-json-schema": "0.53.0", "typescript-json-schema": "0.53.0",
"webpack": "5.72.0", "webpack": "5.72.0",
"webpack-cli": "4.9.2", "webpack-cli": "4.9.2",

View file

@ -1,8 +1,8 @@
import { Action } from '@treejs/types/redux/actions'; import { Action } from '@treejs/types/redux/actions';
import { ACTIONS, FetchConfig } from './types'; import { Actions, FetchConfig } from './types';
export const fetchData = <C = unknown>(config: FetchConfig<C>): Action<FetchConfig<C>> => ({ export const fetchData = <C = unknown>(config: FetchConfig<C>): Action<FetchConfig<C>> => ({
type: ACTIONS.FETCH, type: Actions.FETCH,
payload: config, payload: config,
}); });

View file

@ -3,22 +3,22 @@ import React, { useMemo } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { getIsFetching } from '../selectors'; import { getIsFetching } from '../selectors';
import { FetchShape } from '../types'; import { FetchShapes } from '../types';
type IProps = { type IProps = {
path: string; path: string;
placeholder?: React.ReactElement; placeholder?: React.ReactElement;
shape: FetchShape; shape: FetchShapes;
}; };
const FetchLoader: React.FC<IProps> = (props) => { const FetchLoader: React.FC<IProps> = (props) => {
const { children, path, shape } = props; const { children, path, shape } = props;
const isFetching = useSelector((state) => getIsFetching(state, path)); const isFetching = useSelector((state: any) => getIsFetching([state, path]));
const placeholder = useMemo(() => { const placeholder = useMemo(() => {
switch (shape) { switch (shape) {
case FetchShape.input: case FetchShapes.input:
return ( return (
<> <>
<div className="h-4 bg-gray-200 rounded w-1/4" /> <div className="h-4 bg-gray-200 rounded w-1/4" />

View file

@ -8,7 +8,7 @@ import { Action } from '@treejs/types/redux/actions';
import { isJSON, isNilOrEmpty } from '@treejs/utils'; import { isJSON, isNilOrEmpty } from '@treejs/utils';
import { onError, onRequest, onSuccess } from './slice'; import { onError, onRequest, onSuccess } from './slice';
import { ACTIONS, FetchConfig } from './types'; import { Actions, FetchConfig } from './types';
import { resolveParams } from './utils'; import { resolveParams } from './utils';
type ISettings<C> = { type ISettings<C> = {
@ -42,9 +42,9 @@ export const apiMiddleware =
(store: IStore) => (store: IStore) =>
(next) => (next) =>
async (action: Action<FetchConfig<C>>) => { async (action: Action<FetchConfig<C>>) => {
if (action.type === ACTIONS.FETCH) { if (action.type === Actions.FETCH) {
if (isNilOrEmpty(action.payload.url)) { if (isNilOrEmpty(action.payload.url)) {
throw `URL '${action.payload.url}' is not valid, please specify valid URL!`; throw new Error(`URL '${action.payload.url}' is not valid, please specify valid URL!`);
} }
if (is(Function, action.payload.onRequest)) { if (is(Function, action.payload.onRequest)) {
@ -56,16 +56,18 @@ export const apiMiddleware =
const baseUrl = action.payload.baseUrl || setting.BASE_ENDPOINT_URL; const baseUrl = action.payload.baseUrl || setting.BASE_ENDPOINT_URL;
const endpoint = `${baseUrl}${resolveParams(action.payload.url, action.payload.queryParams)}`; const endpoint = `${baseUrl}${resolveParams(action.payload.url, action.payload.queryParams)}`;
const tokenValue = getAuthenticateAttribute( const tokenValue = getAuthenticateAttribute([
store.getState(), store.getState(),
setting?.authorization?.authAttribute || 'accessToken' {
) as string; attrName: setting?.authorization?.authAttribute || 'accessToken',
},
]);
const authorizationToken = !isNilOrEmpty(tokenValue) const authorizationToken = !isNilOrEmpty(tokenValue)
? { ? {
[setting?.authorization?.header || 'Authorization']: `${ [setting?.authorization?.header || 'Authorization']: `${
setting?.authorization?.schema || 'Bearer' setting?.authorization?.schema || 'Bearer'
} ${tokenValue}`, } ${tokenValue.toString()}`,
} }
: {}; : {};

View file

@ -1,18 +1,13 @@
import { pathOr, propOr } from 'ramda'; import memoize from 'proxy-memoize';
import { createSelector } from 'reselect'; import { APIReducer, FetchState } from '@treejs/api/types';
import { APIReducer } from '@treejs/api/types';
import { EMPTY_OBJECT } from '@treejs/constants/empty';
import { ROOT_REDUCER_NAME } from '@treejs/constants/redux'; import { ROOT_REDUCER_NAME } from '@treejs/constants/redux';
const root = pathOr(EMPTY_OBJECT, [ROOT_REDUCER_NAME, 'fetch']); import { API_REDUCER_NAME } from './constants';
export const getIsFetching = createSelector( export const getIsFetching = memoize<
root, [{ [ROOT_REDUCER_NAME]: { [API_REDUCER_NAME]: APIReducer } }, string],
(state: any, fetchUrl: string) => fetchUrl, FetchState['isFetching']
(state, url): boolean => { >(([state, fetchUrl]) => {
const fetchState: APIReducer = propOr({}, url, state); return state[ROOT_REDUCER_NAME][API_REDUCER_NAME][fetchUrl].isFetching;
return propOr(false, 'isFetching', fetchState); });
}
);

View file

@ -6,7 +6,7 @@ export enum FetchMethod {
PUT = 'put', PUT = 'put',
} }
export enum ACTIONS { export enum Actions {
FETCH = 'API_FETCH/FETCH', FETCH = 'API_FETCH/FETCH',
} }
@ -31,7 +31,7 @@ export type FetchState = {
isFetching: boolean; isFetching: boolean;
}; };
export enum FetchShape { export enum FetchShapes {
input, input,
} }

View file

@ -14,7 +14,8 @@
"@treejs/types": "0.12.1" "@treejs/types": "0.12.1"
}, },
"peerDependencies": { "peerDependencies": {
"@reduxjs/toolkit": "1.8.0", "@reduxjs/toolkit": "^1.8.0",
"proxy-memoize": "0.3.8",
"redux": "4.0.5" "redux": "4.0.5"
} }
} }

View file

@ -1,4 +1,5 @@
import { type Selector, createSelector } from '@reduxjs/toolkit'; import memoize from 'proxy-memoize';
import { DefaultRootState } from 'react-redux';
import { ROOT_REDUCER_NAME } from '@treejs/constants/redux'; import { ROOT_REDUCER_NAME } from '@treejs/constants/redux';
@ -7,12 +8,12 @@ import { IAuthOption } from './types';
const reducer = <P>(state: any): IAuthOption<P> => state[ROOT_REDUCER_NAME][AUTH_REDUCER_NAME]; const reducer = <P>(state: any): IAuthOption<P> => state[ROOT_REDUCER_NAME][AUTH_REDUCER_NAME];
export const isAuthenticated = createSelector<[Selector<any, IAuthOption<any>>], boolean>( export const isAuthenticated = memoize<DefaultRootState, boolean>((state) => {
[reducer], return reducer<Record<string, unknown>>(state).authenticated;
(state) => state.authenticated });
);
export const getAuthenticateAttribute = createSelector< export const getAuthenticateAttribute = memoize<[DefaultRootState, { attrName: string }], unknown>(
[Selector<any, IAuthOption<any>>, Selector<{ name: keyof IAuthOption<any> }, string>], ([state, { attrName }]) => {
keyof IAuthOption<any> return reducer<Record<string, unknown>>(state)[attrName];
>([reducer, (_, { name }) => name], (state, name) => state[name]); }
);

View file

@ -8,13 +8,13 @@
"clean": "rm -rf dist/", "clean": "rm -rf dist/",
"ci:publish": "mkdir dist && cp -r src/* package.json dist && cd dist/ && npm publish && rm package.json" "ci:publish": "mkdir dist && cp -r src/* package.json dist && cd dist/ && npm publish && rm package.json"
}, },
"devDependencies": { "dependencies": {
"postcss-import": "14.0.2", "postcss-import": "^14.0.2",
"postcss-nested": "5.0.6", "postcss-nested": "^5.0.6"
"tailwindcss": "3.0.23"
}, },
"peerDependencies": { "peerDependencies": {
"classnames": "2.2.6", "classnames": "^2.2.6",
"postcss": "8.4.7" "postcss": "^8.4.7",
"tailwindcss": "^3.0.23"
} }
} }

View file

@ -1,11 +0,0 @@
import { Action } from './actions';
class ReduxModel {
public REDUCER_NAME: string;
public initialState: Record<string, unknown>;
public getReducer: (state: any) => any;
public reducer: (state: any, { type, payload }: Action<any>) => any;
}
export default ReduxModel;

View file

@ -1,19 +0,0 @@
import { APIReducer } from '@treejs/api/types';
import { AUTH_REDUCER_NAME } from '@treejs/auth/constants';
import { AuthReducer } from '@treejs/auth/types';
import { MODAL_REDUCER_NAME } from '@treejs/components/Modal/constants';
import { ModalReducer } from '@treejs/components/Modal/types';
import { TOASTER_REDUCER_NAME } from '@treejs/components/Toaster/constants';
import { ToasterReducer } from '@treejs/components/Toaster/types';
import { ROOT_REDUCER_NAME } from '@treejs/constants/redux';
export type TreeJSReducer = {
[AUTH_REDUCER_NAME]: AuthReducer<any>;
[MODAL_REDUCER_NAME]: ModalReducer;
[TOASTER_REDUCER_NAME]: ToasterReducer;
fetch: APIReducer;
};
export type Store = {
[ROOT_REDUCER_NAME]: TreeJSReducer;
};