@nocios/crudify-ui 4.0.98 → 4.1.1

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.
@@ -1 +1 @@
1
- import{a as T,b as L,e as M,f as R,g as k}from"./chunk-6WYDSIJ6.mjs";import{c as l,d as I,e as N}from"./chunk-IO4RPCSZ.mjs";import"./chunk-BJ6PIVZR.mjs";import"./chunk-5JKS55SE.mjs";import{useEffect as B,useState as c}from"react";import{jsx as r,jsxs as n}from"react/jsx-runtime";function G({showBelowMinutes:d=5,position:f="bottom-right",colorNormal:m="#ed6c02",colorCritical:x="#d32f2f",style:g,className:u}={}){let{isAuthenticated:o,tokens:t}=l(),[i,h]=c(0),[y,S]=c(100);if(B(()=>{if(!o||!t)return;let P=setInterval(()=>{let C=Date.now(),p=t.expiresAt-C,w=900*1e3;h(Math.max(0,p)),S(Math.max(0,p/w*100))},1e3);return()=>clearInterval(P)},[o,t]),!o||i<=0)return null;let e=Math.floor(i/6e4),b=Math.floor(i%6e4/1e3);if(e>=d)return null;let s=e<2,a=s?x:m,v={"top-left":{top:"16px",left:"16px"},"top-right":{top:"16px",right:"16px"},"bottom-left":{bottom:"16px",left:"16px"},"bottom-right":{bottom:"16px",right:"16px"}}[f];return n("div",{className:u,style:{position:"fixed",...v,padding:"12px 16px",backgroundColor:"white",borderRadius:"8px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.15)",minWidth:"200px",zIndex:9999,fontFamily:"system-ui, -apple-system, sans-serif",...g},children:[n("div",{style:{marginBottom:"8px"},children:[r("div",{style:{fontSize:"12px",fontWeight:600,color:a,marginBottom:"4px"},children:s?"\u26A0\uFE0F Sesi\xF3n expirando":"\u23F0 Sesi\xF3n por expirar"}),n("div",{style:{fontSize:"14px",color:"#333",fontWeight:500},children:[e,":",b.toString().padStart(2,"0")]})]}),r("div",{style:{width:"100%",height:"6px",backgroundColor:"#e0e0e0",borderRadius:"3px",overflow:"hidden"},children:r("div",{style:{width:`${y}%`,height:"100%",backgroundColor:a,transition:"width 1s linear"}})})]})}export{T as CrudifyLogin,I as GlobalNotificationProvider,R as LoginComponent,M as Policies,k as SessionStatus,G as SessionTimeIndicator,L as UserProfileDisplay,N as useGlobalNotification};
1
+ import{a as T,b as L,e as M,f as R,g as k}from"./chunk-ZA2SJDMK.mjs";import{c as l,d as I,e as N}from"./chunk-CTDQEJAU.mjs";import"./chunk-BJ6PIVZR.mjs";import"./chunk-5JKS55SE.mjs";import{useEffect as B,useState as c}from"react";import{jsx as r,jsxs as n}from"react/jsx-runtime";function G({showBelowMinutes:d=5,position:f="bottom-right",colorNormal:m="#ed6c02",colorCritical:x="#d32f2f",style:g,className:u}={}){let{isAuthenticated:o,tokens:t}=l(),[i,h]=c(0),[y,S]=c(100);if(B(()=>{if(!o||!t)return;let P=setInterval(()=>{let C=Date.now(),p=t.expiresAt-C,w=900*1e3;h(Math.max(0,p)),S(Math.max(0,p/w*100))},1e3);return()=>clearInterval(P)},[o,t]),!o||i<=0)return null;let e=Math.floor(i/6e4),b=Math.floor(i%6e4/1e3);if(e>=d)return null;let s=e<2,a=s?x:m,v={"top-left":{top:"16px",left:"16px"},"top-right":{top:"16px",right:"16px"},"bottom-left":{bottom:"16px",left:"16px"},"bottom-right":{bottom:"16px",right:"16px"}}[f];return n("div",{className:u,style:{position:"fixed",...v,padding:"12px 16px",backgroundColor:"white",borderRadius:"8px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.15)",minWidth:"200px",zIndex:9999,fontFamily:"system-ui, -apple-system, sans-serif",...g},children:[n("div",{style:{marginBottom:"8px"},children:[r("div",{style:{fontSize:"12px",fontWeight:600,color:a,marginBottom:"4px"},children:s?"\u26A0\uFE0F Sesi\xF3n expirando":"\u23F0 Sesi\xF3n por expirar"}),n("div",{style:{fontSize:"14px",color:"#333",fontWeight:500},children:[e,":",b.toString().padStart(2,"0")]})]}),r("div",{style:{width:"100%",height:"6px",backgroundColor:"#e0e0e0",borderRadius:"3px",overflow:"hidden"},children:r("div",{style:{width:`${y}%`,height:"100%",backgroundColor:a,transition:"width 1s linear"}})})]})}export{T as CrudifyLogin,I as GlobalNotificationProvider,R as LoginComponent,M as Policies,k as SessionStatus,G as SessionTimeIndicator,L as UserProfileDisplay,N as useGlobalNotification};
@@ -121,4 +121,4 @@ declare function createErrorTranslator(translateFn: (key: string) => string, opt
121
121
  translateApiError: (apiResponse: any) => string;
122
122
  };
123
123
 
124
- export { ERROR_CODES as E, type ParsedError as P, getCookie as a, secureLocalStorage as b, parseTransactionError as c, decodeJwtSafely as d, parseJavaScriptError as e, getErrorMessage as f, getCurrentUserEmail as g, handleCrudifyError as h, isTokenExpired as i, ERROR_SEVERITY_MAP as j, type ErrorCode as k, type ErrorSeverity as l, translateErrorCodes as m, translateError as n, createErrorTranslator as o, parseApiError as p, type ErrorTranslationConfig as q, secureSessionStorage as s, translateErrorCode as t };
124
+ export { ERROR_CODES as E, type ParsedError as P, getCookie as a, secureLocalStorage as b, parseTransactionError as c, decodeJwtSafely as d, parseJavaScriptError as e, getErrorMessage as f, getCurrentUserEmail as g, handleCrudifyError as h, isTokenExpired as i, ERROR_SEVERITY_MAP as j, translateErrorCodes as k, translateError as l, createErrorTranslator as m, type ErrorCode as n, type ErrorSeverity as o, parseApiError as p, type ErrorTranslationConfig as q, secureSessionStorage as s, translateErrorCode as t };
@@ -121,4 +121,4 @@ declare function createErrorTranslator(translateFn: (key: string) => string, opt
121
121
  translateApiError: (apiResponse: any) => string;
122
122
  };
123
123
 
124
- export { ERROR_CODES as E, type ParsedError as P, getCookie as a, secureLocalStorage as b, parseTransactionError as c, decodeJwtSafely as d, parseJavaScriptError as e, getErrorMessage as f, getCurrentUserEmail as g, handleCrudifyError as h, isTokenExpired as i, ERROR_SEVERITY_MAP as j, type ErrorCode as k, type ErrorSeverity as l, translateErrorCodes as m, translateError as n, createErrorTranslator as o, parseApiError as p, type ErrorTranslationConfig as q, secureSessionStorage as s, translateErrorCode as t };
124
+ export { ERROR_CODES as E, type ParsedError as P, getCookie as a, secureLocalStorage as b, parseTransactionError as c, decodeJwtSafely as d, parseJavaScriptError as e, getErrorMessage as f, getCurrentUserEmail as g, handleCrudifyError as h, isTokenExpired as i, ERROR_SEVERITY_MAP as j, translateErrorCodes as k, translateError as l, createErrorTranslator as m, type ErrorCode as n, type ErrorSeverity as o, parseApiError as p, type ErrorTranslationConfig as q, secureSessionStorage as s, translateErrorCode as t };
package/dist/hooks.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunk5AQJTODWjs = require('./chunk-5AQJTODW.js');var _chunkVQUXX5W3js = require('./chunk-VQUXX5W3.js');require('./chunk-AT74WV5W.js');exports.useAuth = _chunk5AQJTODWjs.b; exports.useCrudifyWithNotifications = _chunk5AQJTODWjs.d; exports.useData = _chunk5AQJTODWjs.c; exports.useSession = _chunkVQUXX5W3js.c; exports.useUserData = _chunk5AQJTODWjs.a; exports.useUserProfile = _chunkVQUXX5W3js.j;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkX3HSMDZ7js = require('./chunk-X3HSMDZ7.js');var _chunkTLGRXZCSjs = require('./chunk-TLGRXZCS.js');require('./chunk-AT74WV5W.js');exports.useAuth = _chunkX3HSMDZ7js.b; exports.useCrudifyWithNotifications = _chunkX3HSMDZ7js.d; exports.useData = _chunkX3HSMDZ7js.c; exports.useSession = _chunkTLGRXZCSjs.c; exports.useUserData = _chunkX3HSMDZ7js.a; exports.useUserProfile = _chunkTLGRXZCSjs.i;
package/dist/hooks.mjs CHANGED
@@ -1 +1 @@
1
- import{a as s,b as r,c as o,d as a}from"./chunk-O52COIJA.mjs";import{c as e,j as t}from"./chunk-IO4RPCSZ.mjs";import"./chunk-5JKS55SE.mjs";export{r as useAuth,a as useCrudifyWithNotifications,o as useData,e as useSession,s as useUserData,t as useUserProfile};
1
+ import{a as s,b as r,c as o,d as a}from"./chunk-KNEHDX2M.mjs";import{c as e,i as t}from"./chunk-CTDQEJAU.mjs";import"./chunk-5JKS55SE.mjs";export{r as useAuth,a as useCrudifyWithNotifications,o as useData,e as useSession,s as useUserData,t as useUserProfile};
package/dist/index.d.mts CHANGED
@@ -1,12 +1,12 @@
1
1
  export * from '@nocios/crudify-browser';
2
2
  export { default as crudify } from '@nocios/crudify-browser';
3
- export { B as BoxScreenType, C as CrudifyLogin, d as CrudifyLoginConfig, e as CrudifyLoginProps, f as CrudifyLoginTranslations, L as LoginComponent, a as POLICY_ACTIONS, b as PREFERRED_POLICY_ORDER, P as Policies, c as PolicyAction, S as SessionStatus, g as UserLoginData, U as UserProfileDisplay } from './LoginComponent-saSn0o5x.mjs';
3
+ export { B as BoxScreenType, C as CrudifyLogin, a as CrudifyLoginConfig, b as CrudifyLoginProps, c as CrudifyLoginTranslations, L as LoginComponent, f as POLICY_ACTIONS, g as PREFERRED_POLICY_ORDER, P as Policies, e as PolicyAction, S as SessionStatus, d as UserLoginData, U as UserProfileDisplay } from './LoginComponent-CSTVsfeV.mjs';
4
4
  export { A as ApiError, C as CrudifyApiResponse, a as CrudifyTransactionResponse, F as ForgotPasswordRequest, J as JwtPayload, b as LoginRequest, L as LoginResponse, R as ResetPasswordRequest, T as TransactionResponseData, U as UserProfile, V as ValidateCodeRequest, c as ValidationError } from './api-Djqihi4n.mjs';
5
5
  import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-BwF68SOh.mjs';
6
6
  export { a as SessionConfig, S as SessionManager, d as SessionState, c as StorageType, b as TokenStorage, j as UseAuthReturn, l as UseDataReturn, g as UseUserDataOptions, f as UseUserDataReturn, h as UserData, i as useAuth, n as useCrudifyWithNotifications, k as useData, u as useSession, e as useUserData, m as useUserProfile } from './index-BwF68SOh.mjs';
7
7
  import * as react_jsx_runtime from 'react/jsx-runtime';
8
8
  import { ReactNode } from 'react';
9
- export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, k as ErrorCode, l as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, o as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, n as translateError, t as translateErrorCode, m as translateErrorCodes } from './errorTranslation-DqdgLEUy.mjs';
9
+ export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, n as ErrorCode, o as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, m as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, l as translateError, t as translateErrorCode, k as translateErrorCodes } from './errorTranslation-DEn4aqs6.mjs';
10
10
  export { G as GlobalNotificationProvider, a as GlobalNotificationProviderProps, N as Notification, b as NotificationSeverity, u as useGlobalNotification } from './GlobalNotificationProvider-C3iWgM1z.mjs';
11
11
 
12
12
  type SessionData = {
@@ -65,17 +65,132 @@ declare function SessionProvider(props: SessionProviderProps): react_jsx_runtime
65
65
  */
66
66
  declare function useSessionContext(): SessionContextType;
67
67
  /**
68
- * HOC para proteger rutas que requieren autenticación
68
+ * Componente para mostrar información de la sesión (debug)
69
69
  */
70
- type ProtectedRouteProps = {
70
+ declare function SessionDebugInfo(): react_jsx_runtime.JSX.Element;
71
+
72
+ interface ProtectedRouteProps {
71
73
  children: ReactNode;
72
- fallback?: ReactNode;
73
- redirectTo?: () => void;
74
- };
75
- declare function ProtectedRoute({ children, fallback, redirectTo }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
74
+ /**
75
+ * Componente a mostrar mientras se valida la sesión
76
+ * @default <SessionLoadingScreen stage="validating-session" />
77
+ */
78
+ loadingComponent?: ReactNode;
79
+ /**
80
+ * Ruta a la que redirigir si no está autenticado
81
+ * @default "/login"
82
+ */
83
+ loginPath?: string;
84
+ }
76
85
  /**
77
- * Componente para mostrar información de la sesión (debug)
86
+ * Componente para proteger rutas que requieren autenticación
87
+ *
88
+ * Características:
89
+ * - Valida sesión de forma estricta (isAuthenticated + tokens válidos)
90
+ * - Guarda URL actual para redirect post-login
91
+ * - Previene open redirect attacks
92
+ * - Limpia storage corrupto automáticamente
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * <Route
97
+ * path="/dashboard"
98
+ * element={
99
+ * <ProtectedRoute>
100
+ * <Dashboard />
101
+ * </ProtectedRoute>
102
+ * }
103
+ * />
104
+ * ```
78
105
  */
79
- declare function SessionDebugInfo(): react_jsx_runtime.JSX.Element;
106
+ declare function ProtectedRoute({ children, loadingComponent, loginPath, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element;
107
+
108
+ interface AuthRouteProps {
109
+ children: ReactNode;
110
+ /**
111
+ * Ruta a la que redirigir si ya está autenticado
112
+ * Si hay parámetro ?redirect= en la URL, se usará ese en su lugar
113
+ * @default "/"
114
+ */
115
+ redirectTo?: string;
116
+ }
117
+ /**
118
+ * Componente para proteger rutas de autenticación (login, register, etc.)
119
+ * Redirige a home si el usuario ya está autenticado
120
+ *
121
+ * Características:
122
+ * - Si usuario autenticado → redirige a home (o ?redirect= si existe)
123
+ * - Si no autenticado → muestra el componente (login, etc.)
124
+ * - Valida parámetro redirect para prevenir open redirect
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * <Route
129
+ * path="/login"
130
+ * element={
131
+ * <AuthRoute>
132
+ * <LoginPage />
133
+ * </AuthRoute>
134
+ * }
135
+ * />
136
+ * ```
137
+ */
138
+ declare function AuthRoute({ children, redirectTo }: AuthRouteProps): react_jsx_runtime.JSX.Element;
139
+
140
+ interface SessionLoadingScreenProps {
141
+ /**
142
+ * Stage of loading to display appropriate message
143
+ * @default "loading"
144
+ */
145
+ stage?: "initializing" | "validating-session" | "loading";
146
+ /**
147
+ * Custom message to display (overrides default stage message)
148
+ */
149
+ message?: string;
150
+ }
151
+ /**
152
+ * Loading screen component for session-related loading states
153
+ *
154
+ * Features:
155
+ * - Clean, minimal design
156
+ * - Customizable message
157
+ * - Stage-based default messages
158
+ * - No external dependencies (works without i18n)
159
+ *
160
+ * @example
161
+ * ```tsx
162
+ * // Basic usage
163
+ * <SessionLoadingScreen stage="validating-session" />
164
+ *
165
+ * // With custom message
166
+ * <SessionLoadingScreen
167
+ * stage="validating-session"
168
+ * message={t("loading.validatingSession")}
169
+ * />
170
+ * ```
171
+ */
172
+ declare function SessionLoadingScreen({ stage, message, }: SessionLoadingScreenProps): react_jsx_runtime.JSX.Element;
173
+
174
+ /**
175
+ * Utilidades de seguridad para validar redirecciones
176
+ * Previene ataques de open redirect permitiendo rutas dinámicas
177
+ */
178
+ /**
179
+ * Valida que una ruta de redirección sea segura (solo rutas internas)
180
+ * Permite rutas dinámicas pero bloquea ataques de open redirect
181
+ *
182
+ * @param path - La ruta a validar
183
+ * @param defaultPath - Ruta por defecto si la validación falla
184
+ * @returns Ruta validada y segura
185
+ */
186
+ declare const validateInternalRedirect: (path: string, defaultPath?: string) => string;
187
+ /**
188
+ * Extrae y valida parámetro redirect de URL search params
189
+ *
190
+ * @param searchParams - URLSearchParams o string de query params
191
+ * @param defaultPath - Ruta por defecto
192
+ * @returns Ruta validada
193
+ */
194
+ declare const extractSafeRedirectFromUrl: (searchParams: URLSearchParams | string, defaultPath?: string) => string;
80
195
 
81
- export { LoginResult, type NotificationOptions, ProtectedRoute, type ProtectedRouteProps, SessionDebugInfo, SessionProvider, type SessionProviderProps, TokenData, UseSessionOptions, useSessionContext };
196
+ export { AuthRoute, type AuthRouteProps, LoginResult, type NotificationOptions, ProtectedRoute, type ProtectedRouteProps, SessionDebugInfo, SessionLoadingScreen, type SessionLoadingScreenProps, SessionProvider, type SessionProviderProps, TokenData, UseSessionOptions, extractSafeRedirectFromUrl, useSessionContext, validateInternalRedirect };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  export * from '@nocios/crudify-browser';
2
2
  export { default as crudify } from '@nocios/crudify-browser';
3
- export { B as BoxScreenType, C as CrudifyLogin, d as CrudifyLoginConfig, e as CrudifyLoginProps, f as CrudifyLoginTranslations, L as LoginComponent, a as POLICY_ACTIONS, b as PREFERRED_POLICY_ORDER, P as Policies, c as PolicyAction, S as SessionStatus, g as UserLoginData, U as UserProfileDisplay } from './LoginComponent-saSn0o5x.js';
3
+ export { B as BoxScreenType, C as CrudifyLogin, a as CrudifyLoginConfig, b as CrudifyLoginProps, c as CrudifyLoginTranslations, L as LoginComponent, f as POLICY_ACTIONS, g as PREFERRED_POLICY_ORDER, P as Policies, e as PolicyAction, S as SessionStatus, d as UserLoginData, U as UserProfileDisplay } from './LoginComponent-CSTVsfeV.js';
4
4
  export { A as ApiError, C as CrudifyApiResponse, a as CrudifyTransactionResponse, F as ForgotPasswordRequest, J as JwtPayload, b as LoginRequest, L as LoginResponse, R as ResetPasswordRequest, T as TransactionResponseData, U as UserProfile, V as ValidateCodeRequest, c as ValidationError } from './api-Djqihi4n.js';
5
5
  import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-Fkm9ErmY.js';
6
6
  export { a as SessionConfig, S as SessionManager, d as SessionState, c as StorageType, b as TokenStorage, j as UseAuthReturn, l as UseDataReturn, g as UseUserDataOptions, f as UseUserDataReturn, h as UserData, i as useAuth, n as useCrudifyWithNotifications, k as useData, u as useSession, e as useUserData, m as useUserProfile } from './index-Fkm9ErmY.js';
7
7
  import * as react_jsx_runtime from 'react/jsx-runtime';
8
8
  import { ReactNode } from 'react';
9
- export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, k as ErrorCode, l as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, o as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, n as translateError, t as translateErrorCode, m as translateErrorCodes } from './errorTranslation-CBbQYNWR.js';
9
+ export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, n as ErrorCode, o as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, m as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, l as translateError, t as translateErrorCode, k as translateErrorCodes } from './errorTranslation-DdqZg8JD.js';
10
10
  export { G as GlobalNotificationProvider, a as GlobalNotificationProviderProps, N as Notification, b as NotificationSeverity, u as useGlobalNotification } from './GlobalNotificationProvider-C3iWgM1z.js';
11
11
 
12
12
  type SessionData = {
@@ -65,17 +65,132 @@ declare function SessionProvider(props: SessionProviderProps): react_jsx_runtime
65
65
  */
66
66
  declare function useSessionContext(): SessionContextType;
67
67
  /**
68
- * HOC para proteger rutas que requieren autenticación
68
+ * Componente para mostrar información de la sesión (debug)
69
69
  */
70
- type ProtectedRouteProps = {
70
+ declare function SessionDebugInfo(): react_jsx_runtime.JSX.Element;
71
+
72
+ interface ProtectedRouteProps {
71
73
  children: ReactNode;
72
- fallback?: ReactNode;
73
- redirectTo?: () => void;
74
- };
75
- declare function ProtectedRoute({ children, fallback, redirectTo }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
74
+ /**
75
+ * Componente a mostrar mientras se valida la sesión
76
+ * @default <SessionLoadingScreen stage="validating-session" />
77
+ */
78
+ loadingComponent?: ReactNode;
79
+ /**
80
+ * Ruta a la que redirigir si no está autenticado
81
+ * @default "/login"
82
+ */
83
+ loginPath?: string;
84
+ }
76
85
  /**
77
- * Componente para mostrar información de la sesión (debug)
86
+ * Componente para proteger rutas que requieren autenticación
87
+ *
88
+ * Características:
89
+ * - Valida sesión de forma estricta (isAuthenticated + tokens válidos)
90
+ * - Guarda URL actual para redirect post-login
91
+ * - Previene open redirect attacks
92
+ * - Limpia storage corrupto automáticamente
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * <Route
97
+ * path="/dashboard"
98
+ * element={
99
+ * <ProtectedRoute>
100
+ * <Dashboard />
101
+ * </ProtectedRoute>
102
+ * }
103
+ * />
104
+ * ```
78
105
  */
79
- declare function SessionDebugInfo(): react_jsx_runtime.JSX.Element;
106
+ declare function ProtectedRoute({ children, loadingComponent, loginPath, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element;
107
+
108
+ interface AuthRouteProps {
109
+ children: ReactNode;
110
+ /**
111
+ * Ruta a la que redirigir si ya está autenticado
112
+ * Si hay parámetro ?redirect= en la URL, se usará ese en su lugar
113
+ * @default "/"
114
+ */
115
+ redirectTo?: string;
116
+ }
117
+ /**
118
+ * Componente para proteger rutas de autenticación (login, register, etc.)
119
+ * Redirige a home si el usuario ya está autenticado
120
+ *
121
+ * Características:
122
+ * - Si usuario autenticado → redirige a home (o ?redirect= si existe)
123
+ * - Si no autenticado → muestra el componente (login, etc.)
124
+ * - Valida parámetro redirect para prevenir open redirect
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * <Route
129
+ * path="/login"
130
+ * element={
131
+ * <AuthRoute>
132
+ * <LoginPage />
133
+ * </AuthRoute>
134
+ * }
135
+ * />
136
+ * ```
137
+ */
138
+ declare function AuthRoute({ children, redirectTo }: AuthRouteProps): react_jsx_runtime.JSX.Element;
139
+
140
+ interface SessionLoadingScreenProps {
141
+ /**
142
+ * Stage of loading to display appropriate message
143
+ * @default "loading"
144
+ */
145
+ stage?: "initializing" | "validating-session" | "loading";
146
+ /**
147
+ * Custom message to display (overrides default stage message)
148
+ */
149
+ message?: string;
150
+ }
151
+ /**
152
+ * Loading screen component for session-related loading states
153
+ *
154
+ * Features:
155
+ * - Clean, minimal design
156
+ * - Customizable message
157
+ * - Stage-based default messages
158
+ * - No external dependencies (works without i18n)
159
+ *
160
+ * @example
161
+ * ```tsx
162
+ * // Basic usage
163
+ * <SessionLoadingScreen stage="validating-session" />
164
+ *
165
+ * // With custom message
166
+ * <SessionLoadingScreen
167
+ * stage="validating-session"
168
+ * message={t("loading.validatingSession")}
169
+ * />
170
+ * ```
171
+ */
172
+ declare function SessionLoadingScreen({ stage, message, }: SessionLoadingScreenProps): react_jsx_runtime.JSX.Element;
173
+
174
+ /**
175
+ * Utilidades de seguridad para validar redirecciones
176
+ * Previene ataques de open redirect permitiendo rutas dinámicas
177
+ */
178
+ /**
179
+ * Valida que una ruta de redirección sea segura (solo rutas internas)
180
+ * Permite rutas dinámicas pero bloquea ataques de open redirect
181
+ *
182
+ * @param path - La ruta a validar
183
+ * @param defaultPath - Ruta por defecto si la validación falla
184
+ * @returns Ruta validada y segura
185
+ */
186
+ declare const validateInternalRedirect: (path: string, defaultPath?: string) => string;
187
+ /**
188
+ * Extrae y valida parámetro redirect de URL search params
189
+ *
190
+ * @param searchParams - URLSearchParams o string de query params
191
+ * @param defaultPath - Ruta por defecto
192
+ * @returns Ruta validada
193
+ */
194
+ declare const extractSafeRedirectFromUrl: (searchParams: URLSearchParams | string, defaultPath?: string) => string;
80
195
 
81
- export { LoginResult, type NotificationOptions, ProtectedRoute, type ProtectedRouteProps, SessionDebugInfo, SessionProvider, type SessionProviderProps, TokenData, UseSessionOptions, useSessionContext };
196
+ export { AuthRoute, type AuthRouteProps, LoginResult, type NotificationOptions, ProtectedRoute, type ProtectedRouteProps, SessionDebugInfo, SessionLoadingScreen, type SessionLoadingScreenProps, SessionProvider, type SessionProviderProps, TokenData, UseSessionOptions, extractSafeRedirectFromUrl, useSessionContext, validateInternalRedirect };
package/dist/index.js CHANGED
@@ -1 +1,6 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); }var _chunkIJOEEO3Zjs = require('./chunk-IJOEEO3Z.js');var _chunk5AQJTODWjs = require('./chunk-5AQJTODW.js');var _chunkVQUXX5W3js = require('./chunk-VQUXX5W3.js');var _chunkNNY4A73Vjs = require('./chunk-NNY4A73V.js');var _chunkYIIUEOXCjs = require('./chunk-YIIUEOXC.js');var _chunkAT74WV5Wjs = require('./chunk-AT74WV5W.js');var _crudifybrowser = require('@nocios/crudify-browser'); var _crudifybrowser2 = _interopRequireDefault(_crudifybrowser); _createStarExport(_crudifybrowser);exports.CrudifyLogin = _chunkIJOEEO3Zjs.a; exports.ERROR_CODES = _chunkYIIUEOXCjs.a; exports.ERROR_SEVERITY_MAP = _chunkYIIUEOXCjs.b; exports.GlobalNotificationProvider = _chunkVQUXX5W3js.d; exports.LoginComponent = _chunkIJOEEO3Zjs.f; exports.POLICY_ACTIONS = _chunkIJOEEO3Zjs.c; exports.PREFERRED_POLICY_ORDER = _chunkIJOEEO3Zjs.d; exports.Policies = _chunkIJOEEO3Zjs.e; exports.ProtectedRoute = _chunkVQUXX5W3js.h; exports.SessionDebugInfo = _chunkVQUXX5W3js.i; exports.SessionManager = _chunkVQUXX5W3js.b; exports.SessionProvider = _chunkVQUXX5W3js.f; exports.SessionStatus = _chunkIJOEEO3Zjs.g; exports.TokenStorage = _chunkVQUXX5W3js.a; exports.UserProfileDisplay = _chunkIJOEEO3Zjs.b; exports.createErrorTranslator = _chunkAT74WV5Wjs.e; exports.crudify = _crudifybrowser2.default; exports.decodeJwtSafely = _chunkAT74WV5Wjs.h; exports.getCookie = _chunkAT74WV5Wjs.a; exports.getCurrentUserEmail = _chunkAT74WV5Wjs.i; exports.getErrorMessage = _chunkYIIUEOXCjs.e; exports.handleCrudifyError = _chunkYIIUEOXCjs.g; exports.isTokenExpired = _chunkAT74WV5Wjs.j; exports.parseApiError = _chunkYIIUEOXCjs.c; exports.parseJavaScriptError = _chunkYIIUEOXCjs.f; exports.parseTransactionError = _chunkYIIUEOXCjs.d; exports.secureLocalStorage = _chunkNNY4A73Vjs.b; exports.secureSessionStorage = _chunkNNY4A73Vjs.a; exports.translateError = _chunkAT74WV5Wjs.d; exports.translateErrorCode = _chunkAT74WV5Wjs.b; exports.translateErrorCodes = _chunkAT74WV5Wjs.c; exports.useAuth = _chunk5AQJTODWjs.b; exports.useCrudifyWithNotifications = _chunk5AQJTODWjs.d; exports.useData = _chunk5AQJTODWjs.c; exports.useGlobalNotification = _chunkVQUXX5W3js.e; exports.useSession = _chunkVQUXX5W3js.c; exports.useSessionContext = _chunkVQUXX5W3js.g; exports.useUserData = _chunk5AQJTODWjs.a; exports.useUserProfile = _chunkVQUXX5W3js.j;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkYQF2FVCXjs = require('./chunk-YQF2FVCX.js');var _chunkX3HSMDZ7js = require('./chunk-X3HSMDZ7.js');var _chunkTLGRXZCSjs = require('./chunk-TLGRXZCS.js');var _chunkNNY4A73Vjs = require('./chunk-NNY4A73V.js');var _chunkYIIUEOXCjs = require('./chunk-YIIUEOXC.js');var _chunkAT74WV5Wjs = require('./chunk-AT74WV5W.js');var _crudifybrowser = require('@nocios/crudify-browser'); var _crudifybrowser2 = _interopRequireDefault(_crudifybrowser); _createStarExport(_crudifybrowser);var _reactrouterdom = require('react-router-dom');var _jsxruntime = require('react/jsx-runtime');var ne={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},ae=()=>_jsxruntime.jsx.call(void 0, "style",{children:`
2
+ @keyframes spin {
3
+ 0% { transform: rotate(0deg); }
4
+ 100% { transform: rotate(360deg); }
5
+ }
6
+ `});function d({stage:e="loading",message:o}){let t=o||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, ae,{}),_jsxruntime.jsxs.call(void 0, "div",{style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100vh",width:"100vw",backgroundColor:"#f0f2f5",fontFamily:'"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',color:"#333",textAlign:"center",boxSizing:"border-box",padding:"20px",background:"#fff"},children:[_jsxruntime.jsx.call(void 0, "div",{style:ne}),_jsxruntime.jsx.call(void 0, "p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:t})]})]})}var pe=/^[a-zA-Z0-9\-_./\?=&%#]+$/,fe=[/^https?:\/\//i,/^ftp:\/\//i,/^\/\//,/javascript:/i,/data:/i,/vbscript:/i,/about:/i,/\.\.\//,/\.\.\\/,/%2e%2e%2f/i,/%2e%2e%5c/i,/%2f%2f/i,/%5c%5c/i,/[\x00-\x1f\x7f-\x9f]/,/\\/],p= exports.validateInternalRedirect =(e,o="/")=>{if(!e||typeof e!="string")return o;let r=e.trim();if(!r)return o;if(!r.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),o;if(!pe.test(r))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),o;let t=r.toLowerCase();for(let i of fe)if(i.test(t))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),o;let s=r.split("?")[0].split("/").filter(Boolean);if(s.length===0)return r;for(let i of s)if(i===".."||i.includes(":")||i.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",i),o;return r},l= exports.extractSafeRedirectFromUrl =(e,o="/")=>{try{let t=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!t)return o;let s=decodeURIComponent(t);return p(s,o)}catch(r){return console.warn("\u{1F6A8} Error parsing redirect parameter:",r),o}};function x({children:e,loadingComponent:o,loginPath:r="/login"}){let{isAuthenticated:t,isLoading:s,isInitialized:i,tokens:n,error:y}=_chunkTLGRXZCSjs.g.call(void 0, ),u=_reactrouterdom.useLocation.call(void 0, );if(!i||s)return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:o||_jsxruntime.jsx.call(void 0, d,{stage:"validating-session"})});let P=t&&_optionalChain([n, 'optionalAccess', _2 => _2.accessToken])&&n.accessToken.length>0;if(y||!t||!P){n&&(!n.accessToken||n.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let h=u.pathname+u.search,C=p(h),L=encodeURIComponent(C);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:`${r}?redirect=${L}`,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}function S({children:e,redirectTo:o="/"}){let{isAuthenticated:r}=_chunkTLGRXZCSjs.g.call(void 0, ),t=_reactrouterdom.useLocation.call(void 0, );if(r){let s=new URLSearchParams(t.search),i=l(s,o);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:i,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}exports.AuthRoute = S; exports.CrudifyLogin = _chunkYQF2FVCXjs.a; exports.ERROR_CODES = _chunkYIIUEOXCjs.a; exports.ERROR_SEVERITY_MAP = _chunkYIIUEOXCjs.b; exports.GlobalNotificationProvider = _chunkTLGRXZCSjs.d; exports.LoginComponent = _chunkYQF2FVCXjs.f; exports.POLICY_ACTIONS = _chunkYQF2FVCXjs.c; exports.PREFERRED_POLICY_ORDER = _chunkYQF2FVCXjs.d; exports.Policies = _chunkYQF2FVCXjs.e; exports.ProtectedRoute = x; exports.SessionDebugInfo = _chunkTLGRXZCSjs.h; exports.SessionLoadingScreen = d; exports.SessionManager = _chunkTLGRXZCSjs.b; exports.SessionProvider = _chunkTLGRXZCSjs.f; exports.SessionStatus = _chunkYQF2FVCXjs.g; exports.TokenStorage = _chunkTLGRXZCSjs.a; exports.UserProfileDisplay = _chunkYQF2FVCXjs.b; exports.createErrorTranslator = _chunkAT74WV5Wjs.e; exports.crudify = _crudifybrowser2.default; exports.decodeJwtSafely = _chunkAT74WV5Wjs.h; exports.extractSafeRedirectFromUrl = l; exports.getCookie = _chunkAT74WV5Wjs.a; exports.getCurrentUserEmail = _chunkAT74WV5Wjs.i; exports.getErrorMessage = _chunkYIIUEOXCjs.e; exports.handleCrudifyError = _chunkYIIUEOXCjs.g; exports.isTokenExpired = _chunkAT74WV5Wjs.j; exports.parseApiError = _chunkYIIUEOXCjs.c; exports.parseJavaScriptError = _chunkYIIUEOXCjs.f; exports.parseTransactionError = _chunkYIIUEOXCjs.d; exports.secureLocalStorage = _chunkNNY4A73Vjs.b; exports.secureSessionStorage = _chunkNNY4A73Vjs.a; exports.translateError = _chunkAT74WV5Wjs.d; exports.translateErrorCode = _chunkAT74WV5Wjs.b; exports.translateErrorCodes = _chunkAT74WV5Wjs.c; exports.useAuth = _chunkX3HSMDZ7js.b; exports.useCrudifyWithNotifications = _chunkX3HSMDZ7js.d; exports.useData = _chunkX3HSMDZ7js.c; exports.useGlobalNotification = _chunkTLGRXZCSjs.e; exports.useSession = _chunkTLGRXZCSjs.c; exports.useSessionContext = _chunkTLGRXZCSjs.g; exports.useUserData = _chunkX3HSMDZ7js.a; exports.useUserProfile = _chunkTLGRXZCSjs.i; exports.validateInternalRedirect = p;
package/dist/index.mjs CHANGED
@@ -1 +1,6 @@
1
- import{a as U,b as L,c as v,d as O,e as h,f as k,g as A}from"./chunk-6WYDSIJ6.mjs";import{a as N,b,c as _,d as w}from"./chunk-O52COIJA.mjs";import{a as r,b as a,c as n,d as m,e as l,f as x,g as d,h as y,i as c,j as T}from"./chunk-IO4RPCSZ.mjs";import{a as I,b as q}from"./chunk-T2CPA46I.mjs";import{a as S,b as P,c as R,d as g,e as E,f as C,g as D}from"./chunk-BJ6PIVZR.mjs";import{a as o,b as e,c as t,d as s,e as i,h as p,i as f,j as u}from"./chunk-5JKS55SE.mjs";import{default as J}from"@nocios/crudify-browser";export*from"@nocios/crudify-browser";export{U as CrudifyLogin,S as ERROR_CODES,P as ERROR_SEVERITY_MAP,m as GlobalNotificationProvider,k as LoginComponent,v as POLICY_ACTIONS,O as PREFERRED_POLICY_ORDER,h as Policies,y as ProtectedRoute,c as SessionDebugInfo,a as SessionManager,x as SessionProvider,A as SessionStatus,r as TokenStorage,L as UserProfileDisplay,i as createErrorTranslator,J as crudify,p as decodeJwtSafely,o as getCookie,f as getCurrentUserEmail,E as getErrorMessage,D as handleCrudifyError,u as isTokenExpired,R as parseApiError,C as parseJavaScriptError,g as parseTransactionError,q as secureLocalStorage,I as secureSessionStorage,s as translateError,e as translateErrorCode,t as translateErrorCodes,b as useAuth,w as useCrudifyWithNotifications,_ as useData,l as useGlobalNotification,n as useSession,d as useSessionContext,N as useUserData,T as useUserProfile};
1
+ import{a as J,b as $,c as K,d as Z,e as Q,f as X,g as j}from"./chunk-ZA2SJDMK.mjs";import{a as ee,b as oe,c as re,d as se}from"./chunk-KNEHDX2M.mjs";import{a as E,b as k,c as D,d as I,e as _,f as z,g as a,h as F,i as Y}from"./chunk-CTDQEJAU.mjs";import{a as te,b as ie}from"./chunk-T2CPA46I.mjs";import{a as M,b as G,c as V,d as q,e as H,f as W,g as B}from"./chunk-BJ6PIVZR.mjs";import{a as v,b as A,c as U,d as T,e as b,h as N,i as w,j as O}from"./chunk-5JKS55SE.mjs";import{default as Ie}from"@nocios/crudify-browser";export*from"@nocios/crudify-browser";import{Navigate as de,useLocation as le}from"react-router-dom";import{Fragment as ce,jsx as c,jsxs as m}from"react/jsx-runtime";var ne={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},ae=()=>c("style",{children:`
2
+ @keyframes spin {
3
+ 0% { transform: rotate(0deg); }
4
+ 100% { transform: rotate(360deg); }
5
+ }
6
+ `});function d({stage:e="loading",message:o}){let t=o||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return m(ce,{children:[c(ae,{}),m("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100vh",width:"100vw",backgroundColor:"#f0f2f5",fontFamily:'"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',color:"#333",textAlign:"center",boxSizing:"border-box",padding:"20px",background:"#fff"},children:[c("div",{style:ne}),c("p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:t})]})]})}var pe=/^[a-zA-Z0-9\-_./\?=&%#]+$/,fe=[/^https?:\/\//i,/^ftp:\/\//i,/^\/\//,/javascript:/i,/data:/i,/vbscript:/i,/about:/i,/\.\.\//,/\.\.\\/,/%2e%2e%2f/i,/%2e%2e%5c/i,/%2f%2f/i,/%5c%5c/i,/[\x00-\x1f\x7f-\x9f]/,/\\/],p=(e,o="/")=>{if(!e||typeof e!="string")return o;let r=e.trim();if(!r)return o;if(!r.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),o;if(!pe.test(r))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),o;let t=r.toLowerCase();for(let i of fe)if(i.test(t))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),o;let s=r.split("?")[0].split("/").filter(Boolean);if(s.length===0)return r;for(let i of s)if(i===".."||i.includes(":")||i.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",i),o;return r},l=(e,o="/")=>{try{let t=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!t)return o;let s=decodeURIComponent(t);return p(s,o)}catch(r){return console.warn("\u{1F6A8} Error parsing redirect parameter:",r),o}};import{Fragment as g,jsx as f}from"react/jsx-runtime";function x({children:e,loadingComponent:o,loginPath:r="/login"}){let{isAuthenticated:t,isLoading:s,isInitialized:i,tokens:n,error:y}=a(),u=le();if(!i||s)return f(g,{children:o||f(d,{stage:"validating-session"})});let P=t&&n?.accessToken&&n.accessToken.length>0;if(y||!t||!P){n&&(!n.accessToken||n.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let h=u.pathname+u.search,C=p(h),L=encodeURIComponent(C);return f(de,{to:`${r}?redirect=${L}`,replace:!0})}return f(g,{children:e})}import{Navigate as ue,useLocation as me}from"react-router-dom";import{Fragment as ge,jsx as R}from"react/jsx-runtime";function S({children:e,redirectTo:o="/"}){let{isAuthenticated:r}=a(),t=me();if(r){let s=new URLSearchParams(t.search),i=l(s,o);return R(ue,{to:i,replace:!0})}return R(ge,{children:e})}export{S as AuthRoute,J as CrudifyLogin,M as ERROR_CODES,G as ERROR_SEVERITY_MAP,I as GlobalNotificationProvider,X as LoginComponent,K as POLICY_ACTIONS,Z as PREFERRED_POLICY_ORDER,Q as Policies,x as ProtectedRoute,F as SessionDebugInfo,d as SessionLoadingScreen,k as SessionManager,z as SessionProvider,j as SessionStatus,E as TokenStorage,$ as UserProfileDisplay,b as createErrorTranslator,Ie as crudify,N as decodeJwtSafely,l as extractSafeRedirectFromUrl,v as getCookie,w as getCurrentUserEmail,H as getErrorMessage,B as handleCrudifyError,O as isTokenExpired,V as parseApiError,W as parseJavaScriptError,q as parseTransactionError,ie as secureLocalStorage,te as secureSessionStorage,T as translateError,A as translateErrorCode,U as translateErrorCodes,oe as useAuth,se as useCrudifyWithNotifications,re as useData,_ as useGlobalNotification,D as useSession,a as useSessionContext,ee as useUserData,Y as useUserProfile,p as validateInternalRedirect};
package/dist/utils.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, k as ErrorCode, l as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, o as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, n as translateError, t as translateErrorCode, m as translateErrorCodes } from './errorTranslation-DqdgLEUy.mjs';
1
+ export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, n as ErrorCode, o as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, m as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, l as translateError, t as translateErrorCode, k as translateErrorCodes } from './errorTranslation-DEn4aqs6.mjs';
2
2
  import './api-Djqihi4n.mjs';
3
3
 
4
4
  /**
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, k as ErrorCode, l as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, o as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, n as translateError, t as translateErrorCode, m as translateErrorCodes } from './errorTranslation-CBbQYNWR.js';
1
+ export { E as ERROR_CODES, j as ERROR_SEVERITY_MAP, n as ErrorCode, o as ErrorSeverity, q as ErrorTranslationConfig, P as ParsedError, m as createErrorTranslator, d as decodeJwtSafely, a as getCookie, g as getCurrentUserEmail, f as getErrorMessage, h as handleCrudifyError, i as isTokenExpired, p as parseApiError, e as parseJavaScriptError, c as parseTransactionError, b as secureLocalStorage, s as secureSessionStorage, l as translateError, t as translateErrorCode, k as translateErrorCodes } from './errorTranslation-DdqZg8JD.js';
2
2
  import './api-Djqihi4n.js';
3
3
 
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocios/crudify-ui",
3
- "version": "4.0.98",
3
+ "version": "4.1.01",
4
4
  "description": "Biblioteca de componentes UI para Crudify",
5
5
  "author": "Nocios",
6
6
  "license": "MIT",
@@ -54,9 +54,15 @@
54
54
  "i18next-http-backend": "^3.0.2",
55
55
  "react": "^19.1.0",
56
56
  "react-dom": "^19.1.0",
57
- "react-i18next": "^15.5.2"
57
+ "react-i18next": "^15.5.2",
58
+ "react-router-dom": "^6.0.0 || ^7.0.0"
58
59
  },
59
60
  "devDependencies": {
61
+ "@emotion/react": "^11.14.0",
62
+ "@emotion/styled": "^11.14.1",
63
+ "@mui/icons-material": "^7.3.4",
64
+ "@mui/material": "^7.3.4",
65
+ "@mui/x-data-grid": "^8.13.1",
60
66
  "@testing-library/jest-dom": "^6.1.5",
61
67
  "@testing-library/react": "^16.3.0",
62
68
  "@testing-library/user-event": "^14.5.1",
@@ -65,7 +71,11 @@
65
71
  "@types/react-dom": "^19.0.1",
66
72
  "@vitest/coverage-v8": "^1.1.0",
67
73
  "@vitest/ui": "^1.1.0",
74
+ "i18next-browser-languagedetector": "^8.2.0",
75
+ "i18next-http-backend": "^3.0.2",
68
76
  "jsdom": "^23.0.1",
77
+ "react-i18next": "^16.0.0",
78
+ "react-router-dom": "^7.9.3",
69
79
  "tsup": "^8.4.0",
70
80
  "typescript": "^5.1.3",
71
81
  "vitest": "^1.1.0"