@nocios/crudify-ui 3.0.42 → 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 +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +118 -43
- package/dist/index.mjs +118 -43
- package/package.json +2 -2
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
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
);
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
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 (
|
|
865
|
-
this.log("Auth error detected
|
|
866
|
-
const
|
|
867
|
-
|
|
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("
|
|
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
|
|
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;
|
|
@@ -1852,6 +1909,9 @@ function translateErrorCode(errorCode, config) {
|
|
|
1852
1909
|
}
|
|
1853
1910
|
for (const key of translationKeys) {
|
|
1854
1911
|
const translated = translateFn(key);
|
|
1912
|
+
if (enableDebug) {
|
|
1913
|
+
console.log(`\u{1F50D} [ErrorTranslation] Checking key: "${key}" -> result: "${translated}" (same as key: ${translated === key})`);
|
|
1914
|
+
}
|
|
1855
1915
|
if (translated && translated !== key) {
|
|
1856
1916
|
if (enableDebug) {
|
|
1857
1917
|
console.log(`\u2705 [ErrorTranslation] Found translation at key: ${key} = "${translated}"`);
|
|
@@ -1880,13 +1940,25 @@ function translateError(error, config) {
|
|
|
1880
1940
|
if (enableDebug) {
|
|
1881
1941
|
console.log(`\u{1F50D} [ErrorTranslation] Translating error:`, error);
|
|
1882
1942
|
}
|
|
1883
|
-
|
|
1943
|
+
const translatedCode = translateErrorCode(error.code, config);
|
|
1944
|
+
if (translatedCode !== error.code.toUpperCase() && translatedCode !== error.code) {
|
|
1884
1945
|
if (enableDebug) {
|
|
1885
|
-
console.log(`\u2705 [ErrorTranslation] Using
|
|
1946
|
+
console.log(`\u2705 [ErrorTranslation] Using hierarchical translation: "${translatedCode}"`);
|
|
1947
|
+
}
|
|
1948
|
+
if (error.field) {
|
|
1949
|
+
return `${error.field}: ${translatedCode}`;
|
|
1950
|
+
}
|
|
1951
|
+
return translatedCode;
|
|
1952
|
+
}
|
|
1953
|
+
if (error.message && !error.message.includes("Error:") && error.message.length > 0 && error.message !== error.code) {
|
|
1954
|
+
if (enableDebug) {
|
|
1955
|
+
console.log(`\u{1F504} [ErrorTranslation] No hierarchical translation found, using API message: "${error.message}"`);
|
|
1886
1956
|
}
|
|
1887
1957
|
return error.message;
|
|
1888
1958
|
}
|
|
1889
|
-
|
|
1959
|
+
if (enableDebug) {
|
|
1960
|
+
console.log(`\u26A0\uFE0F [ErrorTranslation] Using final fallback: "${translatedCode}"`);
|
|
1961
|
+
}
|
|
1890
1962
|
if (error.field) {
|
|
1891
1963
|
return `${error.field}: ${translatedCode}`;
|
|
1892
1964
|
}
|
|
@@ -1949,11 +2021,14 @@ var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError,
|
|
|
1949
2021
|
return () => clearTimeout(timer);
|
|
1950
2022
|
}, []);
|
|
1951
2023
|
const translateError2 = (parsedError) => {
|
|
1952
|
-
|
|
2024
|
+
console.log("\u{1F50D} [LoginForm] Translating parsed error:", parsedError);
|
|
2025
|
+
const result = errorTranslator.translateError({
|
|
1953
2026
|
code: parsedError.code,
|
|
1954
2027
|
message: parsedError.message,
|
|
1955
2028
|
field: parsedError.field
|
|
1956
2029
|
});
|
|
2030
|
+
console.log("\u{1F50D} [LoginForm] Translation result:", result);
|
|
2031
|
+
return result;
|
|
1957
2032
|
};
|
|
1958
2033
|
const handleLogin = async () => {
|
|
1959
2034
|
if (state.loading) return;
|
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
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
);
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
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 (
|
|
792
|
-
this.log("Auth error detected
|
|
793
|
-
const
|
|
794
|
-
|
|
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("
|
|
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
|
|
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;
|
|
@@ -1779,6 +1836,9 @@ function translateErrorCode(errorCode, config) {
|
|
|
1779
1836
|
}
|
|
1780
1837
|
for (const key of translationKeys) {
|
|
1781
1838
|
const translated = translateFn(key);
|
|
1839
|
+
if (enableDebug) {
|
|
1840
|
+
console.log(`\u{1F50D} [ErrorTranslation] Checking key: "${key}" -> result: "${translated}" (same as key: ${translated === key})`);
|
|
1841
|
+
}
|
|
1782
1842
|
if (translated && translated !== key) {
|
|
1783
1843
|
if (enableDebug) {
|
|
1784
1844
|
console.log(`\u2705 [ErrorTranslation] Found translation at key: ${key} = "${translated}"`);
|
|
@@ -1807,13 +1867,25 @@ function translateError(error, config) {
|
|
|
1807
1867
|
if (enableDebug) {
|
|
1808
1868
|
console.log(`\u{1F50D} [ErrorTranslation] Translating error:`, error);
|
|
1809
1869
|
}
|
|
1810
|
-
|
|
1870
|
+
const translatedCode = translateErrorCode(error.code, config);
|
|
1871
|
+
if (translatedCode !== error.code.toUpperCase() && translatedCode !== error.code) {
|
|
1811
1872
|
if (enableDebug) {
|
|
1812
|
-
console.log(`\u2705 [ErrorTranslation] Using
|
|
1873
|
+
console.log(`\u2705 [ErrorTranslation] Using hierarchical translation: "${translatedCode}"`);
|
|
1874
|
+
}
|
|
1875
|
+
if (error.field) {
|
|
1876
|
+
return `${error.field}: ${translatedCode}`;
|
|
1877
|
+
}
|
|
1878
|
+
return translatedCode;
|
|
1879
|
+
}
|
|
1880
|
+
if (error.message && !error.message.includes("Error:") && error.message.length > 0 && error.message !== error.code) {
|
|
1881
|
+
if (enableDebug) {
|
|
1882
|
+
console.log(`\u{1F504} [ErrorTranslation] No hierarchical translation found, using API message: "${error.message}"`);
|
|
1813
1883
|
}
|
|
1814
1884
|
return error.message;
|
|
1815
1885
|
}
|
|
1816
|
-
|
|
1886
|
+
if (enableDebug) {
|
|
1887
|
+
console.log(`\u26A0\uFE0F [ErrorTranslation] Using final fallback: "${translatedCode}"`);
|
|
1888
|
+
}
|
|
1817
1889
|
if (error.field) {
|
|
1818
1890
|
return `${error.field}: ${translatedCode}`;
|
|
1819
1891
|
}
|
|
@@ -1876,11 +1948,14 @@ var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError,
|
|
|
1876
1948
|
return () => clearTimeout(timer);
|
|
1877
1949
|
}, []);
|
|
1878
1950
|
const translateError2 = (parsedError) => {
|
|
1879
|
-
|
|
1951
|
+
console.log("\u{1F50D} [LoginForm] Translating parsed error:", parsedError);
|
|
1952
|
+
const result = errorTranslator.translateError({
|
|
1880
1953
|
code: parsedError.code,
|
|
1881
1954
|
message: parsedError.message,
|
|
1882
1955
|
field: parsedError.field
|
|
1883
1956
|
});
|
|
1957
|
+
console.log("\u{1F50D} [LoginForm] Translation result:", result);
|
|
1958
|
+
return result;
|
|
1884
1959
|
};
|
|
1885
1960
|
const handleLogin = async () => {
|
|
1886
1961
|
if (state.loading) return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocios/crudify-ui",
|
|
3
|
-
"version": "3.0.
|
|
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.
|
|
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",
|