@logto/react 0.1.4 → 0.1.7
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 +2 -0
- package/lib/context.js +2 -0
- package/lib/hooks/index.d.ts +8 -5
- package/lib/hooks/index.js +86 -27
- package/lib/provider.js +4 -1
- package/package.json +11 -10
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
|
});
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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: () =>
|
|
12
|
+
declare const useHandleSignInCallback: (returnToPageUrl?: string) => {
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
isAuthenticated: boolean;
|
|
15
|
+
};
|
|
13
16
|
declare const useLogto: () => Logto;
|
|
14
17
|
export { useLogto, useHandleSignInCallback };
|
package/lib/hooks/index.js
CHANGED
|
@@ -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,136 @@ 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 = () => {
|
|
31
|
+
const useHandleSignInCallback = (returnToPageUrl = window.location.origin) => {
|
|
19
32
|
const { logtoClient, isAuthenticated, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
|
|
20
|
-
const setLoadingState = useLoadingState();
|
|
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
39
|
setLoadingState(true);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
40
|
+
try {
|
|
41
|
+
await logtoClient.handleSignInCallback(callbackUri);
|
|
42
|
+
setIsAuthenticated(true);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
handleError(error, 'Unexpected error occurred while handling sign in callback.');
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
setLoadingState(false);
|
|
49
|
+
}
|
|
50
|
+
window.location.assign(returnToPageUrl);
|
|
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
|
+
};
|
|
35
61
|
};
|
|
36
62
|
exports.useHandleSignInCallback = useHandleSignInCallback;
|
|
37
63
|
const useLogto = () => {
|
|
38
|
-
const { logtoClient, loadingCount, isAuthenticated, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
|
|
39
|
-
const setLoadingState = useLoadingState();
|
|
64
|
+
const { logtoClient, loadingCount, isAuthenticated, error, setIsAuthenticated } = (0, react_1.useContext)(context_1.LogtoContext);
|
|
65
|
+
const { setLoadingState } = useLoadingState();
|
|
66
|
+
const { handleError } = useErrorHandler();
|
|
40
67
|
const isLoading = loadingCount > 0;
|
|
41
68
|
const signIn = (0, react_1.useCallback)(async (redirectUri) => {
|
|
42
69
|
if (!logtoClient) {
|
|
43
70
|
return (0, context_1.throwContextError)();
|
|
44
71
|
}
|
|
45
72
|
setLoadingState(true);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
try {
|
|
74
|
+
await logtoClient.signIn(redirectUri);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
handleError(error, 'Unexpected error occurred while signing in.');
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
setLoadingState(false);
|
|
81
|
+
}
|
|
82
|
+
}, [logtoClient, setLoadingState, handleError]);
|
|
49
83
|
const signOut = (0, react_1.useCallback)(async (postLogoutRedirectUri) => {
|
|
50
84
|
if (!logtoClient) {
|
|
51
85
|
return (0, context_1.throwContextError)();
|
|
52
86
|
}
|
|
53
87
|
setLoadingState(true);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
88
|
+
try {
|
|
89
|
+
await logtoClient.signOut(postLogoutRedirectUri);
|
|
90
|
+
setIsAuthenticated(false);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
handleError(error, 'Unexpected error occurred while signing out.');
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
setLoadingState(false);
|
|
97
|
+
}
|
|
98
|
+
}, [logtoClient, setIsAuthenticated, setLoadingState, handleError]);
|
|
58
99
|
const fetchUserInfo = (0, react_1.useCallback)(async () => {
|
|
59
100
|
if (!logtoClient) {
|
|
60
101
|
return (0, context_1.throwContextError)();
|
|
61
102
|
}
|
|
62
103
|
setLoadingState(true);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
104
|
+
try {
|
|
105
|
+
return await logtoClient.fetchUserInfo();
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
handleError(error, 'Unexpected error occurred while fetching user info.');
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
setLoadingState(false);
|
|
112
|
+
}
|
|
113
|
+
}, [logtoClient, setLoadingState, handleError]);
|
|
67
114
|
const getAccessToken = (0, react_1.useCallback)(async (resource) => {
|
|
68
115
|
if (!logtoClient) {
|
|
69
116
|
return (0, context_1.throwContextError)();
|
|
70
117
|
}
|
|
71
118
|
setLoadingState(true);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
119
|
+
try {
|
|
120
|
+
return await logtoClient.getAccessToken(resource);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
handleError(error, 'Unexpected error occurred while getting access token.');
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
setLoadingState(false);
|
|
127
|
+
}
|
|
128
|
+
}, [logtoClient, setLoadingState, handleError]);
|
|
76
129
|
const getIdTokenClaims = (0, react_1.useCallback)(() => {
|
|
77
130
|
if (!logtoClient) {
|
|
78
131
|
return (0, context_1.throwContextError)();
|
|
79
132
|
}
|
|
80
|
-
|
|
81
|
-
|
|
133
|
+
try {
|
|
134
|
+
return logtoClient.getIdTokenClaims();
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
handleError(error, 'Unexpected error occurred while getting id token claims.');
|
|
138
|
+
}
|
|
139
|
+
}, [logtoClient, handleError]);
|
|
82
140
|
if (!logtoClient) {
|
|
83
141
|
return (0, context_1.throwContextError)();
|
|
84
142
|
}
|
|
85
143
|
return {
|
|
86
144
|
isAuthenticated,
|
|
87
145
|
isLoading,
|
|
146
|
+
error,
|
|
88
147
|
signIn,
|
|
89
148
|
signOut,
|
|
90
149
|
fetchUserInfo,
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"exports": "./lib/index.js",
|
|
6
6
|
"typings": "./lib/index.d.ts",
|
|
@@ -21,27 +21,28 @@
|
|
|
21
21
|
"lint": "eslint --ext .ts --ext .tsx src",
|
|
22
22
|
"test": "jest",
|
|
23
23
|
"test:coverage": "jest --silent --coverage",
|
|
24
|
-
"prepack": "pnpm test
|
|
24
|
+
"prepack": "pnpm test"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@logto/browser": "^0.1.
|
|
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.
|
|
33
|
-
"@silverhand/eslint-config-react": "^0.
|
|
34
|
-
"@silverhand/ts-config": "^0.
|
|
35
|
-
"@silverhand/ts-config-react": "^0.
|
|
36
|
-
"@testing-library/react-hooks": "^
|
|
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
|
+
"@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": "^
|
|
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": "
|
|
59
|
+
"gitHead": "45f2ad06fa069eac66016696703b1a37e1509ffb"
|
|
59
60
|
}
|