@refinedev/core 4.1.4 → 4.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refinedev/core",
3
- "version": "4.1.4",
3
+ "version": "4.1.6",
4
4
  "description": "refine is a React-based framework for building internal tools, rapidly. It ships with Ant Design System, an enterprise-level UI toolkit.",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -98,105 +98,147 @@ export function Authenticated({
98
98
  loading: loadingContent,
99
99
  }: AuthenticatedProps | LegacyAuthenticatedProps): JSX.Element | null {
100
100
  const activeAuthProvider = useActiveAuthProvider();
101
+ const routerType = useRouterType();
101
102
 
102
- const isLegacy = Boolean(activeAuthProvider?.isLegacy);
103
-
104
- const isAuthenticatedProps = useIsAuthenticated({
105
- v3LegacyAuthProviderCompatible: Boolean(activeAuthProvider?.isLegacy),
106
- });
103
+ const hasAuthProvider = Boolean(activeAuthProvider?.isProvided);
104
+ const isLegacyAuth = Boolean(activeAuthProvider?.isLegacy);
105
+ const isLegacyRouter = routerType === "legacy";
107
106
 
108
- const routerType = useRouterType();
109
107
  const parsed = useParsed();
110
108
  const go = useGo();
111
109
  const deferredGo = useDeferredGo();
112
110
  const { replace } = useNavigation();
113
111
  const { useLocation } = useRouterContext();
114
- const { pathname, search } = useLocation();
115
-
116
- const loading = isAuthenticatedProps.isLoading;
117
-
118
- const isAuthenticated = activeAuthProvider?.isProvided
119
- ? isLegacy
120
- ? isAuthenticatedProps.isSuccess
121
- : isAuthenticatedProps.data?.authenticated
122
- : true;
112
+ const legacyLocation = useLocation();
113
+
114
+ const {
115
+ isLoading,
116
+ isFetching,
117
+ // isRefetching,
118
+ isSuccess,
119
+ data: {
120
+ authenticated: isAuthenticatedStatus,
121
+ redirectTo: authenticatedRedirect,
122
+ } = {},
123
+ refetch,
124
+ } = useIsAuthenticated({
125
+ v3LegacyAuthProviderCompatible: isLegacyAuth,
126
+ });
123
127
 
124
- const appliedRedirect = isLegacy
125
- ? typeof redirectOnFail === "string"
126
- ? redirectOnFail
127
- : "/login"
128
- : typeof redirectOnFail === "string"
129
- ? redirectOnFail
130
- : (isAuthenticatedProps.data?.redirectTo as string | undefined);
128
+ React.useEffect(() => {
129
+ /**
130
+ * Refetch the authentication status if the content is changed (e.g. redirected or updated)
131
+ *
132
+ * This is done to avoid re-rendering the wrappers with the same content.
133
+ */
134
+
135
+ refetch();
136
+ }, [children, fallbackContent]);
137
+
138
+ const state = React.useRef<{
139
+ status: "initial" | "pending" | "settled";
140
+ content: React.ReactNode;
141
+ }>({
142
+ status: isLoading ? "initial" : "pending",
143
+ content: loadingContent ?? null,
144
+ });
131
145
 
132
- if (loading) {
133
- return loadingContent ? <>{loadingContent}</> : null;
146
+ /**
147
+ * Update state when fetching the authentication response.
148
+ */
149
+ if (isFetching) {
150
+ state.current.status = "pending";
151
+ } else if (!isFetching) {
152
+ state.current.status = "settled";
134
153
  }
135
154
 
136
- if (isAuthenticated) {
137
- return <>{children ?? null}</>;
138
- } else {
139
- if (typeof fallbackContent === "undefined") {
140
- if (routerType === "legacy") {
141
- const suffix = appendCurrentPathToQuery
142
- ? pathname
143
- ? `?to=${encodeURIComponent(
144
- `${pathname}${search ?? ""}`,
145
- )}`
146
- : ""
147
- : "";
148
-
149
- /**
150
- * Legacy provider handles `/login` path rendering.
151
- * So, we need to check if pathname is `/login` or not.
152
- * To avoid infinite loop.
153
- */
154
- const cleanPathname = pathname?.split(/[?#]/)[0];
155
- if (
156
- !cleanPathname?.includes("/login") &&
157
- cleanPathname !== redirectOnFail
158
- ) {
159
- replace(
160
- `/${(appliedRedirect ?? "/login").replace(
161
- /^\//,
162
- "",
163
- )}${suffix}`,
164
- );
165
- }
166
- } else {
167
- const cleanPathname = parsed.pathname?.split(/[?#]/)[0];
168
-
169
- /** If the route is same, do not redirect */
170
- if (cleanPathname === appliedRedirect) return null;
171
-
172
- /** If `to` is already present, do not append the new one. */
173
- const suffix = parsed.params?.to
174
- ? parsed.params?.to
175
- : go({
176
- to: parsed.pathname || "/",
177
- options: { keepQuery: true },
178
- type: "path",
179
- });
180
-
181
- if (appliedRedirect) {
155
+ /**
156
+ * Authentication status
157
+ */
158
+ const isAuthenticated = hasAuthProvider
159
+ ? isLegacyAuth
160
+ ? isSuccess
161
+ : isAuthenticatedStatus
162
+ : true;
163
+
164
+ if (state.current.status === "settled") {
165
+ /**
166
+ * If the state is settled, and query is resolved.
167
+ */
168
+ if (isAuthenticated) {
169
+ /**
170
+ * If user is authenticated, show the children.
171
+ */
172
+ state.current.content = <>{children ?? null}</>;
173
+ } else if (typeof fallbackContent !== "undefined") {
174
+ /**
175
+ * If user is not authenticated, and `fallback` is present, show the fallback content.
176
+ */
177
+ state.current.content = <>{fallbackContent}</>;
178
+ } else {
179
+ /**
180
+ * If there's no `fallback` content, redirect will be applied.
181
+ */
182
+
183
+ /**
184
+ * Current pathname to append to the redirect url.
185
+ */
186
+ const pathname = `${
187
+ isLegacyRouter ? legacyLocation?.pathname : parsed.pathname
188
+ }`.replace(/(\?.*|#.*)$/, "");
189
+
190
+ /**
191
+ * Redirect url to use, if `redirectOnFail` is set to a string,
192
+ * it will be used instead of `redirectTo` property of the `check` function's response.
193
+ */
194
+ const appliedRedirect = isLegacyAuth
195
+ ? typeof redirectOnFail === "string"
196
+ ? redirectOnFail
197
+ : "/login"
198
+ : typeof redirectOnFail === "string"
199
+ ? redirectOnFail
200
+ : (authenticatedRedirect as string | undefined);
201
+
202
+ /**
203
+ * Redirect if `appliedRedirect` is set.
204
+ */
205
+ if (appliedRedirect) {
206
+ if (isLegacyRouter) {
207
+ const toQuery = appendCurrentPathToQuery
208
+ ? `?to=${encodeURIComponent(pathname)}`
209
+ : "";
210
+ replace(`${appliedRedirect}${toQuery}`);
211
+ } else {
182
212
  deferredGo({
183
- // needs to be adjusted by the return value of `checkAuth`
184
- to: `/${appliedRedirect.replace(/^\//, "")}`,
185
- query:
186
- suffix &&
187
- typeof suffix === "string" &&
188
- suffix.length > 1
189
- ? {
190
- to: suffix,
191
- }
192
- : {},
213
+ to: appliedRedirect,
214
+ query: appendCurrentPathToQuery
215
+ ? {
216
+ to: parsed.params?.to
217
+ ? parsed.params.to
218
+ : go({
219
+ to: pathname,
220
+ options: { keepQuery: true },
221
+ type: "path",
222
+ }),
223
+ }
224
+ : undefined,
225
+ type: "replace",
193
226
  });
194
227
  }
195
228
  }
196
-
197
- return null;
198
229
  }
230
+ }
231
+
199
232
 
200
- return <>{fallbackContent}</>;
233
+ /**
234
+ * If there's no `authProvider` set, we don't need to check whether user is logged in or not.
235
+ */
236
+ if (!hasAuthProvider) {
237
+ return <>{children ?? null}</>;
201
238
  }
239
+
240
+ /**
241
+ * Returning the content based on the state, `fallback` or `children`.
242
+ */
243
+ return <>{state.current.content}</>;
202
244
  }
@@ -0,0 +1,15 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+
3
+ export const useInvalidateAuthStore = () => {
4
+ const queryClient = useQueryClient();
5
+
6
+ const invalidate = async () => {
7
+ await Promise.all([
8
+ queryClient.invalidateQueries(["useAuthenticated"]),
9
+ queryClient.invalidateQueries(["getUserIdentity"]),
10
+ queryClient.invalidateQueries(["usePermissions"]),
11
+ ]);
12
+ };
13
+
14
+ return invalidate;
15
+ };
@@ -63,7 +63,7 @@ export function useIsAuthenticated({
63
63
  );
64
64
 
65
65
  const legacyQueryResponse = useQuery(
66
- ["useAuthenticated", "v3LegacyAuthProviderCompatible", params],
66
+ ["useAuthenticated", params, "v3LegacyAuthProviderCompatible"],
67
67
  async () => (await checkAuth?.(params)) ?? {},
68
68
  {
69
69
  retry: false,
@@ -18,7 +18,7 @@ import { useAuthBindingsContext, useLegacyAuthContext } from "@contexts/auth";
18
18
  import { OpenNotificationParams, TLoginData } from "../../../interfaces";
19
19
  import { AuthActionResponse } from "src/interfaces/bindings/auth";
20
20
  import React from "react";
21
- import { useInvalidateAuthStore } from "../useInvaliteAuthStore";
21
+ import { useInvalidateAuthStore } from "../useInvalidateAuthStore";
22
22
 
23
23
  export type UseLoginLegacyProps<TVariables> = {
24
24
  v3LegacyAuthProviderCompatible: true;
@@ -129,7 +129,7 @@ export function useLogin<TVariables = {}>({
129
129
  TVariables,
130
130
  unknown
131
131
  >(["useLogin"], loginFromContext, {
132
- onSuccess: ({ success, redirectTo, error }) => {
132
+ onSuccess: async ({ success, redirectTo, error }) => {
133
133
  if (success) {
134
134
  close?.("login-error");
135
135
  }
@@ -138,6 +138,8 @@ export function useLogin<TVariables = {}>({
138
138
  open?.(buildNotification(error));
139
139
  }
140
140
 
141
+ await invalidateAuthStore();
142
+
141
143
  if (to && success) {
142
144
  if (routerType === "legacy") {
143
145
  replace(to as string);
@@ -155,10 +157,6 @@ export function useLogin<TVariables = {}>({
155
157
  replace("/");
156
158
  }
157
159
  }
158
-
159
- setTimeout(() => {
160
- invalidateAuthStore();
161
- });
162
160
  },
163
161
  onError: (error: any) => {
164
162
  open?.(buildNotification(error));
@@ -172,7 +170,9 @@ export function useLogin<TVariables = {}>({
172
170
  TVariables,
173
171
  unknown
174
172
  >(["useLogin", "v3LegacyAuthProviderCompatible"], legacyLoginFromContext, {
175
- onSuccess: (redirectPathFromAuth) => {
173
+ onSuccess: async (redirectPathFromAuth) => {
174
+ await invalidateAuthStore();
175
+
176
176
  if (to) {
177
177
  replace(to as string);
178
178
  }
@@ -194,10 +194,6 @@ export function useLogin<TVariables = {}>({
194
194
  }
195
195
 
196
196
  close?.("login-error");
197
-
198
- setTimeout(() => {
199
- invalidateAuthStore();
200
- });
201
197
  },
202
198
  onError: (error: any) => {
203
199
  open?.(buildNotification(error));
@@ -8,7 +8,7 @@ import { useGo, useNavigation, useNotification, useRouterType } from "@hooks";
8
8
  import { useAuthBindingsContext, useLegacyAuthContext } from "@contexts/auth";
9
9
  import { OpenNotificationParams, TLogoutData } from "../../../interfaces";
10
10
  import { AuthActionResponse } from "src/interfaces/bindings/auth";
11
- import { useInvalidateAuthStore } from "../useInvaliteAuthStore";
11
+ import { useInvalidateAuthStore } from "../useInvalidateAuthStore";
12
12
 
13
13
  type Variables = {
14
14
  redirectPath?: string | false;
@@ -112,7 +112,7 @@ export function useLogout<TVariables = {}>({
112
112
  (TVariables & Variables) | void,
113
113
  unknown
114
114
  >(["useLogout"], logoutFromContext, {
115
- onSuccess: (data, variables) => {
115
+ onSuccess: async (data, variables) => {
116
116
  const { success, error, redirectTo } = data;
117
117
  const { redirectPath } = variables ?? {};
118
118
 
@@ -126,6 +126,8 @@ export function useLogout<TVariables = {}>({
126
126
  open?.(buildNotification(error));
127
127
  }
128
128
 
129
+ await invalidateAuthStore();
130
+
129
131
  if (redirect !== false) {
130
132
  if (routerType === "legacy") {
131
133
  push(redirect ?? "/login");
@@ -135,8 +137,6 @@ export function useLogout<TVariables = {}>({
135
137
  }
136
138
  }
137
139
  }
138
-
139
- invalidateAuthStore();
140
140
  },
141
141
  onError: (error: any) => {
142
142
  open?.(buildNotification(error));
@@ -153,9 +153,11 @@ export function useLogout<TVariables = {}>({
153
153
  ["useLogout", "v3LegacyAuthProviderCompatible"],
154
154
  legacyLogoutFromContext,
155
155
  {
156
- onSuccess: (data, variables) => {
156
+ onSuccess: async (data, variables) => {
157
157
  const redirectPath = variables?.redirectPath ?? data;
158
158
 
159
+ await invalidateAuthStore();
160
+
159
161
  if (redirectPath === false) {
160
162
  return;
161
163
  }
@@ -174,8 +176,6 @@ export function useLogout<TVariables = {}>({
174
176
  } else {
175
177
  go({ to: "/login" });
176
178
  }
177
-
178
- invalidateAuthStore();
179
179
  },
180
180
  onError: (error: any) => {
181
181
  open?.(buildNotification(error));
@@ -13,7 +13,7 @@ import {
13
13
  TLoginData,
14
14
  TRegisterData,
15
15
  } from "../../../interfaces";
16
- import { useInvalidateAuthStore } from "../useInvaliteAuthStore";
16
+ import { useInvalidateAuthStore } from "../useInvalidateAuthStore";
17
17
 
18
18
  export type UseRegisterLegacyProps<TVariables> = {
19
19
  v3LegacyAuthProviderCompatible: true;
@@ -106,7 +106,7 @@ export function useRegister<TVariables = {}>({
106
106
  TVariables,
107
107
  unknown
108
108
  >(["useRegister"], registerFromContext, {
109
- onSuccess: ({ success, redirectTo, error }) => {
109
+ onSuccess: async ({ success, redirectTo, error }) => {
110
110
  if (success) {
111
111
  close?.("register-error");
112
112
  }
@@ -115,6 +115,8 @@ export function useRegister<TVariables = {}>({
115
115
  open?.(buildNotification(error));
116
116
  }
117
117
 
118
+ await invalidateAuthStore();
119
+
118
120
  if (redirectTo) {
119
121
  if (routerType === "legacy") {
120
122
  replace(redirectTo);
@@ -126,8 +128,6 @@ export function useRegister<TVariables = {}>({
126
128
  replace("/");
127
129
  }
128
130
  }
129
-
130
- invalidateAuthStore();
131
131
  },
132
132
  onError: (error: any) => {
133
133
  open?.(buildNotification(error));
@@ -144,7 +144,9 @@ export function useRegister<TVariables = {}>({
144
144
  ["useRegister", "v3LegacyAuthProviderCompatible"],
145
145
  legacyRegisterFromContext,
146
146
  {
147
- onSuccess: (redirectPathFromAuth) => {
147
+ onSuccess: async (redirectPathFromAuth) => {
148
+ await invalidateAuthStore();
149
+
148
150
  if (redirectPathFromAuth !== false) {
149
151
  if (redirectPathFromAuth) {
150
152
  if (routerType === "legacy") {
@@ -161,8 +163,6 @@ export function useRegister<TVariables = {}>({
161
163
  }
162
164
  close?.("register-error");
163
165
  }
164
-
165
- invalidateAuthStore();
166
166
  },
167
167
  onError: (error: any) => {
168
168
  open?.(buildNotification(error));
@@ -1,2 +0,0 @@
1
- export declare const useInvalidateAuthStore: () => () => void;
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/auth/useInvaliteAuthStore/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,kBAUlC,CAAC"}
@@ -1,13 +0,0 @@
1
- import { useQueryClient } from "@tanstack/react-query";
2
-
3
- export const useInvalidateAuthStore = () => {
4
- const queryClient = useQueryClient();
5
-
6
- const invalidate = () => {
7
- queryClient.invalidateQueries(["useAuthenticated"]);
8
- queryClient.invalidateQueries(["getUserIdentity"]);
9
- queryClient.invalidateQueries(["usePermissions"]);
10
- };
11
-
12
- return invalidate;
13
- };