@nocios/crudify-ui 3.0.44 → 3.0.46

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/dist/index.d.mts CHANGED
@@ -290,6 +290,10 @@ declare class SessionManager {
290
290
  * Configurar interceptor de respuesta para manejo automático de errores
291
291
  */
292
292
  setupResponseInterceptor(): void;
293
+ /**
294
+ * Detectar errores de autorización en todos los formatos posibles
295
+ */
296
+ private detectAuthorizationError;
293
297
  /**
294
298
  * Limpiar sesión completamente
295
299
  */
package/dist/index.d.ts CHANGED
@@ -290,6 +290,10 @@ declare class SessionManager {
290
290
  * Configurar interceptor de respuesta para manejo automático de errores
291
291
  */
292
292
  setupResponseInterceptor(): void;
293
+ /**
294
+ * Detectar errores de autorización en todos los formatos posibles
295
+ */
296
+ private detectAuthorizationError;
293
297
  /**
294
298
  * Limpiar sesión completamente
295
299
  */
package/dist/index.js CHANGED
@@ -487,7 +487,7 @@ var useLoginState = () => {
487
487
  };
488
488
 
489
489
  // src/providers/SessionProvider.tsx
490
- var import_react7 = require("react");
490
+ var import_react7 = __toESM(require("react"));
491
491
 
492
492
  // src/hooks/useSession.ts
493
493
  var import_react5 = require("react");
@@ -842,53 +842,103 @@ var SessionManager = class _SessionManager {
842
842
  */
843
843
  setupResponseInterceptor() {
844
844
  import_crudify_browser2.default.setResponseInterceptor(async (response) => {
845
- if (response.errors) {
846
- this.log("Response interceptor - received response with errors:", response);
847
- }
848
- if (response.errors) {
849
- let hasAuthError = false;
850
- if (Array.isArray(response.errors)) {
851
- hasAuthError = response.errors.some(
852
- (error) => error.message?.includes("Unauthorized") || error.message?.includes("Token") || error.extensions?.code === "UNAUTHENTICATED" || error.message?.includes("NOT_AUTHORIZED")
853
- );
854
- } else if (typeof response.errors === "object") {
855
- const errorMessages = Object.values(response.errors).flat();
856
- hasAuthError = errorMessages.some(
857
- (message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
858
- );
859
- }
860
- if (!hasAuthError && response.errorCode) {
861
- const errorCode = response.errorCode;
862
- hasAuthError = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
845
+ const authError = this.detectAuthorizationError(response);
846
+ if (authError.isAuthError) {
847
+ console.warn("\u{1F6A8} SessionManager - Authorization error detected:", {
848
+ errorType: authError.errorType,
849
+ errorDetails: authError.errorDetails,
850
+ fullResponse: response
851
+ });
852
+ if (authError.isRefreshTokenInvalid || authError.isTokenRefreshFailed) {
853
+ this.log("Refresh token invalid or refresh already failed, clearing session");
854
+ TokenStorage.clearTokens();
855
+ this.config.onSessionExpired?.();
856
+ return response;
863
857
  }
864
- if (hasAuthError) {
865
- this.log("Auth error detected in response interceptor");
866
- const isRefreshTokenFailed = response.errors && typeof response.errors === "object" && Object.values(response.errors).flat().some(
867
- (message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
868
- );
869
- if (isRefreshTokenFailed) {
870
- this.log("Refresh token failed, clearing tokens and triggering session expired");
871
- TokenStorage.clearTokens();
872
- this.config.onSessionExpired?.();
873
- } else if (TokenStorage.hasValidTokens()) {
874
- this.log("Auth error detected, attempting token refresh...");
875
- const refreshSuccess = await this.refreshTokens();
876
- if (!refreshSuccess) {
877
- this.log("Session expired, triggering callback");
878
- this.config.onSessionExpired?.();
879
- }
880
- } else {
881
- this.log("Auth error but no valid tokens, triggering session expired");
858
+ if (TokenStorage.hasValidTokens() && !authError.isIrrecoverable) {
859
+ this.log("Auth error detected, attempting token refresh...");
860
+ const refreshSuccess = await this.refreshTokens();
861
+ if (!refreshSuccess) {
862
+ this.log("Token refresh failed, triggering session expired");
882
863
  this.config.onSessionExpired?.();
883
864
  }
884
865
  } else {
885
- this.log("No auth error detected in response");
866
+ this.log("Auth error with no valid tokens or irrecoverable error, triggering session expired");
867
+ TokenStorage.clearTokens();
868
+ this.config.onSessionExpired?.();
886
869
  }
887
870
  }
888
871
  return response;
889
872
  });
890
873
  this.log("Response interceptor configured");
891
874
  }
875
+ /**
876
+ * Detectar errores de autorización en todos los formatos posibles
877
+ */
878
+ detectAuthorizationError(response) {
879
+ const result = {
880
+ isAuthError: false,
881
+ isRefreshTokenInvalid: false,
882
+ isTokenRefreshFailed: false,
883
+ isIrrecoverable: false,
884
+ errorType: "",
885
+ errorDetails: null
886
+ };
887
+ if (response.errors) {
888
+ if (Array.isArray(response.errors)) {
889
+ const hasAuthError = response.errors.some(
890
+ (error) => error.message?.includes("Unauthorized") || error.message?.includes("Token") || error.extensions?.code === "UNAUTHENTICATED" || error.message?.includes("NOT_AUTHORIZED")
891
+ );
892
+ if (hasAuthError) {
893
+ result.isAuthError = true;
894
+ result.errorType = "GraphQL Array Format";
895
+ result.errorDetails = response.errors;
896
+ }
897
+ } else if (typeof response.errors === "object") {
898
+ const errorMessages = Object.values(response.errors).flat();
899
+ const hasAuthError = errorMessages.some(
900
+ (message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
901
+ );
902
+ if (hasAuthError) {
903
+ result.isAuthError = true;
904
+ result.errorType = "GraphQL Object Format";
905
+ result.errorDetails = response.errors;
906
+ result.isTokenRefreshFailed = errorMessages.some(
907
+ (message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
908
+ );
909
+ }
910
+ }
911
+ }
912
+ if (!result.isAuthError && response.data?.response?.status === "UNAUTHORIZED") {
913
+ result.isAuthError = true;
914
+ result.errorType = "Status UNAUTHORIZED";
915
+ result.errorDetails = response.data.response;
916
+ result.isIrrecoverable = true;
917
+ }
918
+ if (!result.isAuthError && response.data?.response?.data) {
919
+ try {
920
+ const parsedData = JSON.parse(response.data.response.data);
921
+ if (parsedData.error === "REFRESH_TOKEN_INVALID" || parsedData.error === "TOKEN_EXPIRED") {
922
+ result.isAuthError = true;
923
+ result.errorType = "Parsed Data Format";
924
+ result.errorDetails = parsedData;
925
+ result.isRefreshTokenInvalid = true;
926
+ result.isIrrecoverable = true;
927
+ }
928
+ } catch {
929
+ }
930
+ }
931
+ if (!result.isAuthError && response.errorCode) {
932
+ const errorCode = response.errorCode;
933
+ const isAuthErrorCode = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
934
+ if (isAuthErrorCode) {
935
+ result.isAuthError = true;
936
+ result.errorType = "Error Code Format";
937
+ result.errorDetails = { errorCode };
938
+ }
939
+ }
940
+ return result;
941
+ }
892
942
  /**
893
943
  * Limpiar sesión completamente
894
944
  */
@@ -1314,7 +1364,14 @@ function SessionProvider({
1314
1364
  // ✅ Por defecto DESACTIVADO
1315
1365
  notificationOptions = {}
1316
1366
  }) {
1317
- const sessionHook = useSession(options);
1367
+ const enhancedOptions = import_react7.default.useMemo(() => ({
1368
+ ...options,
1369
+ onSessionExpired: () => {
1370
+ console.log("\u{1F6A8} SessionProvider - Session expired callback triggered");
1371
+ options.onSessionExpired?.();
1372
+ }
1373
+ }), [options]);
1374
+ const sessionHook = useSession(enhancedOptions);
1318
1375
  const resolvedConfig = (0, import_react7.useMemo)(() => {
1319
1376
  let publicApiKey;
1320
1377
  let env;
package/dist/index.mjs CHANGED
@@ -414,7 +414,7 @@ var useLoginState = () => {
414
414
  };
415
415
 
416
416
  // src/providers/SessionProvider.tsx
417
- import { createContext as createContext5, useContext as useContext5, useMemo as useMemo2 } from "react";
417
+ import React5, { createContext as createContext5, useContext as useContext5, useMemo as useMemo2 } from "react";
418
418
 
419
419
  // src/hooks/useSession.ts
420
420
  import { useState as useState3, useEffect as useEffect4, useCallback } from "react";
@@ -769,53 +769,103 @@ var SessionManager = class _SessionManager {
769
769
  */
770
770
  setupResponseInterceptor() {
771
771
  crudify2.setResponseInterceptor(async (response) => {
772
- if (response.errors) {
773
- this.log("Response interceptor - received response with errors:", response);
774
- }
775
- if (response.errors) {
776
- let hasAuthError = false;
777
- if (Array.isArray(response.errors)) {
778
- hasAuthError = response.errors.some(
779
- (error) => error.message?.includes("Unauthorized") || error.message?.includes("Token") || error.extensions?.code === "UNAUTHENTICATED" || error.message?.includes("NOT_AUTHORIZED")
780
- );
781
- } else if (typeof response.errors === "object") {
782
- const errorMessages = Object.values(response.errors).flat();
783
- hasAuthError = errorMessages.some(
784
- (message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
785
- );
786
- }
787
- if (!hasAuthError && response.errorCode) {
788
- const errorCode = response.errorCode;
789
- hasAuthError = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
772
+ const authError = this.detectAuthorizationError(response);
773
+ if (authError.isAuthError) {
774
+ console.warn("\u{1F6A8} SessionManager - Authorization error detected:", {
775
+ errorType: authError.errorType,
776
+ errorDetails: authError.errorDetails,
777
+ fullResponse: response
778
+ });
779
+ if (authError.isRefreshTokenInvalid || authError.isTokenRefreshFailed) {
780
+ this.log("Refresh token invalid or refresh already failed, clearing session");
781
+ TokenStorage.clearTokens();
782
+ this.config.onSessionExpired?.();
783
+ return response;
790
784
  }
791
- if (hasAuthError) {
792
- this.log("Auth error detected in response interceptor");
793
- const isRefreshTokenFailed = response.errors && typeof response.errors === "object" && Object.values(response.errors).flat().some(
794
- (message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
795
- );
796
- if (isRefreshTokenFailed) {
797
- this.log("Refresh token failed, clearing tokens and triggering session expired");
798
- TokenStorage.clearTokens();
799
- this.config.onSessionExpired?.();
800
- } else if (TokenStorage.hasValidTokens()) {
801
- this.log("Auth error detected, attempting token refresh...");
802
- const refreshSuccess = await this.refreshTokens();
803
- if (!refreshSuccess) {
804
- this.log("Session expired, triggering callback");
805
- this.config.onSessionExpired?.();
806
- }
807
- } else {
808
- this.log("Auth error but no valid tokens, triggering session expired");
785
+ if (TokenStorage.hasValidTokens() && !authError.isIrrecoverable) {
786
+ this.log("Auth error detected, attempting token refresh...");
787
+ const refreshSuccess = await this.refreshTokens();
788
+ if (!refreshSuccess) {
789
+ this.log("Token refresh failed, triggering session expired");
809
790
  this.config.onSessionExpired?.();
810
791
  }
811
792
  } else {
812
- this.log("No auth error detected in response");
793
+ this.log("Auth error with no valid tokens or irrecoverable error, triggering session expired");
794
+ TokenStorage.clearTokens();
795
+ this.config.onSessionExpired?.();
813
796
  }
814
797
  }
815
798
  return response;
816
799
  });
817
800
  this.log("Response interceptor configured");
818
801
  }
802
+ /**
803
+ * Detectar errores de autorización en todos los formatos posibles
804
+ */
805
+ detectAuthorizationError(response) {
806
+ const result = {
807
+ isAuthError: false,
808
+ isRefreshTokenInvalid: false,
809
+ isTokenRefreshFailed: false,
810
+ isIrrecoverable: false,
811
+ errorType: "",
812
+ errorDetails: null
813
+ };
814
+ if (response.errors) {
815
+ if (Array.isArray(response.errors)) {
816
+ const hasAuthError = response.errors.some(
817
+ (error) => error.message?.includes("Unauthorized") || error.message?.includes("Token") || error.extensions?.code === "UNAUTHENTICATED" || error.message?.includes("NOT_AUTHORIZED")
818
+ );
819
+ if (hasAuthError) {
820
+ result.isAuthError = true;
821
+ result.errorType = "GraphQL Array Format";
822
+ result.errorDetails = response.errors;
823
+ }
824
+ } else if (typeof response.errors === "object") {
825
+ const errorMessages = Object.values(response.errors).flat();
826
+ const hasAuthError = errorMessages.some(
827
+ (message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
828
+ );
829
+ if (hasAuthError) {
830
+ result.isAuthError = true;
831
+ result.errorType = "GraphQL Object Format";
832
+ result.errorDetails = response.errors;
833
+ result.isTokenRefreshFailed = errorMessages.some(
834
+ (message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
835
+ );
836
+ }
837
+ }
838
+ }
839
+ if (!result.isAuthError && response.data?.response?.status === "UNAUTHORIZED") {
840
+ result.isAuthError = true;
841
+ result.errorType = "Status UNAUTHORIZED";
842
+ result.errorDetails = response.data.response;
843
+ result.isIrrecoverable = true;
844
+ }
845
+ if (!result.isAuthError && response.data?.response?.data) {
846
+ try {
847
+ const parsedData = JSON.parse(response.data.response.data);
848
+ if (parsedData.error === "REFRESH_TOKEN_INVALID" || parsedData.error === "TOKEN_EXPIRED") {
849
+ result.isAuthError = true;
850
+ result.errorType = "Parsed Data Format";
851
+ result.errorDetails = parsedData;
852
+ result.isRefreshTokenInvalid = true;
853
+ result.isIrrecoverable = true;
854
+ }
855
+ } catch {
856
+ }
857
+ }
858
+ if (!result.isAuthError && response.errorCode) {
859
+ const errorCode = response.errorCode;
860
+ const isAuthErrorCode = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
861
+ if (isAuthErrorCode) {
862
+ result.isAuthError = true;
863
+ result.errorType = "Error Code Format";
864
+ result.errorDetails = { errorCode };
865
+ }
866
+ }
867
+ return result;
868
+ }
819
869
  /**
820
870
  * Limpiar sesión completamente
821
871
  */
@@ -1241,7 +1291,14 @@ function SessionProvider({
1241
1291
  // ✅ Por defecto DESACTIVADO
1242
1292
  notificationOptions = {}
1243
1293
  }) {
1244
- const sessionHook = useSession(options);
1294
+ const enhancedOptions = React5.useMemo(() => ({
1295
+ ...options,
1296
+ onSessionExpired: () => {
1297
+ console.log("\u{1F6A8} SessionProvider - Session expired callback triggered");
1298
+ options.onSessionExpired?.();
1299
+ }
1300
+ }), [options]);
1301
+ const sessionHook = useSession(enhancedOptions);
1245
1302
  const resolvedConfig = useMemo2(() => {
1246
1303
  let publicApiKey;
1247
1304
  let env;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocios/crudify-ui",
3
- "version": "3.0.44",
3
+ "version": "3.0.46",
4
4
  "description": "Biblioteca de componentes UI para Crudify",
5
5
  "author": "Nocios",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  "@mui/icons-material": "^7.1.0",
26
26
  "@mui/material": "^7.1.0",
27
27
  "@mui/x-data-grid": "^8.5.1",
28
- "@nocios/crudify-browser": "^2.0.2",
28
+ "@nocios/crudify-browser": "^2.0.4",
29
29
  "@types/uuid": "^10.0.0",
30
30
  "crypto-js": "^4.2.0",
31
31
  "i18next-browser-languagedetector": "^8.1.0",