@nocios/crudify-components 2.0.61 → 2.0.88

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.
Files changed (85) hide show
  1. package/README.md +21 -0
  2. package/dist/api-jcCTCqPD.d.mts +61 -0
  3. package/dist/api-jcCTCqPD.d.ts +61 -0
  4. package/dist/chunk-4I767MRM.mjs +142 -0
  5. package/dist/chunk-5V5ILPP3.js +1 -0
  6. package/dist/chunk-BJEDX2HU.js +142 -0
  7. package/dist/chunk-GZOB4JDB.js +1 -0
  8. package/dist/chunk-ODKXUEH5.js +1 -0
  9. package/dist/chunk-U335FNUD.mjs +1 -0
  10. package/dist/chunk-YRU7AXYV.mjs +1 -0
  11. package/dist/chunk-Z75DRSTN.mjs +1 -0
  12. package/dist/{errorTranslation-CF-5JClP.d.ts → errorTranslation-BdqG-dXD.d.ts} +97 -26
  13. package/dist/{errorTranslation-BcX8AaK7.d.mts → errorTranslation-BxJmBGx0.d.mts} +97 -26
  14. package/dist/hooks.d.mts +3 -4
  15. package/dist/hooks.d.ts +3 -4
  16. package/dist/hooks.js +1 -1
  17. package/dist/hooks.mjs +1 -1
  18. package/dist/{index-D06kTP0C.d.mts → index-Cx9P3ZCG.d.mts} +225 -139
  19. package/dist/{index-DEDnmsdO.d.ts → index-rHtWMls-.d.ts} +225 -139
  20. package/dist/index.d.mts +508 -213
  21. package/dist/index.d.ts +508 -213
  22. package/dist/index.js +2 -2
  23. package/dist/index.mjs +2 -2
  24. package/dist/public-policies.d.mts +7 -0
  25. package/dist/public-policies.d.ts +7 -0
  26. package/dist/public-policies.js +1 -0
  27. package/dist/public-policies.mjs +1 -0
  28. package/dist/utils.d.mts +94 -26
  29. package/dist/utils.d.ts +94 -26
  30. package/dist/utils.js +1 -1
  31. package/dist/utils.mjs +1 -1
  32. package/package.json +44 -42
  33. package/.github/workflows/ci.yml +0 -70
  34. package/.husky/pre-commit +0 -26
  35. package/.husky/pre-push +0 -30
  36. package/.nvmrc +0 -1
  37. package/.prettierignore +0 -18
  38. package/.prettierrc +0 -9
  39. package/README_DEPTH.md +0 -1237
  40. package/coverage/base.css +0 -224
  41. package/coverage/block-navigation.js +0 -87
  42. package/coverage/coverage-final.json +0 -120
  43. package/coverage/favicon.png +0 -0
  44. package/coverage/index.html +0 -686
  45. package/coverage/lcov-report/base.css +0 -224
  46. package/coverage/lcov-report/block-navigation.js +0 -87
  47. package/coverage/lcov-report/favicon.png +0 -0
  48. package/coverage/lcov-report/index.html +0 -686
  49. package/coverage/lcov-report/prettify.css +0 -1
  50. package/coverage/lcov-report/prettify.js +0 -2
  51. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  52. package/coverage/lcov-report/sorter.js +0 -210
  53. package/coverage/lcov.info +0 -22388
  54. package/coverage/prettify.css +0 -1
  55. package/coverage/prettify.js +0 -2
  56. package/coverage/sort-arrow-sprite.png +0 -0
  57. package/coverage/sorter.js +0 -210
  58. package/dist/CrudiaMarkdownField-CkiBwG-U.d.ts +0 -343
  59. package/dist/CrudiaMarkdownField-D-DqiXMQ.d.mts +0 -343
  60. package/dist/GlobalNotificationProvider-CdwdNv_8.d.mts +0 -96
  61. package/dist/GlobalNotificationProvider-CdwdNv_8.d.ts +0 -96
  62. package/dist/chunk-2WAUZ6KI.js +0 -1
  63. package/dist/chunk-3IGZNZCT.mjs +0 -1
  64. package/dist/chunk-43L2PP77.mjs +0 -1
  65. package/dist/chunk-6VS5OT3A.mjs +0 -1
  66. package/dist/chunk-BWJTTMKS.js +0 -1
  67. package/dist/chunk-EMPPCCVU.js +0 -1
  68. package/dist/chunk-J43UPGBE.js +0 -1
  69. package/dist/chunk-K6ZRXOJ7.mjs +0 -1
  70. package/dist/chunk-RYQQZTEP.js +0 -1
  71. package/dist/chunk-VTMSOK4V.mjs +0 -1
  72. package/dist/components.d.mts +0 -24
  73. package/dist/components.d.ts +0 -24
  74. package/dist/components.js +0 -1
  75. package/dist/components.mjs +0 -1
  76. package/dist/tenantConfig-CYnS9TPV.d.mts +0 -318
  77. package/dist/tenantConfig-CYnS9TPV.d.ts +0 -318
  78. package/eslint.config.mjs +0 -140
  79. package/scripts/bump-version.cjs +0 -23
  80. package/sonar-project.properties +0 -23
  81. package/tests/helpers/testUtils.tsx +0 -89
  82. package/tests/hooks/useSession/testUtils.tsx +0 -212
  83. package/tests/setup.ts +0 -139
  84. package/tests/vitest.d.ts +0 -1
  85. package/vitest.config.ts +0 -39
package/dist/index.d.ts CHANGED
@@ -1,17 +1,71 @@
1
1
  import { CrudifyInstance } from '@nocios/crudify-sdk';
2
2
  export * from '@nocios/crudify-sdk';
3
3
  export { CrudifyInstance } from '@nocios/crudify-sdk';
4
- import { g as CrudifyLoginConfig, E as EvaluatedPasswordRule, l as PasswordRule } from './CrudiaMarkdownField-CkiBwG-U.js';
5
- export { B as BoxScreenType, C as CrudiaAutoGenerate, a as CrudiaAutoGenerateProps, b as CrudiaFileField, m as CrudiaFileFieldDeletionHandlers, c as CrudiaFileFieldProps, d as CrudiaMarkdownField, e as CrudiaMarkdownFieldProps, f as CrudifyLogin, h as CrudifyLoginProps, i as CrudifyLoginTranslations, D as DEFAULT_PASSWORD_RULES, L as LoginComponent, n as POLICY_ACTIONS, o as PREFERRED_POLICY_ORDER, p as PasswordRuleType, P as Policies, j as PolicyAction, S as SessionStatus, U as UserLoginData, k as UserProfileDisplay } from './CrudiaMarkdownField-CkiBwG-U.js';
6
- import React, { ReactNode } from 'react';
7
- export { A as ApiError, f as CrudifyApiResponse, a as CrudifyEnvironment, g as CrudifyOperationOptions, h as CrudifyRequestOptions, i as CrudifyTransactionResponse, F as ForgotPasswordRequest, J as JwtPayload, L as LoginRequest, j as LoginResponse, k as ResetPasswordRequest, b as ResolvedTenantConfig, T as TenantConfig, c as TenantConfigOptions, l as TransactionInput, m as TransactionOperation, n as TransactionResponseData, U as UserProfile, V as ValidateCodeRequest, o as ValidationError, d as resolveTenantConfig, e as useTenantConfig } from './tenantConfig-CYnS9TPV.js';
8
- export { F as FileItem, a as FileStatus, L as LoginResult, N as NotificationOptions, S as SessionConfig, b as SessionDebugInfo, c as SessionManager, d as SessionProvider, e as SessionProviderProps, f as SessionState, g as StorageType, T as TokenData, h as TokenStorage, U as UseAuthReturn, i as UseDataReturn, j as UseFileUploadOptions, k as UseFileUploadReturn, l as UseSessionOptions, m as UseUserDataOptions, n as UseUserDataReturn, o as UserData, u as useAuth, p as useCrudifyWithNotifications, q as useData, r as useFileUpload, s as useSession, t as useSessionContext, v as useUserData, w as useUserProfile } from './index-DEDnmsdO.js';
4
+ import React, { ReactNode, RefObject } from 'react';
5
+ import { PasswordRule, FrontendEnvironment, AdminApiResponse, ModuleDefinition, ModuleCreateInput, ModuleEditInput, ModuleVersionItem, AdminActionFilters, ActionDefinition, ActionCreateInput, ActionEditInput, ActionVersionItem, UpdateActionsProfilesInput, UpdateActionsProfilesResponse, CalculatePermissionsInput, CalculatePermissionsResponse } from '@nocios/frontend-types';
6
+ export { CrudifyOperationOptions, CrudifyRequestOptions, CrudifyResponse, CrudifyTransactionResponse, FrontendEnvironment, PasswordRule, PasswordRuleType, TenantConfig, TransactionInput, TransactionOperation, TransactionResponseData } from '@nocios/frontend-types';
7
+ import { PolicyAction } from './public-policies.js';
8
+ export { POLICY_ACTIONS, PREFERRED_POLICY_ORDER } from './public-policies.js';
9
+ export { A as ApiError, F as ForgotPasswordRequest, J as JwtPayload, L as LoginRequest, a as LoginResponse, R as ResetPasswordRequest, U as UserProfile, V as ValidateCodeRequest, b as ValidationError } from './api-jcCTCqPD.js';
10
+ import { A as AutoGenerateConfig } from './index-rHtWMls-.js';
11
+ export { F as FileItem, a as FileStatus, G as GlobalNotificationProvider, b as GlobalNotificationProviderProps, L as LoginResult, N as Notification, c as NotificationOptions, d as NotificationSeverity, S as SessionConfig, e as SessionDebugInfo, f as SessionManager, g as SessionProvider, h as SessionProviderProps, i as SessionState, j as StorageType, T as TokenData, k as TokenStorage, U as UseAuthReturn, l as UseAutoGenerateOptions, m as UseAutoGenerateReturn, n as UseDataReturn, o as UseFileUploadOptions, p as UseFileUploadReturn, q as UseSessionOptions, r as UseUserDataOptions, s as UseUserDataReturn, t as UserData, u as useAuth, v as useAutoGenerate, w as useCrudifyWithNotifications, x as useData, y as useFileUpload, z as useGlobalNotification, B as useSession, C as useSessionContext, D as useUserData, E as useUserProfile } from './index-rHtWMls-.js';
9
12
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
13
  import { ThemeOptions } from '@mui/material';
11
- export { A as AutoGenerateConfig, G as GlobalNotificationProvider, a as GlobalNotificationProviderProps, N as Notification, b as NotificationSeverity, U as UseAutoGenerateOptions, c as UseAutoGenerateReturn, d as useAutoGenerate, u as useGlobalNotification } from './GlobalNotificationProvider-CdwdNv_8.js';
12
- export { E as ERROR_CODES, a as ERROR_SEVERITY_MAP, b as ErrorCode, c as ErrorSeverity, d as ErrorTranslationConfig, P as ParsedError, e as createErrorTranslator, f as decodeJwtSafely, g as getCurrentUserEmail, h as getErrorMessage, i as handleCrudifyError, j as isTokenExpired, p as parseApiError, k as parseJavaScriptError, l as parseTransactionError, s as secureLocalStorage, m as secureSessionStorage, t as translateError, n as translateErrorCode, o as translateErrorCodes } from './errorTranslation-CF-5JClP.js';
13
- import { ApiResponse, IModule, ModuleCreateInput, ModuleEditInput, ActionListFilters, IAction, ActionCreateInput, ActionEditInput, UpdateActionsProfilesInput, UpdateActionsProfilesResponse, CalculatePermissionsInput, CalculatePermissionsResponse } from '@nocios/crudify-admin-sdk';
14
- export { ActionCreateInput, ActionEditInput, ActionListFilters, ApiResponse, IAction, IModule, ModuleCreateInput, ModuleEditInput, UpdateActionsProfilesInput, UpdateActionsProfilesResponse } from '@nocios/crudify-admin-sdk';
14
+ import { LogContext } from '@nocios/frontend-types/shared';
15
+ export { LogContext, LogLevel } from '@nocios/frontend-types/shared';
16
+ export { C as CrudifyEnvironment, E as ERROR_CODES, a as ERROR_SEVERITY_MAP, b as ErrorCode, c as ErrorSeverity, d as ErrorTranslationConfig, P as ParsedError, R as ResolvedTenantConfig, T as TenantConfigOptions, e as createErrorTranslator, f as decodeJwtSafely, g as getCurrentUserEmail, h as getErrorMessage, i as handleCrudifyError, j as isTokenExpired, p as parseApiError, k as parseJavaScriptError, l as parseTransactionError, r as resolveTenantConfig, s as secureLocalStorage, m as secureSessionStorage, t as translateError, n as translateErrorCode, o as translateErrorCodes, u as useTenantConfig } from './errorTranslation-BdqG-dXD.js';
17
+
18
+ /**
19
+ * Password validation types and constants
20
+ * Used for password requirements validation in forms
21
+ */
22
+
23
+ interface EvaluatedPasswordRule {
24
+ message: string;
25
+ valid: boolean;
26
+ enforce: boolean;
27
+ }
28
+ /**
29
+ * Default password rules used as fallback when no custom rules are provided.
30
+ * Messages are translation keys that should be translated at runtime.
31
+ */
32
+ declare const DEFAULT_PASSWORD_RULES: PasswordRule[];
33
+
34
+ type BoxScreenType = 'login' | 'signUp' | 'forgotPassword' | 'resetPassword' | 'checkCode';
35
+ interface CrudifyLoginConfig {
36
+ publicApiKey?: string | null;
37
+ env?: FrontendEnvironment;
38
+ appName?: string;
39
+ logo?: string;
40
+ loginActions?: string[];
41
+ }
42
+ interface CrudifyLoginTranslations {
43
+ [key: string]: string | CrudifyLoginTranslations;
44
+ }
45
+ interface UserLoginData {
46
+ token: string;
47
+ username?: string;
48
+ email?: string;
49
+ userId?: string;
50
+ profile?: Record<string, unknown>;
51
+ [key: string]: unknown;
52
+ }
53
+ interface CrudifyLoginProps {
54
+ onScreenChange?: (screen: BoxScreenType, params?: Record<string, string>) => void;
55
+ onExternalNavigate?: (path: string) => void;
56
+ onLoginSuccess?: (userData: UserLoginData, redirectUrl?: string) => void;
57
+ onError?: (error: string) => void;
58
+ initialScreen?: BoxScreenType;
59
+ redirectUrl?: string;
60
+ autoReadFromCookies?: boolean;
61
+ translations?: CrudifyLoginTranslations;
62
+ translationsUrl?: string;
63
+ language?: string;
64
+ /** Custom password rules for reset password form. Falls back to default rules if not provided. */
65
+ passwordRules?: PasswordRule[];
66
+ }
67
+
68
+ declare const CrudifyLogin: React.FC<CrudifyLoginProps>;
15
69
 
16
70
  interface CrudifyContextValue {
17
71
  crudify: typeof CrudifyInstance | null;
@@ -30,12 +84,41 @@ interface CrudifyProviderProps {
30
84
  declare const CrudifyProvider: React.FC<CrudifyProviderProps>;
31
85
  declare const useCrudify: () => CrudifyContextValue;
32
86
 
87
+ interface UserProfileDisplayProps {
88
+ showExtendedData?: boolean;
89
+ showProfileCard?: boolean;
90
+ autoRefresh?: boolean;
91
+ }
92
+ declare const UserProfileDisplay: React.FC<UserProfileDisplayProps>;
93
+
94
+ type Policy = {
95
+ id: string;
96
+ action: PolicyAction;
97
+ fields?: {
98
+ allow: string[];
99
+ owner_allow: string[];
100
+ deny: string[];
101
+ };
102
+ permission?: string;
103
+ };
104
+ type FieldErrorMap = string | ({
105
+ _error?: string;
106
+ } & Record<string, string | undefined>);
107
+ interface PoliciesProps {
108
+ policies: Policy[];
109
+ onChange: (next: Policy[]) => void;
110
+ availableFields: string[];
111
+ errors?: FieldErrorMap;
112
+ isSubmitting?: boolean;
113
+ }
114
+ declare const Policies: React.FC<PoliciesProps>;
115
+
33
116
  /**
34
- * Tipos de mensajes que se pueden enviar entre tabs
117
+ * Types of messages that can be sent between tabs
35
118
  */
36
119
  type CrossTabMessageType = 'SESSION_STARTED' | 'SESSION_ENDED' | 'TOKEN_REFRESHED' | 'SESSION_PING' | 'SESSION_PONG';
37
120
  /**
38
- * Estructura del mensaje cross-tab
121
+ * Cross-tab message structure
39
122
  */
40
123
  interface CrossTabMessage {
41
124
  type: CrossTabMessageType;
@@ -44,79 +127,79 @@ interface CrossTabMessage {
44
127
  payload?: Record<string, unknown>;
45
128
  }
46
129
  /**
47
- * Tipo de callback para suscriptores
130
+ * Callback type for subscribers
48
131
  */
49
132
  type CrossTabListener = (message: CrossTabMessage) => void;
50
133
  /**
51
- * Manager singleton para sincronización cross-tab
134
+ * Singleton manager for cross-tab synchronization
52
135
  */
53
136
  declare class CrossTabSyncManager {
54
137
  private static instance;
55
138
  private broadcastChannel;
56
139
  private readonly CHANNEL_NAME;
57
- private tabId;
58
- private listeners;
140
+ private readonly tabId;
141
+ private readonly listeners;
59
142
  private isInitialized;
60
143
  /**
61
- * Constructor privado - usar getInstance()
144
+ * Private constructor - use getInstance()
62
145
  */
63
146
  private constructor();
64
147
  /**
65
- * Genera un ID único para esta pestaña
148
+ * Generate a unique ID for this tab
66
149
  */
67
150
  private static generateTabId;
68
151
  /**
69
- * Obtener la instancia singleton
152
+ * Get the singleton instance
70
153
  */
71
154
  static getInstance(): CrossTabSyncManager;
72
155
  /**
73
- * Resetear la instancia (útil para tests)
156
+ * Reset the instance (useful for tests)
74
157
  */
75
158
  static resetInstance(): void;
76
159
  /**
77
- * Inicializar el canal de comunicación
160
+ * Initialize the communication channel
78
161
  */
79
162
  private initialize;
80
163
  /**
81
- * Destruir el manager y limpiar recursos
164
+ * Destroy the manager and clean up resources
82
165
  */
83
166
  destroy(): void;
84
167
  /**
85
- * Obtener el ID de esta pestaña
168
+ * Get the ID of this tab
86
169
  */
87
170
  getTabId(): string;
88
171
  /**
89
- * Suscribirse a mensajes de otras pestañas
90
- * @returns Función para desuscribirse
172
+ * Subscribe to messages from other tabs
173
+ * @returns Unsubscribe function
91
174
  */
92
175
  subscribe(listener: CrossTabListener): () => void;
93
176
  /**
94
- * Notificar que se inició sesión en esta pestaña
177
+ * Notify that a session was started in this tab
95
178
  */
96
179
  notifyLogin(): void;
97
180
  /**
98
- * Notificar que se cerró sesión en esta pestaña
181
+ * Notify that the session was ended in this tab
99
182
  */
100
183
  notifyLogout(): void;
101
184
  /**
102
- * Notificar que se refrescaron los tokens
185
+ * Notify that tokens were refreshed
103
186
  */
104
187
  notifyTokenRefreshed(): void;
105
188
  /**
106
- * Enviar un ping para verificar otras pestañas activas
189
+ * Send a ping to check for other active tabs
107
190
  */
108
191
  ping(): void;
109
192
  /**
110
- * Enviar mensaje a todas las demás pestañas
193
+ * Send message to all other tabs
111
194
  */
112
195
  private broadcast;
113
196
  /**
114
- * Procesar mensaje recibido de otra pestaña
197
+ * Process message received from another tab
115
198
  */
116
199
  private handleMessage;
117
200
  }
118
201
  /**
119
- * Instancia singleton exportada para uso directo
202
+ * Exported singleton instance for direct use
120
203
  */
121
204
  declare const crossTabSync: CrossTabSyncManager;
122
205
 
@@ -126,9 +209,9 @@ type CrudifyThemeProviderProps = {
126
209
  disableCssBaseline?: boolean;
127
210
  };
128
211
  /**
129
- * Provider de tema para aplicaciones Crudify
130
- * Lee automáticamente el theme desde window.__TENANT_CONFIG__ (inyectado por Lambda@Edge)
131
- * y aplica el tema a Material-UI
212
+ * Theme provider for Crudify applications
213
+ * Automatically reads the theme from window.__TENANT_CONFIG__ (injected by Lambda@Edge)
214
+ * and applies it to Material-UI
132
215
  *
133
216
  * @example
134
217
  * ```tsx
@@ -137,7 +220,7 @@ type CrudifyThemeProviderProps = {
137
220
  * </CrudifyThemeProvider>
138
221
  * ```
139
222
  *
140
- * @example Con tema por defecto personalizado
223
+ * @example With custom default theme
141
224
  * ```tsx
142
225
  * <CrudifyThemeProvider defaultTheme={{ palette: { mode: 'dark' } }}>
143
226
  * <App />
@@ -146,6 +229,253 @@ type CrudifyThemeProviderProps = {
146
229
  */
147
230
  declare function CrudifyThemeProvider({ children, defaultTheme, disableCssBaseline, }: Readonly<CrudifyThemeProviderProps>): react_jsx_runtime.JSX.Element;
148
231
 
232
+ declare function LoginComponent(): react_jsx_runtime.JSX.Element;
233
+ /**
234
+ * Simple session status component to display anywhere
235
+ */
236
+ declare function SessionStatus(): react_jsx_runtime.JSX.Element;
237
+
238
+ interface CrudiaAutoGenerateProps {
239
+ config: AutoGenerateConfig;
240
+ value?: string;
241
+ onChange?: (value: string) => void;
242
+ label?: string;
243
+ error?: boolean;
244
+ helperText?: string;
245
+ readOnly?: boolean;
246
+ disabled?: boolean;
247
+ name?: string;
248
+ containerRef?: React.RefObject<HTMLDivElement | null>;
249
+ }
250
+ /**
251
+ * Component for auto-generated fields (sequential codes)
252
+ *
253
+ * Features:
254
+ * - Auto-fetches the code on mount
255
+ * - Automatic duplicate error detection
256
+ * - "Regenerate" button in endAdornment when there is a duplicate error
257
+ * - Loading and error states
258
+ * - Read-only by default
259
+ * - Integration with useAutoGenerate hook
260
+ *
261
+ * Duplicate Error Handling Flow:
262
+ * 1. User opens form -> Code is generated automatically (e.g.: PROD-0013671)
263
+ * 2. User fills the form and submits
264
+ * 3. Backend returns "duplicate key" or "unique constraint" error
265
+ * 4. Parent form passes error={true} and helperText="Code already exists"
266
+ * 5. Component detects duplicate keywords and shows regenerate button
267
+ * 6. User clicks regenerate button -> New code is generated
268
+ * 7. onChange is called with new code -> Parent form clears the error
269
+ * 8. Regenerate button disappears (because there is no longer an error)
270
+ *
271
+ * @example
272
+ * ```tsx
273
+ * // Basic usage
274
+ * <CrudiaAutoGenerate
275
+ * config={{ prefix: "PROD-", padding: 7 }}
276
+ * onChange={(code) => setFormData({ ...formData, barCode: code })}
277
+ * label="Código de Barras"
278
+ * />
279
+ *
280
+ * // With duplicate error handling from the form
281
+ * <CrudiaAutoGenerate
282
+ * config={{ prefix: "PROD-", padding: 7 }}
283
+ * onChange={(code) => {
284
+ * setFormData({ ...formData, barCode: code });
285
+ * // Clear error when the code changes
286
+ * setFormErrors({ ...formErrors, barCode: null });
287
+ * }}
288
+ * label="Código de Barras"
289
+ * error={!!formErrors.barCode}
290
+ * helperText={formErrors.barCode}
291
+ * />
292
+ * ```
293
+ */
294
+ declare const CrudiaAutoGenerate: React.FC<CrudiaAutoGenerateProps>;
295
+
296
+ /**
297
+ * Types and interfaces for CrudiaFileField component
298
+ */
299
+
300
+ /**
301
+ * Deletion handlers exposed by the component
302
+ */
303
+ interface CrudiaFileFieldDeletionHandlers {
304
+ /** Execute all pending deletions (call this on form success callback) */
305
+ commitDeletions: () => Promise<{
306
+ success: boolean;
307
+ errors: string[];
308
+ }>;
309
+ /** Cancel all pending deletions and restore files */
310
+ restorePendingDeletions: () => void;
311
+ /** Whether there are files pending deletion */
312
+ hasPendingDeletions: boolean;
313
+ /** Mark the field as submitted (triggers validation errors display) */
314
+ markAsSubmitted: () => void;
315
+ /** Whether the field is valid */
316
+ isValid: boolean;
317
+ /** Whether files are currently being uploaded */
318
+ isUploading: boolean;
319
+ /** Wait for all uploads to complete - returns completed file paths */
320
+ waitForUploads: () => Promise<string[]>;
321
+ /** Get completed file paths synchronously (may be stale if uploads just finished) */
322
+ getCompletedFilePaths: () => string[];
323
+ }
324
+ /**
325
+ * Props del componente CrudiaFileField
326
+ */
327
+ interface CrudiaFileFieldProps {
328
+ /** Label del campo */
329
+ label?: string;
330
+ /** Tipos MIME permitidos (ej: ["image/png", "image/jpeg"]) */
331
+ accept?: string[];
332
+ /** Tamaño máximo por archivo en bytes */
333
+ maxFileSize?: number;
334
+ /** Permitir múltiples archivos */
335
+ multiple?: boolean;
336
+ /** Número máximo de archivos (solo si multiple=true) */
337
+ maxFiles?: number;
338
+ /** Número mínimo de archivos requeridos */
339
+ minFiles?: number;
340
+ /** Campo requerido */
341
+ required?: boolean;
342
+ /** Campo deshabilitado */
343
+ disabled?: boolean;
344
+ /** Error externo */
345
+ error?: boolean;
346
+ /** Texto de ayuda o error */
347
+ helperText?: string;
348
+ /**
349
+ * Callback cuando cambian los filePaths de archivos completados
350
+ * Los filePaths son rutas relativas con visibility (public/... o private/...)
351
+ */
352
+ onChange?: (filePaths: string[]) => void;
353
+ /** Callback cuando se valida el campo */
354
+ onValidation?: (isValid: boolean, error: string | null) => void;
355
+ /** Archivos existentes (para edición) - usar filePath (ruta relativa con visibility) */
356
+ initialFiles?: Array<{
357
+ filePath: string;
358
+ name: string;
359
+ size?: number;
360
+ contentType?: string;
361
+ }>;
362
+ /** Texto placeholder para drag zone */
363
+ placeholder?: string;
364
+ /** Mostrar lista de archivos */
365
+ showFileList?: boolean;
366
+ /**
367
+ * Visibilidad de los archivos subidos
368
+ * @default "private"
369
+ */
370
+ visibility?: 'public' | 'private';
371
+ /**
372
+ * Mostrar preview de imágenes
373
+ * @default true para imágenes
374
+ */
375
+ showPreview?: boolean;
376
+ /**
377
+ * URL base para prefijar al path del archivo
378
+ * El valor guardado será baseUrl + path
379
+ * También se usa para previsualizar/descargar archivos públicos en modo readonly
380
+ */
381
+ baseUrl: string;
382
+ /**
383
+ * Callback called when deletion handlers are ready
384
+ * Use this to get access to commitDeletions and restorePendingDeletions functions
385
+ */
386
+ onDeletionHandlersReady?: (handlers: CrudiaFileFieldDeletionHandlers) => void;
387
+ /**
388
+ * Form mode: 'create' or 'edit' - affects delete behavior
389
+ * - create: delete shows confirmation and deletes immediately from server
390
+ * - edit: existing files use pendingDeletion, new files delete immediately
391
+ * @default "create"
392
+ */
393
+ mode?: 'create' | 'edit';
394
+ /** HTML name attribute for the hidden file input */
395
+ name?: string;
396
+ /** Ref para el contenedor (usado para scroll en errores) */
397
+ containerRef?: RefObject<HTMLDivElement | null>;
398
+ }
399
+
400
+ /**
401
+ * File field component with:
402
+ * - Drag & drop
403
+ * - File preview
404
+ * - Progress bar during upload
405
+ * - Delete files (soft delete)
406
+ * - Type and size validation
407
+ * - Single/multiple support
408
+ */
409
+
410
+ /**
411
+ * Main file field component
412
+ *
413
+ * @example
414
+ * ```tsx
415
+ * // Basic usage - single file
416
+ * <CrudiaFileField
417
+ * label="Document"
418
+ * accept={["application/pdf"]}
419
+ * onChange={(filePaths) => setFormData({ ...formData, document: filePaths[0] })}
420
+ * />
421
+ *
422
+ * // Multiple files with limits
423
+ * <CrudiaFileField
424
+ * label="Images"
425
+ * accept={["image/png", "image/jpeg"]}
426
+ * multiple
427
+ * maxFiles={5}
428
+ * minFiles={1}
429
+ * maxFileSize={5 * 1024 * 1024}
430
+ * onChange={(filePaths) => setFormData({ ...formData, images: filePaths })}
431
+ * />
432
+ *
433
+ * // With initial files (edit mode)
434
+ * <CrudiaFileField
435
+ * label="Attachments"
436
+ * multiple
437
+ * initialFiles={existingFiles}
438
+ * onChange={handleFilesChange}
439
+ * />
440
+ * ```
441
+ */
442
+ declare const CrudiaFileField: React.FC<CrudiaFileFieldProps>;
443
+
444
+ /**
445
+ * Markdown field component with rich text editing using MDXEditor
446
+ * - WYSIWYG markdown editing
447
+ * - Toolbar with formatting options
448
+ * - Saves content as markdown string
449
+ */
450
+
451
+ interface CrudiaMarkdownFieldProps {
452
+ /** Field label */
453
+ label?: string;
454
+ /** Current value (markdown string) */
455
+ value?: string;
456
+ /** Callback when content changes */
457
+ onChange?: (value: string) => void;
458
+ /** Required field */
459
+ required?: boolean;
460
+ /** Disabled/readonly field */
461
+ disabled?: boolean;
462
+ /** External error state */
463
+ error?: boolean;
464
+ /** Helper or error text */
465
+ helperText?: string;
466
+ /** Placeholder text */
467
+ placeholder?: string;
468
+ /** Minimum editor height in pixels */
469
+ minHeight?: number;
470
+ /** Maximum editor height in pixels (scrolls after) */
471
+ maxHeight?: number;
472
+ /** HTML name attribute for hidden input (for form semantics) */
473
+ name?: string;
474
+ /** Ref para el contenedor (usado para scroll en errores) */
475
+ containerRef?: React.RefObject<HTMLDivElement | null>;
476
+ }
477
+ declare const CrudiaMarkdownField: React.FC<CrudiaMarkdownFieldProps>;
478
+
149
479
  interface PasswordRequirementsProps {
150
480
  requirements: Array<{
151
481
  message: string;
@@ -174,93 +504,15 @@ declare function evaluatePasswordRules(password: string, rules: PasswordRule[]):
174
504
  */
175
505
  declare function allPasswordRulesPassed(evaluated: EvaluatedPasswordRule[]): boolean;
176
506
 
177
- /**
178
- * Unified Logger for Crudify Projects
179
- *
180
- * Environment-based logging:
181
- * - dev/stg: All logs (error, warn, info, debug)
182
- * - prod: Only errors (default)
183
- *
184
- * AUTO-DETECTION (v2.0.0 - No longer uses cookies):
185
- * The logger will automatically detect the environment from:
186
- * 1. Explicit setEnvironment() call (highest priority)
187
- * 2. window.__TENANT_CONFIG__.environment (production with Lambda@Edge)
188
- * 3. window.__CRUDIFY_ENV__ global variable (legacy/fallback)
189
- * 4. Default to "prod" for safety
190
- *
191
- * Usage:
192
- * import { logger } from './logger';
193
- *
194
- * // Option 1: Explicit configuration (recommended for apps)
195
- * logger.setEnvironment('dev'); // or 'stg', 'prod'
196
- *
197
- * // Option 2: Auto-detection (reads from window.__TENANT_CONFIG__)
198
- * // Just use the logger - it will auto-detect
199
- *
200
- * logger.error('Something failed', { userId: '123' });
201
- * logger.warn('Deprecated feature used');
202
- * logger.info('User logged in', { email: 'user@example.com' });
203
- * logger.debug('Processing request', { payload: data });
204
- */
205
- type LogLevel = 'error' | 'warn' | 'info' | 'debug';
206
- interface LogContext {
207
- [key: string]: unknown;
208
- }
209
507
  declare class Logger {
210
- private explicitEnv;
211
- private prefix;
508
+ private readonly core;
212
509
  constructor();
213
- /**
214
- * Get current effective environment
215
- * Priority: explicit setEnvironment() > auto-detection
216
- */
217
- private getEffectiveEnv;
218
- /**
219
- * Sanitize sensitive data from strings
220
- */
221
- private sanitize;
222
- /**
223
- * Sanitize context object
224
- */
225
- private sanitizeContext;
226
- /**
227
- * Check if a log level should be displayed based on environment
228
- * - dev/stg: show all logs
229
- * - prod: show only errors (unless CRUDIFY_DEBUG_MODE is enabled)
230
- */
231
- private shouldLog;
232
- /**
233
- * Format and output log entry
234
- */
235
- private log;
236
- /**
237
- * Log an error - Always logged in all environments
238
- */
239
510
  error(message: string, context?: LogContext | Error): void;
240
- /**
241
- * Log a warning - Only in dev/stg
242
- */
243
511
  warn(message: string, context?: LogContext): void;
244
- /**
245
- * Log info - Only in dev/stg
246
- */
247
512
  info(message: string, context?: LogContext): void;
248
- /**
249
- * Log debug information - Only in dev/stg
250
- */
251
513
  debug(message: string, context?: LogContext): void;
252
- /**
253
- * Get current effective environment
254
- */
255
514
  getEnvironment(): string;
256
- /**
257
- * Manually set environment (useful for libraries that receive env from parent app)
258
- * This takes priority over auto-detection
259
- */
260
515
  setEnvironment(env: string): void;
261
- /**
262
- * Check if environment was explicitly set or auto-detected
263
- */
264
516
  isExplicitlyConfigured(): boolean;
265
517
  }
266
518
  declare const logger: Logger;
@@ -268,24 +520,24 @@ declare const logger: Logger;
268
520
  interface ProtectedRouteProps {
269
521
  children: ReactNode;
270
522
  /**
271
- * Componente a mostrar mientras se valida la sesión
523
+ * Component to display while the session is being validated
272
524
  * @default <SessionLoadingScreen stage="validating-session" />
273
525
  */
274
526
  loadingComponent?: ReactNode;
275
527
  /**
276
- * Ruta a la que redirigir si no está autenticado
528
+ * Path to redirect to if not authenticated
277
529
  * @default "/login"
278
530
  */
279
531
  loginPath?: string;
280
532
  }
281
533
  /**
282
- * Componente para proteger rutas que requieren autenticación
534
+ * Component to protect routes that require authentication
283
535
  *
284
- * Características:
285
- * - Valida sesión de forma estricta (isAuthenticated + tokens válidos)
286
- * - Guarda URL actual para redirect post-login
287
- * - Previene open redirect attacks
288
- * - Limpia storage corrupto automáticamente
536
+ * Features:
537
+ * - Strictly validates the session (isAuthenticated + valid tokens)
538
+ * - Saves the current URL for post-login redirect
539
+ * - Prevents open redirect attacks
540
+ * - Automatically cleans up corrupted storage
289
541
  *
290
542
  * @example
291
543
  * ```tsx
@@ -304,32 +556,32 @@ declare function ProtectedRoute({ children, loadingComponent, loginPath }: Reado
304
556
  interface AuthRouteProps {
305
557
  children: ReactNode;
306
558
  /**
307
- * Ruta a la que redirigir si ya está autenticado
308
- * Si hay parámetro ?redirect= en la URL, se usará ese en su lugar
559
+ * Path to redirect to if already authenticated
560
+ * If a ?redirect= parameter exists in the URL, it will be used instead
309
561
  * @default "/"
310
562
  */
311
563
  redirectTo?: string;
312
564
  /**
313
- * Componente a mostrar mientras se valida la sesión
565
+ * Component to display while the session is being validated
314
566
  * @default <SessionLoadingScreen stage="validating-session" />
315
567
  */
316
568
  loadingComponent?: ReactNode;
317
569
  /**
318
- * Tiempo máximo de espera (ms) para la inicialización antes de mostrar el form
570
+ * Maximum wait time (ms) for initialization before showing the form
319
571
  * @default 3000
320
572
  */
321
573
  initTimeout?: number;
322
574
  }
323
575
  /**
324
- * Componente para proteger rutas de autenticación (login, register, etc.)
325
- * Redirige a home si el usuario ya está autenticado
576
+ * Component to protect authentication routes (login, register, etc.)
577
+ * Redirects to home if the user is already authenticated
326
578
  *
327
- * Características:
328
- * - Si usuario autenticado redirige a home (o ?redirect= si existe)
329
- * - Si no autenticado muestra el componente (login, etc.)
330
- * - Pre-check: Si hay tokens en localStorage, espera inicialización antes de mostrar form
331
- * - Timeout: Si la inicialización tarda mucho, muestra el form de todos modos
332
- * - Valida parámetro redirect para prevenir open redirect
579
+ * Features:
580
+ * - If user is authenticated -> redirects to home (or ?redirect= if present)
581
+ * - If not authenticated -> renders the component (login, etc.)
582
+ * - Pre-check: If tokens exist in localStorage, waits for initialization before showing the form
583
+ * - Timeout: If initialization takes too long, shows the form anyway
584
+ * - Validates the redirect parameter to prevent open redirect attacks
333
585
  *
334
586
  * @example
335
587
  * ```tsx
@@ -346,40 +598,40 @@ interface AuthRouteProps {
346
598
  declare function AuthRoute({ children, redirectTo, loadingComponent, initTimeout, }: Readonly<AuthRouteProps>): react_jsx_runtime.JSX.Element;
347
599
 
348
600
  /**
349
- * Comportamiento de GuestRoute cuando el usuario está autenticado
601
+ * GuestRoute behavior when the user is authenticated
350
602
  */
351
603
  type GuestRouteBehavior = 'redirect-if-authenticated' | 'allow-all';
352
604
  interface GuestRouteProps {
353
605
  children: ReactNode;
354
606
  /**
355
- * Comportamiento cuando el usuario está autenticado
356
- * - 'redirect-if-authenticated': Redirige al usuario a redirectTo (default)
357
- * - 'allow-all': Permite acceso tanto a usuarios autenticados como no autenticados
607
+ * Behavior when the user is authenticated
608
+ * - 'redirect-if-authenticated': Redirects the user to redirectTo (default)
609
+ * - 'allow-all': Allows access to both authenticated and unauthenticated users
358
610
  * @default 'redirect-if-authenticated'
359
611
  */
360
612
  behavior?: GuestRouteBehavior;
361
613
  /**
362
- * Ruta a la que redirigir si está autenticado y behavior es 'redirect-if-authenticated'
614
+ * Path to redirect to if authenticated and behavior is 'redirect-if-authenticated'
363
615
  * @default "/"
364
616
  */
365
617
  redirectTo?: string;
366
618
  /**
367
- * Componente a mostrar mientras se valida la sesión
619
+ * Component to display while the session is being validated
368
620
  * @default <SessionLoadingScreen stage="validating-session" />
369
621
  */
370
622
  loadingComponent?: ReactNode;
371
623
  }
372
624
  /**
373
- * Componente para rutas de invitados con comportamiento configurable
625
+ * Component for guest routes with configurable behavior
374
626
  *
375
- * Casos de uso:
376
- * - Login page: behavior='redirect-if-authenticated' redirige si ya está logueado
377
- * - Forgot password: behavior='allow-all' permite acceso aunque esté logueado
378
- * - Reset password: behavior='allow-all' permite acceso aunque esté logueado
627
+ * Use cases:
628
+ * - Login page: behavior='redirect-if-authenticated' -> redirects if already logged in
629
+ * - Forgot password: behavior='allow-all' -> allows access even if logged in
630
+ * - Reset password: behavior='allow-all' -> allows access even if logged in
379
631
  *
380
632
  * @example
381
633
  * ```tsx
382
- * // Login - redirige si ya está autenticado
634
+ * // Login - redirects if already authenticated
383
635
  * <Route
384
636
  * path="/login"
385
637
  * element={
@@ -389,7 +641,7 @@ interface GuestRouteProps {
389
641
  * }
390
642
  * />
391
643
  *
392
- * // Forgot password - permite acceso aunque esté autenticado
644
+ * // Forgot password - allows access even if authenticated
393
645
  * <Route
394
646
  * path="/login/forgotPassword"
395
647
  * element={
@@ -434,81 +686,81 @@ interface SessionLoadingScreenProps {
434
686
  * />
435
687
  * ```
436
688
  */
437
- declare function SessionLoadingScreen({ stage, message }: SessionLoadingScreenProps): react_jsx_runtime.JSX.Element;
689
+ declare function SessionLoadingScreen({ stage, message }: Readonly<SessionLoadingScreenProps>): react_jsx_runtime.JSX.Element;
438
690
 
439
691
  /**
440
- * Utilidades de seguridad para validar redirecciones
441
- * Previene ataques de open redirect permitiendo rutas dinámicas
692
+ * Security utilities for validating redirects
693
+ * Prevents open redirect attacks while allowing dynamic paths
442
694
  */
443
695
  /**
444
- * Valida que una ruta de redirección sea segura (solo rutas internas)
445
- * Permite rutas dinámicas pero bloquea ataques de open redirect
696
+ * Validates that a redirect path is safe (internal paths only)
697
+ * Allows dynamic paths but blocks open redirect attacks
446
698
  *
447
- * @param path - La ruta a validar
448
- * @param defaultPath - Ruta por defecto si la validación falla
449
- * @returns Ruta validada y segura
699
+ * @param path - The path to validate
700
+ * @param defaultPath - Default path if validation fails
701
+ * @returns Validated and safe path
450
702
  */
451
703
  declare const validateInternalRedirect: (path: string, defaultPath?: string) => string;
452
704
  /**
453
- * Valida que una URL de redirección sea segura
454
- * Soporta tanto rutas relativas internas como URLs absolutas de dominios confiables
705
+ * Validates that a redirect URL is safe
706
+ * Supports both internal relative paths and absolute URLs from trusted domains
455
707
  *
456
- * Casos de uso:
457
- * - Rutas relativas: /dashboard, /admin/users
458
- * - URLs absolutas confiables: https://files.nocios.link/subscriber/private/file.png
708
+ * Use cases:
709
+ * - Relative paths: /dashboard, /admin/users
710
+ * - Trusted absolute URLs: https://files.nocios.link/subscriber/private/file.png
459
711
  *
460
- * @param url - La URL o ruta a validar
461
- * @param defaultPath - Ruta por defecto si la validación falla
462
- * @returns URL o ruta validada y segura
712
+ * @param url - The URL or path to validate
713
+ * @param defaultPath - Default path if validation fails
714
+ * @returns Validated and safe URL or path
463
715
  */
464
716
  declare const validateTrustedRedirect: (url: string, defaultPath?: string) => string;
465
717
  /**
466
- * Extrae y valida parámetro redirect de URL search params
718
+ * Extracts and validates the redirect parameter from URL search params
467
719
  *
468
- * @param searchParams - URLSearchParams o string de query params
469
- * @param defaultPath - Ruta por defecto
470
- * @returns Ruta validada
720
+ * @param searchParams - URLSearchParams or query params string
721
+ * @param defaultPath - Default path
722
+ * @returns Validated path
471
723
  */
472
724
  declare const extractSafeRedirectFromUrl: (searchParams: URLSearchParams | string, defaultPath?: string) => string;
473
725
 
474
726
  /**
475
- * Verifica si hay tokens encriptados en localStorage
476
- * Hace un check rápido sin desencriptar
727
+ * Checks if there are encrypted tokens in localStorage
728
+ * Performs a quick check without decrypting
477
729
  *
478
- * @returns true si parece haber tokens guardados en formato v2
730
+ * @returns true if there appear to be tokens stored in v2 format
479
731
  */
480
732
  declare function hasStoredTokens(): boolean;
481
733
  /**
482
- * Verifica si existe el hash de la clave de encriptación
483
- * Si existe, indica que TokenStorage puede desencriptar los tokens
734
+ * Checks if the encryption key hash exists
735
+ * If it exists, it indicates that TokenStorage can decrypt the tokens
484
736
  *
485
- * @returns true si hay un hash de clave válido guardado
737
+ * @returns true if there is a valid key hash stored
486
738
  */
487
739
  declare function hasEncryptionKeyHash(): boolean;
488
740
  /**
489
- * Determina si debemos esperar a la inicialización de la sesión
490
- * antes de mostrar el formulario de login
741
+ * Determines if we should wait for session initialization
742
+ * before showing the login form
491
743
  *
492
- * Retorna true si:
493
- * - Hay tokens encriptados guardados
494
- * - Hay un hash de clave de encriptación (para poder desencriptarlos)
744
+ * Returns true if:
745
+ * - There are encrypted tokens stored
746
+ * - There is an encryption key hash (to be able to decrypt them)
495
747
  *
496
- * Esto indica alta probabilidad de sesión válida, por lo que
497
- * deberíamos mostrar loading mientras se inicializa SessionManager
748
+ * This indicates a high probability of a valid session, so
749
+ * we should show loading while SessionManager initializes
498
750
  *
499
- * @returns true si probablemente hay una sesión válida
751
+ * @returns true if there is likely a valid session
500
752
  */
501
753
  declare function shouldWaitForInitialization(): boolean;
502
754
  /**
503
- * Verifica si los tokens parecen estar corruptos o incompletos
504
- * Útil para decidir si limpiar el storage
755
+ * Checks if the tokens appear to be corrupted or incomplete
756
+ * Useful for deciding whether to clear the storage
505
757
  *
506
- * @returns true si hay datos pero parecen corruptos
758
+ * @returns true if there is data but it appears corrupted
507
759
  */
508
760
  declare function hasCorruptedTokens(): boolean;
509
761
  /**
510
- * Limpia tokens que parecen corruptos
511
- * Solo debe llamarse si hasCorruptedTokens() retorna true
762
+ * Clears tokens that appear corrupted
763
+ * Should only be called if hasCorruptedTokens() returns true
512
764
  */
513
765
  declare function clearCorruptedTokens(): void;
514
766
 
@@ -525,7 +777,7 @@ interface InitializationState {
525
777
  interface InitializationRequest {
526
778
  priority: InitializationPriority;
527
779
  publicApiKey: string;
528
- env: 'dev' | 'stg' | 'api' | 'prod';
780
+ env: FrontendEnvironment;
529
781
  enableLogging?: boolean;
530
782
  requestedBy: string;
531
783
  }
@@ -567,7 +819,7 @@ declare class CrudifyInitializationManager {
567
819
  private state;
568
820
  private initializationPromise;
569
821
  private highPriorityInitializerPresent;
570
- private waitingForHighPriority;
822
+ private readonly waitingForHighPriority;
571
823
  private readonly HIGH_PRIORITY_WAIT_TIMEOUT;
572
824
  private constructor();
573
825
  /**
@@ -595,6 +847,32 @@ declare class CrudifyInitializationManager {
595
847
  * @throws Error if initialization fails
596
848
  */
597
849
  initialize(request: InitializationRequest): Promise<void>;
850
+ /**
851
+ * Warn if a caller tries to initialize with a different API key than already configured
852
+ */
853
+ private warnIfKeyMismatch;
854
+ /**
855
+ * Log a debug message if logging is enabled
856
+ */
857
+ private logDebug;
858
+ /**
859
+ * Check if a LOW priority request should defer to a HIGH priority initializer
860
+ */
861
+ private shouldDeferToHighPriority;
862
+ /**
863
+ * Defer to HIGH priority initializer, waiting with timeout.
864
+ * Returns true if initialization was completed by HIGH priority (caller should return).
865
+ * Returns false if caller should proceed with its own initialization.
866
+ */
867
+ private deferToHighPriority;
868
+ /**
869
+ * If a HIGH priority request arrives while LOW priority is initializing, override it
870
+ */
871
+ private overrideLowPriorityIfNeeded;
872
+ /**
873
+ * Execute the actual SDK initialization and update state accordingly
874
+ */
875
+ private executeInitialization;
598
876
  /**
599
877
  * Wait for HIGH priority initializer with timeout
600
878
  */
@@ -654,7 +932,7 @@ declare const crudifyInitManager: CrudifyInitializationManager;
654
932
 
655
933
  interface CrudifyInitializerConfig {
656
934
  publicApiKey?: string;
657
- env?: 'dev' | 'stg' | 'api' | 'prod';
935
+ env?: FrontendEnvironment;
658
936
  enableLogging?: boolean;
659
937
  }
660
938
  interface CrudifyInitializerContextValue {
@@ -754,7 +1032,7 @@ interface I18nInstance {
754
1032
  interface TranslationsProviderProps {
755
1033
  children: React.ReactNode;
756
1034
  apiKey?: string;
757
- crudifyEnv?: 'dev' | 'stg' | 'api' | 'prod';
1035
+ crudifyEnv?: FrontendEnvironment;
758
1036
  featureKeys?: string[];
759
1037
  language?: string;
760
1038
  devTranslations?: Record<string, string>;
@@ -840,7 +1118,7 @@ declare const useTranslations: () => TranslationsContextValue;
840
1118
 
841
1119
  interface FetchTranslationsOptions {
842
1120
  apiKey: string;
843
- crudifyEnv?: 'dev' | 'stg' | 'api' | 'prod';
1121
+ crudifyEnv?: FrontendEnvironment;
844
1122
  featureKeys?: string[];
845
1123
  urlTranslations?: Record<string, string>;
846
1124
  }
@@ -876,6 +1154,19 @@ declare class TranslationService {
876
1154
  * Thread-safe: multiple calls will wait for the same initialization
877
1155
  */
878
1156
  private ensureCrudifyInitialized;
1157
+ /**
1158
+ * Try to return valid (non-expired) cached translations.
1159
+ * Returns null if cache is missing or expired.
1160
+ */
1161
+ private tryValidCache;
1162
+ /**
1163
+ * Return expired cache or critical bundle as fallback.
1164
+ */
1165
+ private getFallbackTranslations;
1166
+ /**
1167
+ * Process a successful API response: update cache and merge with URL translations.
1168
+ */
1169
+ private processApiResponse;
879
1170
  /**
880
1171
  * Fetch translations with cache strategy
881
1172
  * 1. Try cache (if valid and not changed)
@@ -954,11 +1245,12 @@ declare const translationService: TranslationService;
954
1245
  */
955
1246
  declare const CRITICAL_TRANSLATIONS: {
956
1247
  readonly es: {
957
- readonly 'base.actions.create': "Nuevo";
1248
+ readonly 'base.actions.create': "Crear";
958
1249
  readonly 'base.actions.delete': "Eliminar";
959
1250
  readonly 'base.actions.read': "Ver";
960
1251
  readonly 'base.actions.refresh': "Refrescar";
961
1252
  readonly 'base.actions.update': "Editar";
1253
+ readonly 'base.actions.logout': "Cerrar sesión";
962
1254
  readonly 'base.btn.back': "Volver";
963
1255
  readonly 'base.btn.cancel': "Cancelar";
964
1256
  readonly 'base.btn.hidePassword': "Ocultar contraseña";
@@ -967,6 +1259,7 @@ declare const CRITICAL_TRANSLATIONS: {
967
1259
  readonly 'base.fields.actions': "Acciones";
968
1260
  readonly 'base.fields.confirmPassword': "Confirmar contraseña";
969
1261
  readonly 'base.fields.createdAt': "Creado el";
1262
+ readonly 'base.fields._id': "ID";
970
1263
  readonly 'base.fields.email': "Correo electrónico";
971
1264
  readonly 'base.fields.lastName': "Apellido";
972
1265
  readonly 'base.fields.name': "Nombre";
@@ -1001,7 +1294,7 @@ declare const CRITICAL_TRANSLATIONS: {
1001
1294
  readonly 'base.loading.starting': "Iniciando aplicación...";
1002
1295
  readonly 'base.loading.themeSetup': "Generando tema...";
1003
1296
  readonly 'base.loading.validatingSession': "Validando sesión...";
1004
- readonly 'base.titles.create': "Nuevo {{moduleName}}";
1297
+ readonly 'base.titles.create': "Crear {{moduleName}}";
1005
1298
  readonly 'base.titles.read': "Ver {{moduleName}}";
1006
1299
  readonly 'base.titles.update': "Editar {{moduleName}}";
1007
1300
  readonly 'base.success.transaction': "La operación se ha completado con éxito.";
@@ -1131,6 +1424,7 @@ declare const CRITICAL_TRANSLATIONS: {
1131
1424
  readonly 'base.actions.read': "View";
1132
1425
  readonly 'base.actions.refresh': "Refresh";
1133
1426
  readonly 'base.actions.update': "Edit";
1427
+ readonly 'base.actions.logout': "Logout";
1134
1428
  readonly 'base.btn.back': "Back";
1135
1429
  readonly 'base.btn.cancel': "Cancel";
1136
1430
  readonly 'base.btn.hidePassword': "Hide password";
@@ -1139,6 +1433,7 @@ declare const CRITICAL_TRANSLATIONS: {
1139
1433
  readonly 'base.fields.actions': "Actions";
1140
1434
  readonly 'base.fields.confirmPassword': "Confirm password";
1141
1435
  readonly 'base.fields.createdAt': "Created at";
1436
+ readonly 'base.fields._id': "ID";
1142
1437
  readonly 'base.fields.email': "Email";
1143
1438
  readonly 'base.fields.lastName': "Last name";
1144
1439
  readonly 'base.fields.name': "Name";
@@ -1315,25 +1610,25 @@ declare const getCriticalTranslations: (language: string) => Record<string, stri
1315
1610
  * Automatically injects JWT token in each request and handles token refresh on 401 errors.
1316
1611
  */
1317
1612
  declare const crudifyAdmin: {
1318
- listModules: () => Promise<ApiResponse<IModule[]>>;
1319
- getModule: (moduleKey: string) => Promise<ApiResponse<IModule>>;
1320
- createModule: (moduleData: ModuleCreateInput) => Promise<ApiResponse<IModule>>;
1321
- editModule: (moduleKey: string, moduleData: ModuleEditInput) => Promise<ApiResponse<IModule>>;
1322
- deleteModule: (moduleKey: string) => Promise<ApiResponse>;
1323
- activateModule: (moduleKey: string) => Promise<ApiResponse<IModule>>;
1324
- deactivateModule: (moduleKey: string) => Promise<ApiResponse<IModule>>;
1325
- getModuleVersions: (moduleKey: string) => Promise<ApiResponse<any[]>>;
1326
- listActions: (filters?: ActionListFilters) => Promise<ApiResponse<IAction[]>>;
1327
- getAction: (actionKey: string) => Promise<ApiResponse<IAction>>;
1328
- createAction: (actionData: ActionCreateInput) => Promise<ApiResponse<IAction>>;
1329
- editAction: (actionKey: string, actionData: ActionEditInput) => Promise<ApiResponse<IAction>>;
1330
- deleteAction: (actionKey: string) => Promise<ApiResponse>;
1331
- activateAction: (actionKey: string) => Promise<ApiResponse<IAction>>;
1332
- deactivateAction: (actionKey: string) => Promise<ApiResponse<IAction>>;
1333
- getActionVersions: (actionKey: string) => Promise<ApiResponse<any[]>>;
1334
- getActionsByProfile: (profileId: string) => Promise<ApiResponse<IAction[]>>;
1335
- updateActionsProfiles: (data: UpdateActionsProfilesInput) => Promise<ApiResponse<UpdateActionsProfilesResponse>>;
1336
- calculatePermissions: (data: CalculatePermissionsInput) => Promise<ApiResponse<CalculatePermissionsResponse>>;
1613
+ listModules: () => Promise<AdminApiResponse<ModuleDefinition[]>>;
1614
+ getModule: (moduleKey: string) => Promise<AdminApiResponse<ModuleDefinition>>;
1615
+ createModule: (moduleData: ModuleCreateInput) => Promise<AdminApiResponse<ModuleDefinition>>;
1616
+ editModule: (moduleKey: string, moduleData: ModuleEditInput) => Promise<AdminApiResponse<ModuleDefinition>>;
1617
+ deleteModule: (moduleKey: string) => Promise<AdminApiResponse>;
1618
+ activateModule: (moduleKey: string) => Promise<AdminApiResponse<ModuleDefinition>>;
1619
+ deactivateModule: (moduleKey: string) => Promise<AdminApiResponse<ModuleDefinition>>;
1620
+ getModuleVersions: (moduleKey: string) => Promise<AdminApiResponse<ModuleVersionItem[]>>;
1621
+ listActions: (filters?: AdminActionFilters) => Promise<AdminApiResponse<ActionDefinition[]>>;
1622
+ getAction: (actionKey: string) => Promise<AdminApiResponse<ActionDefinition>>;
1623
+ createAction: (actionData: ActionCreateInput) => Promise<AdminApiResponse<ActionDefinition>>;
1624
+ editAction: (actionKey: string, actionData: ActionEditInput) => Promise<AdminApiResponse<ActionDefinition>>;
1625
+ deleteAction: (actionKey: string) => Promise<AdminApiResponse>;
1626
+ activateAction: (actionKey: string) => Promise<AdminApiResponse<ActionDefinition>>;
1627
+ deactivateAction: (actionKey: string) => Promise<AdminApiResponse<ActionDefinition>>;
1628
+ getActionVersions: (actionKey: string) => Promise<AdminApiResponse<ActionVersionItem[]>>;
1629
+ getActionsByProfile: (profileId: string) => Promise<AdminApiResponse<ActionDefinition[]>>;
1630
+ updateActionsProfiles: (data: UpdateActionsProfilesInput) => Promise<AdminApiResponse<UpdateActionsProfilesResponse>>;
1631
+ calculatePermissions: (data: CalculatePermissionsInput) => Promise<AdminApiResponse<CalculatePermissionsResponse>>;
1337
1632
  };
1338
1633
 
1339
- export { AuthRoute, type AuthRouteProps, CRITICAL_TRANSLATIONS, type CriticalTranslationKey, type CrossTabListener, type CrossTabMessage, type CrossTabMessageType, CrossTabSyncManager, CrudifyInitializationManager, CrudifyInitializer, type CrudifyInitializerConfig, type CrudifyInitializerProps, CrudifyLoginConfig, CrudifyProvider, CrudifyThemeProvider, type CrudifyThemeProviderProps, EvaluatedPasswordRule, type FetchTranslationsOptions, GuestRoute, type GuestRouteBehavior, type GuestRouteProps, type InitializationPriority, type InitializationRequest, type InitializationStatus, type LogContext, type LogLevel, PasswordRequirements, type PasswordRequirementsProps, PasswordRule, ProtectedRoute, type ProtectedRouteProps, SessionLoadingScreen, type SessionLoadingScreenProps, type SupportedLanguage, type TranslationResponse, TranslationService, type TranslationsContextValue, TranslationsProvider, type TranslationsProviderProps, allPasswordRulesPassed, clearCorruptedTokens, crossTabSync, crudifyAdmin, crudifyInitManager, evaluatePasswordRules, extractSafeRedirectFromUrl, getCriticalLanguages, getCriticalTranslations, hasCorruptedTokens, hasEncryptionKeyHash, hasStoredTokens, logger, shouldWaitForInitialization, translationService, useCrudify, useCrudifyInitializer, useTranslations, validateInternalRedirect, validateTrustedRedirect };
1634
+ export { AuthRoute, type AuthRouteProps, AutoGenerateConfig, type BoxScreenType, CRITICAL_TRANSLATIONS, type CriticalTranslationKey, type CrossTabListener, type CrossTabMessage, type CrossTabMessageType, CrossTabSyncManager, CrudiaAutoGenerate, type CrudiaAutoGenerateProps, CrudiaFileField, type CrudiaFileFieldDeletionHandlers, type CrudiaFileFieldProps, CrudiaMarkdownField, type CrudiaMarkdownFieldProps, CrudifyInitializationManager, CrudifyInitializer, type CrudifyInitializerConfig, type CrudifyInitializerProps, CrudifyLogin, type CrudifyLoginConfig, type CrudifyLoginProps, type CrudifyLoginTranslations, CrudifyProvider, CrudifyThemeProvider, type CrudifyThemeProviderProps, DEFAULT_PASSWORD_RULES, type EvaluatedPasswordRule, type FetchTranslationsOptions, GuestRoute, type GuestRouteBehavior, type GuestRouteProps, type InitializationPriority, type InitializationRequest, type InitializationStatus, LoginComponent, PasswordRequirements, type PasswordRequirementsProps, Policies, PolicyAction, ProtectedRoute, type ProtectedRouteProps, SessionLoadingScreen, type SessionLoadingScreenProps, SessionStatus, type SupportedLanguage, type TranslationResponse, TranslationService, type TranslationsContextValue, TranslationsProvider, type TranslationsProviderProps, type UserLoginData, UserProfileDisplay, allPasswordRulesPassed, clearCorruptedTokens, crossTabSync, crudifyAdmin, crudifyInitManager, evaluatePasswordRules, extractSafeRedirectFromUrl, getCriticalLanguages, getCriticalTranslations, hasCorruptedTokens, hasEncryptionKeyHash, hasStoredTokens, logger, shouldWaitForInitialization, translationService, useCrudify, useCrudifyInitializer, useTranslations, validateInternalRedirect, validateTrustedRedirect };