diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index e6c6a2a..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import React, {
- createContext,
- useContext,
- useEffect,
- useCallback,
- useReducer,
-} from 'react';
-
-export const AuthContext = createContext();
-
-export function reducer(state, action) {
- switch (action.type) {
- case 'loading': {
- return { ...state, loading: action.payload };
- }
- case 'currentUser': {
- return { ...state, currentUser: action.payload };
- }
- default: {
- return state;
- }
- }
-}
-
-export const AuthProvider = ({
- children,
- getCurrentUser,
- beforeLoginUser,
- afterLoginUser,
- beforeLogoutUser,
- afterLogoutUser,
- renderLoading,
-}) => {
- const [state, dispatch] = useReducer(reducer, {
- loading: getCurrentUser ? true : false,
- currentUser: null,
- });
- const { loading, currentUser } = state;
-
- function setLoading(payload) {
- dispatch({ type: 'loading', payload });
- }
-
- function setCurrentUser(payload) {
- dispatch({ type: 'currentUser', payload });
- }
-
- const loginUser = useCallback(
- (user) => {
- return beforeLoginUser(user)
- .then((user) => {
- setCurrentUser(user);
- return user;
- })
- .then((user) => afterLoginUser(user));
- },
- [beforeLoginUser, afterLoginUser]
- );
-
- const logoutUser = useCallback(() => {
- return beforeLogoutUser(currentUser)
- .then((user) => {
- setCurrentUser(null);
- return user;
- })
- .then((user) => afterLogoutUser(user));
- }, [currentUser, beforeLogoutUser, afterLogoutUser]);
-
- const refreshUser = useCallback(() => {
- if (getCurrentUser) {
- getCurrentUser()
- .then((user) => {
- if (user) {
- return loginUser(user).then(() => {
- setLoading(false);
- });
- } else {
- setCurrentUser(null);
- setLoading(false);
- }
- })
- .catch((err) => {
- console.warn(err);
- setCurrentUser(null);
- setLoading(false);
- });
- } else {
- setLoading(false);
- }
- }, [getCurrentUser, loginUser]);
-
- const providerValue = {
- loading,
- setLoading,
- loginUser,
- logoutUser,
- refreshUser,
- currentUser,
- setCurrentUser,
- };
-
- useEffect(() => {
- refreshUser();
- }, [refreshUser]);
-
- if (loading && renderLoading) {
- return (
-
- {React.createElement(renderLoading)}
-
- );
- }
-
- return (
-
- {children}
-
- );
-};
-
-AuthProvider.defaultProps = {
- beforeLoginUser: (user) => Promise.resolve(user),
- afterLoginUser: (user) => Promise.resolve(user),
- beforeLogoutUser: (user) => Promise.resolve(user),
- afterLogoutUser: (user) => Promise.resolve(user),
-};
-
-export const useAuth = () => {
- const context = useContext(AuthContext);
- return context;
-};
-
-export const AuthProtected = ({ renderLoading, renderLogin, children }) => {
- const { loading, currentUser } = useAuth();
-
- if (loading) {
- return renderLoading ? React.createElement(renderLoading) : null;
- }
-
- if (!currentUser) {
- return renderLogin ? React.createElement(renderLogin) : null;
- }
-
- return children;
-};
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..352ca4e
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,105 @@
+import React, {
+ createContext,
+ useState,
+ useContext,
+ useEffect,
+ useCallback,
+ useReducer
+} from 'react';
+
+type AuthContextValue = {
+ login: (params: any) => Promise;
+ logout: (params: any) => Promise;
+ getViewer?: () => Promise;
+ [key: string]: any;
+};
+
+export const AuthContext = createContext();
+
+export function useAuth() {
+ const context = useContext(AuthContext);
+ return context;
+}
+
+export function useLogin() {
+ const context = useContext(AuthContext);
+ return context.login;
+}
+
+export function useLogout() {
+ const context = useContext(AuthContext);
+ return context.logout;
+}
+
+export function useViewer() {
+ const context = useContext(AuthContext);
+ return context.viewer;
+}
+
+export function AuthProvider({ children, provider, renderLoading }) {
+ const [{ loading, viewer, error }, setState] = useState({
+ loading: provider.getViewer ? true : false,
+ viewer: null,
+ error: null
+ });
+
+ const setViewer = (viewer) => {
+ setState({ loading: false, viewer, error: null });
+ };
+
+ const refreshViewer = useCallback(() => {
+ if (provider.getViewer) {
+ provider
+ .getViewer()
+ .then((viewer) => {
+ if (viewer) {
+ setState({ loading: false, viewer, error: null });
+ }
+ })
+ .catch((error) => {
+ setState({ loading: false, viewer: null, error });
+ });
+ }
+ }, [provider]);
+
+ useEffect(() => {
+ refreshViewer();
+ }, [refreshViewer]);
+
+ const providerValue = {
+ loading,
+ viewer,
+ setViewer,
+ refreshViewer,
+ login: provider.login,
+ logout: provider.logout
+ };
+
+ if (loading && renderLoading) {
+ return (
+
+ {React.createElement(renderLoading)}
+
+ );
+ }
+
+ return (
+
+ {children}
+
+ );
+}
+
+export const AuthProtected = ({ renderLoading, renderLogin, children }) => {
+ const { loading, viewer } = useAuth();
+
+ if (loading) {
+ return renderLoading ? React.createElement(renderLoading) : null;
+ }
+
+ if (!viewer) {
+ return renderLogin ? React.createElement(renderLogin) : null;
+ }
+
+ return children;
+};