analytica-frontend-lib 1.1.23 → 1.1.25

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.
@@ -16,6 +16,9 @@
16
16
  * @property {string} endpoint - API endpoint to fetch session data
17
17
  * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function
18
18
  * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing
19
+ * @property {number} [maxRetries] - Maximum number of retry attempts (default: 3)
20
+ * @property {number} [retryDelay] - Base delay between retries in milliseconds (default: 1000)
21
+ * @property {(error: unknown) => void} [onError] - Error handler callback
19
22
  */
20
23
  interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown> {
21
24
  setTokens: (tokens: Tokens) => void;
@@ -32,6 +35,9 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
32
35
  refreshToken: string;
33
36
  };
34
37
  clearParamsFromURL?: () => void;
38
+ maxRetries?: number;
39
+ retryDelay?: number;
40
+ onError?: (error: unknown) => void;
35
41
  }
36
42
  /**
37
43
  * Hook for handling URL-based authentication
@@ -16,6 +16,9 @@
16
16
  * @property {string} endpoint - API endpoint to fetch session data
17
17
  * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function
18
18
  * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing
19
+ * @property {number} [maxRetries] - Maximum number of retry attempts (default: 3)
20
+ * @property {number} [retryDelay] - Base delay between retries in milliseconds (default: 1000)
21
+ * @property {(error: unknown) => void} [onError] - Error handler callback
19
22
  */
20
23
  interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown> {
21
24
  setTokens: (tokens: Tokens) => void;
@@ -32,6 +35,9 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
32
35
  refreshToken: string;
33
36
  };
34
37
  clearParamsFromURL?: () => void;
38
+ maxRetries?: number;
39
+ retryDelay?: number;
40
+ onError?: (error: unknown) => void;
35
41
  }
36
42
  /**
37
43
  * Hook for handling URL-based authentication
@@ -71,28 +71,58 @@ var handleUserData = (responseData, setUser) => {
71
71
  };
72
72
  function useUrlAuthentication(options) {
73
73
  const location = (0, import_react_router_dom.useLocation)();
74
+ const processedRef = (0, import_react.useRef)(false);
74
75
  (0, import_react.useEffect)(() => {
75
76
  const handleAuthentication = async () => {
77
+ if (processedRef.current) {
78
+ return;
79
+ }
76
80
  const authParams = getAuthParams(location, options.extractParams);
77
81
  if (!hasValidAuthParams(authParams)) {
78
82
  return;
79
83
  }
84
+ processedRef.current = true;
80
85
  try {
81
86
  options.setTokens({
82
87
  token: authParams.token,
83
88
  refreshToken: authParams.refreshToken
84
89
  });
85
- const response = await options.api.get(options.endpoint, {
86
- headers: {
87
- Authorization: `Bearer ${authParams.token}`
90
+ const maxRetries = options.maxRetries || 3;
91
+ const retryDelay = options.retryDelay || 1e3;
92
+ let retries = 0;
93
+ let sessionData = null;
94
+ while (retries < maxRetries && !sessionData) {
95
+ try {
96
+ const response = await options.api.get(options.endpoint, {
97
+ headers: {
98
+ Authorization: `Bearer ${authParams.token}`
99
+ }
100
+ });
101
+ sessionData = response.data.data;
102
+ break;
103
+ } catch (error) {
104
+ retries++;
105
+ console.warn(
106
+ `Tentativa ${retries}/${maxRetries} falhou para ${options.endpoint}:`,
107
+ error
108
+ );
109
+ if (retries < maxRetries) {
110
+ await new Promise(
111
+ (resolve) => setTimeout(resolve, retryDelay * retries)
112
+ );
113
+ } else {
114
+ throw error;
115
+ }
88
116
  }
89
- });
90
- options.setSessionInfo(response.data.data);
91
- handleProfileSelection(response.data.data, options.setSelectedProfile);
92
- handleUserData(response.data.data, options.setUser);
117
+ }
118
+ options.setSessionInfo(sessionData);
119
+ handleProfileSelection(sessionData, options.setSelectedProfile);
120
+ handleUserData(sessionData, options.setUser);
93
121
  options.clearParamsFromURL?.();
94
122
  } catch (error) {
95
123
  console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
124
+ processedRef.current = false;
125
+ options.onError?.(error);
96
126
  }
97
127
  };
98
128
  handleAuthentication();
@@ -105,7 +135,10 @@ function useUrlAuthentication(options) {
105
135
  options.api,
106
136
  options.endpoint,
107
137
  options.extractParams,
108
- options.clearParamsFromURL
138
+ options.clearParamsFromURL,
139
+ options.maxRetries,
140
+ options.retryDelay,
141
+ options.onError
109
142
  ]);
110
143
  }
111
144
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n handleUserData(response.data.data, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAC1B,8BAA4B;AAmD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,eAAW,qCAAY;AAE7B,8BAAU,MAAM;AAOd,UAAM,uBAAuB,YAAY;AACvC,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAEhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAEX,cAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,UACxD,SAAS;AAAA,YACP,eAAe,UAAU,WAAW,KAAK;AAAA,UAC3C;AAAA,QACF,CAAC;AAED,gBAAQ,eAAe,SAAS,KAAK,IAAe;AACpD,+BAAuB,SAAS,KAAK,MAAM,QAAQ,kBAAkB;AACrE,uBAAe,SAAS,KAAK,MAAM,QAAQ,OAAO;AAClD,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAAA,MAC7D;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n * @property {number} [maxRetries] - Maximum number of retry attempts (default: 3)\n * @property {number} [retryDelay] - Base delay between retries in milliseconds (default: 1000)\n * @property {(error: unknown) => void} [onError] - Error handler callback\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n maxRetries?: number;\n retryDelay?: number;\n onError?: (error: unknown) => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n const processedRef = useRef(false);\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @private\n */\n const handleAuthentication = async (): Promise<void> => {\n // Check if we already processed this request\n if (processedRef.current) {\n return;\n }\n\n const authParams = getAuthParams(location, options.extractParams);\n\n // Only proceed if we have all required auth parameters\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n // Mark as processed to prevent multiple calls\n processedRef.current = true;\n\n try {\n // Set tokens first\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n // Call session-info with proper error handling and retry\n const maxRetries = options.maxRetries || 3;\n const retryDelay = options.retryDelay || 1000;\n let retries = 0;\n let sessionData = null;\n\n while (retries < maxRetries && !sessionData) {\n try {\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n sessionData = response.data.data;\n break;\n } catch (error) {\n retries++;\n console.warn(\n `Tentativa ${retries}/${maxRetries} falhou para ${options.endpoint}:`,\n error\n );\n\n if (retries < maxRetries) {\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, retryDelay * retries)\n );\n } else {\n throw error;\n }\n }\n }\n\n // Always call setSessionInfo with the received data (even if null)\n options.setSessionInfo(sessionData as Session);\n handleProfileSelection(sessionData, options.setSelectedProfile);\n handleUserData(sessionData, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n // Reset processed flag on error to allow retry\n processedRef.current = false;\n // Call error handler if provided\n options.onError?.(error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n options.maxRetries,\n options.retryDelay,\n options.onError,\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,8BAA4B;AAyD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,eAAW,qCAAY;AAC7B,QAAM,mBAAe,qBAAO,KAAK;AAEjC,8BAAU,MAAM;AAMd,UAAM,uBAAuB,YAA2B;AAEtD,UAAI,aAAa,SAAS;AACxB;AAAA,MACF;AAEA,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAGhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAGA,mBAAa,UAAU;AAEvB,UAAI;AAEF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAGX,cAAM,aAAa,QAAQ,cAAc;AACzC,cAAM,aAAa,QAAQ,cAAc;AACzC,YAAI,UAAU;AACd,YAAI,cAAc;AAElB,eAAO,UAAU,cAAc,CAAC,aAAa;AAC3C,cAAI;AACF,kBAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,cACxD,SAAS;AAAA,gBACP,eAAe,UAAU,WAAW,KAAK;AAAA,cAC3C;AAAA,YACF,CAAC;AAED,0BAAc,SAAS,KAAK;AAC5B;AAAA,UACF,SAAS,OAAO;AACd;AACA,oBAAQ;AAAA,cACN,aAAa,OAAO,IAAI,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,cAClE;AAAA,YACF;AAEA,gBAAI,UAAU,YAAY;AAExB,oBAAM,IAAI;AAAA,gBAAQ,CAAC,YACjB,WAAW,SAAS,aAAa,OAAO;AAAA,cAC1C;AAAA,YACF,OAAO;AACL,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAGA,gBAAQ,eAAe,WAAsB;AAC7C,+BAAuB,aAAa,QAAQ,kBAAkB;AAC9D,uBAAe,aAAa,QAAQ,OAAO;AAC3C,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAE3D,qBAAa,UAAU;AAEvB,gBAAQ,UAAU,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
@@ -1,5 +1,5 @@
1
1
  // src/components/Auth/useUrlAuthentication.ts
2
- import { useEffect } from "react";
2
+ import { useEffect, useRef } from "react";
3
3
  import { useLocation } from "react-router-dom";
4
4
  var getAuthParams = (location, extractParams) => {
5
5
  const searchParams = new URLSearchParams(location.search);
@@ -47,28 +47,58 @@ var handleUserData = (responseData, setUser) => {
47
47
  };
48
48
  function useUrlAuthentication(options) {
49
49
  const location = useLocation();
50
+ const processedRef = useRef(false);
50
51
  useEffect(() => {
51
52
  const handleAuthentication = async () => {
53
+ if (processedRef.current) {
54
+ return;
55
+ }
52
56
  const authParams = getAuthParams(location, options.extractParams);
53
57
  if (!hasValidAuthParams(authParams)) {
54
58
  return;
55
59
  }
60
+ processedRef.current = true;
56
61
  try {
57
62
  options.setTokens({
58
63
  token: authParams.token,
59
64
  refreshToken: authParams.refreshToken
60
65
  });
61
- const response = await options.api.get(options.endpoint, {
62
- headers: {
63
- Authorization: `Bearer ${authParams.token}`
66
+ const maxRetries = options.maxRetries || 3;
67
+ const retryDelay = options.retryDelay || 1e3;
68
+ let retries = 0;
69
+ let sessionData = null;
70
+ while (retries < maxRetries && !sessionData) {
71
+ try {
72
+ const response = await options.api.get(options.endpoint, {
73
+ headers: {
74
+ Authorization: `Bearer ${authParams.token}`
75
+ }
76
+ });
77
+ sessionData = response.data.data;
78
+ break;
79
+ } catch (error) {
80
+ retries++;
81
+ console.warn(
82
+ `Tentativa ${retries}/${maxRetries} falhou para ${options.endpoint}:`,
83
+ error
84
+ );
85
+ if (retries < maxRetries) {
86
+ await new Promise(
87
+ (resolve) => setTimeout(resolve, retryDelay * retries)
88
+ );
89
+ } else {
90
+ throw error;
91
+ }
64
92
  }
65
- });
66
- options.setSessionInfo(response.data.data);
67
- handleProfileSelection(response.data.data, options.setSelectedProfile);
68
- handleUserData(response.data.data, options.setUser);
93
+ }
94
+ options.setSessionInfo(sessionData);
95
+ handleProfileSelection(sessionData, options.setSelectedProfile);
96
+ handleUserData(sessionData, options.setUser);
69
97
  options.clearParamsFromURL?.();
70
98
  } catch (error) {
71
99
  console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
100
+ processedRef.current = false;
101
+ options.onError?.(error);
72
102
  }
73
103
  };
74
104
  handleAuthentication();
@@ -81,7 +111,10 @@ function useUrlAuthentication(options) {
81
111
  options.api,
82
112
  options.endpoint,
83
113
  options.extractParams,
84
- options.clearParamsFromURL
114
+ options.clearParamsFromURL,
115
+ options.maxRetries,
116
+ options.retryDelay,
117
+ options.onError
85
118
  ]);
86
119
  }
87
120
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n handleUserData(response.data.data, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAmD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,WAAW,YAAY;AAE7B,YAAU,MAAM;AAOd,UAAM,uBAAuB,YAAY;AACvC,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAEhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAEX,cAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,UACxD,SAAS;AAAA,YACP,eAAe,UAAU,WAAW,KAAK;AAAA,UAC3C;AAAA,QACF,CAAC;AAED,gBAAQ,eAAe,SAAS,KAAK,IAAe;AACpD,+BAAuB,SAAS,KAAK,MAAM,QAAQ,kBAAkB;AACrE,uBAAe,SAAS,KAAK,MAAM,QAAQ,OAAO;AAClD,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAAA,MAC7D;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n * @property {number} [maxRetries] - Maximum number of retry attempts (default: 3)\n * @property {number} [retryDelay] - Base delay between retries in milliseconds (default: 1000)\n * @property {(error: unknown) => void} [onError] - Error handler callback\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n maxRetries?: number;\n retryDelay?: number;\n onError?: (error: unknown) => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n const processedRef = useRef(false);\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @private\n */\n const handleAuthentication = async (): Promise<void> => {\n // Check if we already processed this request\n if (processedRef.current) {\n return;\n }\n\n const authParams = getAuthParams(location, options.extractParams);\n\n // Only proceed if we have all required auth parameters\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n // Mark as processed to prevent multiple calls\n processedRef.current = true;\n\n try {\n // Set tokens first\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n // Call session-info with proper error handling and retry\n const maxRetries = options.maxRetries || 3;\n const retryDelay = options.retryDelay || 1000;\n let retries = 0;\n let sessionData = null;\n\n while (retries < maxRetries && !sessionData) {\n try {\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n sessionData = response.data.data;\n break;\n } catch (error) {\n retries++;\n console.warn(\n `Tentativa ${retries}/${maxRetries} falhou para ${options.endpoint}:`,\n error\n );\n\n if (retries < maxRetries) {\n // Wait before retry (exponential backoff)\n await new Promise((resolve) =>\n setTimeout(resolve, retryDelay * retries)\n );\n } else {\n throw error;\n }\n }\n }\n\n // Always call setSessionInfo with the received data (even if null)\n options.setSessionInfo(sessionData as Session);\n handleProfileSelection(sessionData, options.setSelectedProfile);\n handleUserData(sessionData, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n // Reset processed flag on error to allow retry\n processedRef.current = false;\n // Call error handler if provided\n options.onError?.(error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n options.maxRetries,\n options.retryDelay,\n options.onError,\n ]);\n}\n"],"mappings":";AAAA,SAAS,WAAW,cAAc;AAClC,SAAS,mBAAmB;AAyD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,WAAW,YAAY;AAC7B,QAAM,eAAe,OAAO,KAAK;AAEjC,YAAU,MAAM;AAMd,UAAM,uBAAuB,YAA2B;AAEtD,UAAI,aAAa,SAAS;AACxB;AAAA,MACF;AAEA,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAGhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAGA,mBAAa,UAAU;AAEvB,UAAI;AAEF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAGX,cAAM,aAAa,QAAQ,cAAc;AACzC,cAAM,aAAa,QAAQ,cAAc;AACzC,YAAI,UAAU;AACd,YAAI,cAAc;AAElB,eAAO,UAAU,cAAc,CAAC,aAAa;AAC3C,cAAI;AACF,kBAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,cACxD,SAAS;AAAA,gBACP,eAAe,UAAU,WAAW,KAAK;AAAA,cAC3C;AAAA,YACF,CAAC;AAED,0BAAc,SAAS,KAAK;AAC5B;AAAA,UACF,SAAS,OAAO;AACd;AACA,oBAAQ;AAAA,cACN,aAAa,OAAO,IAAI,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,cAClE;AAAA,YACF;AAEA,gBAAI,UAAU,YAAY;AAExB,oBAAM,IAAI;AAAA,gBAAQ,CAAC,YACjB,WAAW,SAAS,aAAa,OAAO;AAAA,cAC1C;AAAA,YACF,OAAO;AACL,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAGA,gBAAQ,eAAe,WAAsB;AAC7C,+BAAuB,aAAa,QAAQ,kBAAkB;AAC9D,uBAAe,aAAa,QAAQ,OAAO;AAC3C,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAE3D,qBAAa,UAAU;AAEvB,gBAAQ,UAAU,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
69
69
  className?: string;
70
70
  /** Label CSS classes */
71
71
  labelClassName?: string;
72
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
72
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
73
73
 
74
74
  export { type CheckBoxProps, CheckBox as default };
@@ -5510,7 +5510,7 @@ var QuizFooter = (0, import_react12.forwardRef)(
5510
5510
  const [modalResultOpen, setModalResultOpen] = (0, import_react12.useState)(false);
5511
5511
  const [modalNavigateOpen, setModalNavigateOpen] = (0, import_react12.useState)(false);
5512
5512
  const [modalResolutionOpen, setModalResolutionOpen] = (0, import_react12.useState)(false);
5513
- const [filterType, setFilterType] = (0, import_react12.useState)(void 0);
5513
+ const [filterType, setFilterType] = (0, import_react12.useState)("all");
5514
5514
  const unansweredQuestions = getUnansweredQuestionsFromUserAnswers();
5515
5515
  const allQuestions = getTotalQuestions();
5516
5516
  const handleFinishQuiz = async () => {