@logto/react 0.1.5 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/context.d.ts CHANGED
@@ -4,8 +4,10 @@ export declare type LogtoContextProps = {
4
4
  logtoClient?: LogtoClient;
5
5
  isAuthenticated: boolean;
6
6
  loadingCount: number;
7
+ error?: Error;
7
8
  setIsAuthenticated: React.Dispatch<React.SetStateAction<boolean>>;
8
9
  setLoadingCount: React.Dispatch<React.SetStateAction<number>>;
10
+ setError: React.Dispatch<React.SetStateAction<Error | undefined>>;
9
11
  };
10
12
  export declare const throwContextError: () => never;
11
13
  export declare const LogtoContext: import("react").Context<LogtoContextProps>;
package/lib/context.js CHANGED
@@ -10,6 +10,8 @@ exports.LogtoContext = (0, react_1.createContext)({
10
10
  logtoClient: undefined,
11
11
  isAuthenticated: false,
12
12
  loadingCount: 0,
13
+ error: undefined,
13
14
  setIsAuthenticated: exports.throwContextError,
14
15
  setLoadingCount: exports.throwContextError,
16
+ setError: exports.throwContextError,
15
17
  });
@@ -1,14 +1,18 @@
1
1
  import { IdTokenClaims, UserInfoResponse } from '@logto/browser';
2
- import { Nullable } from '@silverhand/essentials';
3
2
  declare type Logto = {
4
3
  isAuthenticated: boolean;
5
4
  isLoading: boolean;
6
- fetchUserInfo: () => Promise<UserInfoResponse>;
7
- getAccessToken: (resource?: string) => Promise<Nullable<string>>;
8
- getIdTokenClaims: () => IdTokenClaims;
5
+ error?: Error;
6
+ fetchUserInfo: () => Promise<UserInfoResponse | undefined>;
7
+ getAccessToken: (resource?: string) => Promise<string | undefined>;
8
+ getIdTokenClaims: () => IdTokenClaims | undefined;
9
9
  signIn: (redirectUri: string) => Promise<void>;
10
10
  signOut: (postLogoutRedirectUri: string) => Promise<void>;
11
11
  };
12
- declare const useHandleSignInCallback: () => void;
12
+ declare const useHandleSignInCallback: (returnToPageUrl?: string) => {
13
+ isLoading: boolean;
14
+ isAuthenticated: boolean;
15
+ error: Error | undefined;
16
+ };
13
17
  declare const useLogto: () => Logto;
14
18
  export { useLogto, useHandleSignInCallback };
@@ -4,7 +4,8 @@ exports.useHandleSignInCallback = exports.useLogto = void 0;
4
4
  const react_1 = require("react");
5
5
  const context_1 = require("../context");
6
6
  const useLoadingState = () => {
7
- const { setLoadingCount } = (0, react_1.useContext)(context_1.LogtoContext);
7
+ const { loadingCount, setLoadingCount } = (0, react_1.useContext)(context_1.LogtoContext);
8
+ const isLoading = loadingCount > 0;
8
9
  const setLoadingState = (0, react_1.useCallback)((state) => {
9
10
  if (state) {
10
11
  setLoadingCount((count) => count + 1);
@@ -13,78 +14,137 @@ const useLoadingState = () => {
13
14
  setLoadingCount((count) => Math.max(0, count - 1));
14
15
  }
15
16
  }, [setLoadingCount]);
16
- return setLoadingState;
17
+ return { isLoading, setLoadingState };
18
+ };
19
+ const useErrorHandler = () => {
20
+ const { setError } = (0, react_1.useContext)(context_1.LogtoContext);
21
+ const handleError = (0, react_1.useCallback)((error, fallbackErrorMessage) => {
22
+ if (error instanceof Error) {
23
+ setError(error);
24
+ }
25
+ else if (fallbackErrorMessage) {
26
+ setError(new Error(fallbackErrorMessage));
27
+ }
28
+ }, [setError]);
29
+ return { handleError };
17
30
  };
18
- const useHandleSignInCallback = () => {
19
- const { logtoClient, isAuthenticated, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
20
- const setLoadingState = useLoadingState();
31
+ const useHandleSignInCallback = (returnToPageUrl = window.location.origin) => {
32
+ const { logtoClient, isAuthenticated, error, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
33
+ const { isLoading, setLoadingState } = useLoadingState();
34
+ const { handleError } = useErrorHandler();
21
35
  const handleSignInCallback = (0, react_1.useCallback)(async (callbackUri) => {
22
36
  if (!logtoClient) {
23
37
  return (0, context_1.throwContextError)();
24
38
  }
25
- setLoadingState(true);
26
- await logtoClient.handleSignInCallback(callbackUri);
27
- setLoadingState(false);
28
- setIsAuthenticated(true);
29
- }, [logtoClient, setIsAuthenticated, setLoadingState]);
39
+ try {
40
+ setLoadingState(true);
41
+ await logtoClient.handleSignInCallback(callbackUri);
42
+ setIsAuthenticated(true);
43
+ window.location.assign(returnToPageUrl);
44
+ }
45
+ catch (error) {
46
+ handleError(error, 'Unexpected error occurred while handling sign in callback.');
47
+ }
48
+ finally {
49
+ setLoadingState(false);
50
+ }
51
+ }, [logtoClient, returnToPageUrl, setIsAuthenticated, setLoadingState, handleError]);
30
52
  (0, react_1.useEffect)(() => {
31
53
  if (!isAuthenticated && logtoClient?.isSignInRedirected(window.location.href)) {
32
54
  void handleSignInCallback(window.location.href);
33
55
  }
34
56
  }, [handleSignInCallback, isAuthenticated, logtoClient]);
57
+ return {
58
+ isLoading,
59
+ isAuthenticated,
60
+ error,
61
+ };
35
62
  };
36
63
  exports.useHandleSignInCallback = useHandleSignInCallback;
37
64
  const useLogto = () => {
38
- const { logtoClient, loadingCount, isAuthenticated, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
39
- const setLoadingState = useLoadingState();
65
+ const { logtoClient, loadingCount, isAuthenticated, error, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
66
+ const { setLoadingState } = useLoadingState();
67
+ const { handleError } = useErrorHandler();
40
68
  const isLoading = loadingCount > 0;
41
69
  const signIn = (0, react_1.useCallback)(async (redirectUri) => {
42
70
  if (!logtoClient) {
43
71
  return (0, context_1.throwContextError)();
44
72
  }
45
- setLoadingState(true);
46
- await logtoClient.signIn(redirectUri);
47
- setLoadingState(false);
48
- }, [logtoClient, setLoadingState]);
73
+ try {
74
+ setLoadingState(true);
75
+ await logtoClient.signIn(redirectUri);
76
+ }
77
+ catch (error) {
78
+ handleError(error, 'Unexpected error occurred while signing in.');
79
+ }
80
+ finally {
81
+ setLoadingState(false);
82
+ }
83
+ }, [logtoClient, setLoadingState, handleError]);
49
84
  const signOut = (0, react_1.useCallback)(async (postLogoutRedirectUri) => {
50
85
  if (!logtoClient) {
51
86
  return (0, context_1.throwContextError)();
52
87
  }
53
- setLoadingState(true);
54
- await logtoClient.signOut(postLogoutRedirectUri);
55
- setLoadingState(false);
56
- setIsAuthenticated(false);
57
- }, [logtoClient, setIsAuthenticated, setLoadingState]);
88
+ try {
89
+ setLoadingState(true);
90
+ await logtoClient.signOut(postLogoutRedirectUri);
91
+ setIsAuthenticated(false);
92
+ }
93
+ catch (error) {
94
+ handleError(error, 'Unexpected error occurred while signing out.');
95
+ }
96
+ finally {
97
+ setLoadingState(false);
98
+ }
99
+ }, [logtoClient, setIsAuthenticated, setLoadingState, handleError]);
58
100
  const fetchUserInfo = (0, react_1.useCallback)(async () => {
59
101
  if (!logtoClient) {
60
102
  return (0, context_1.throwContextError)();
61
103
  }
62
- setLoadingState(true);
63
- const userInfo = await logtoClient.fetchUserInfo();
64
- setLoadingState(false);
65
- return userInfo;
66
- }, [logtoClient, setLoadingState]);
104
+ try {
105
+ setLoadingState(true);
106
+ return await logtoClient.fetchUserInfo();
107
+ }
108
+ catch (error) {
109
+ handleError(error, 'Unexpected error occurred while fetching user info.');
110
+ }
111
+ finally {
112
+ setLoadingState(false);
113
+ }
114
+ }, [logtoClient, setLoadingState, handleError]);
67
115
  const getAccessToken = (0, react_1.useCallback)(async (resource) => {
68
116
  if (!logtoClient) {
69
117
  return (0, context_1.throwContextError)();
70
118
  }
71
- setLoadingState(true);
72
- const accessToken = await logtoClient.getAccessToken(resource);
73
- setLoadingState(false);
74
- return accessToken;
75
- }, [logtoClient, setLoadingState]);
119
+ try {
120
+ setLoadingState(true);
121
+ return await logtoClient.getAccessToken(resource);
122
+ }
123
+ catch (error) {
124
+ handleError(error, 'Unexpected error occurred while getting access token.');
125
+ }
126
+ finally {
127
+ setLoadingState(false);
128
+ }
129
+ }, [logtoClient, setLoadingState, handleError]);
76
130
  const getIdTokenClaims = (0, react_1.useCallback)(() => {
77
131
  if (!logtoClient) {
78
132
  return (0, context_1.throwContextError)();
79
133
  }
80
- return logtoClient.getIdTokenClaims();
81
- }, [logtoClient]);
134
+ try {
135
+ return logtoClient.getIdTokenClaims();
136
+ }
137
+ catch (error) {
138
+ handleError(error, 'Unexpected error occurred while getting id token claims.');
139
+ }
140
+ }, [logtoClient, handleError]);
82
141
  if (!logtoClient) {
83
142
  return (0, context_1.throwContextError)();
84
143
  }
85
144
  return {
86
145
  isAuthenticated,
87
146
  isLoading,
147
+ error,
88
148
  signIn,
89
149
  signOut,
90
150
  fetchUserInfo,
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export type { LogtoContextProps } from './context';
2
- export type { LogtoConfig, IdTokenClaims, UserInfoResponse } from '@logto/browser';
2
+ export type { LogtoConfig, IdTokenClaims, UserInfoResponse, LogtoClientError, LogtoClientErrorCode, } from '@logto/browser';
3
3
  export * from './provider';
4
4
  export { useLogto, useHandleSignInCallback } from './hooks';
package/lib/provider.js CHANGED
@@ -34,13 +34,16 @@ const LogtoProvider = ({ config, children }) => {
34
34
  const [loadingCount, setLoadingCount] = (0, react_1.useState)(0);
35
35
  const memorizedLogtoClient = (0, react_1.useMemo)(() => ({ logtoClient: new browser_1.default(config) }), [config]);
36
36
  const [isAuthenticated, setIsAuthenticated] = (0, react_1.useState)(memorizedLogtoClient.logtoClient.isAuthenticated);
37
+ const [error, setError] = (0, react_1.useState)();
37
38
  const memorizedContextValue = (0, react_1.useMemo)(() => ({
38
39
  ...memorizedLogtoClient,
39
40
  isAuthenticated,
40
41
  setIsAuthenticated,
41
42
  loadingCount,
42
43
  setLoadingCount,
43
- }), [memorizedLogtoClient, isAuthenticated, loadingCount]);
44
+ error,
45
+ setError,
46
+ }), [memorizedLogtoClient, isAuthenticated, loadingCount, error]);
44
47
  return react_1.default.createElement(context_1.LogtoContext.Provider, { value: memorizedContextValue }, children);
45
48
  };
46
49
  exports.LogtoProvider = LogtoProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logto/react",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "main": "./lib/index.js",
5
5
  "exports": "./lib/index.js",
6
6
  "typings": "./lib/index.d.ts",
@@ -24,24 +24,25 @@
24
24
  "prepack": "pnpm test"
25
25
  },
26
26
  "dependencies": {
27
- "@logto/browser": "^0.1.5",
27
+ "@logto/browser": "^0.1.7",
28
28
  "@silverhand/essentials": "^1.1.6"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@jest/types": "^27.5.1",
32
- "@silverhand/eslint-config": "^0.10.0",
33
- "@silverhand/eslint-config-react": "^0.10.0",
34
- "@silverhand/ts-config": "^0.10.0",
35
- "@silverhand/ts-config-react": "^0.10.0",
32
+ "@silverhand/eslint-config": "^0.14.0",
33
+ "@silverhand/eslint-config-react": "^0.14.0",
34
+ "@silverhand/ts-config": "^0.14.0",
35
+ "@silverhand/ts-config-react": "^0.14.0",
36
36
  "@testing-library/react-hooks": "^8.0.0",
37
37
  "@types/jest": "^27.4.1",
38
38
  "@types/react": "^17.0.39",
39
39
  "eslint": "^8.9.0",
40
40
  "jest": "^27.5.1",
41
41
  "lint-staged": "^12.3.4",
42
+ "postcss": "^8.4.6",
42
43
  "prettier": "^2.5.1",
43
44
  "react": "^17.0.2",
44
- "stylelint": "^13.13.1",
45
+ "stylelint": "^14.8.2",
45
46
  "ts-jest": "^27.0.4",
46
47
  "typescript": "^4.6.2"
47
48
  },
@@ -55,5 +56,5 @@
55
56
  "publishConfig": {
56
57
  "access": "public"
57
58
  },
58
- "gitHead": "ed98d55270ae923f95a57fe4f3bc5a5959518c06"
59
+ "gitHead": "8adf9495676b65649b093f9e8b460a1568e08e0a"
59
60
  }