@nocios/crudify-ui 4.4.26 → 4.4.28

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.
@@ -462,6 +462,130 @@ interface UseUserProfileReturn {
462
462
  }
463
463
  declare const useUserProfile: (options?: UseUserProfileOptions) => UseUserProfileReturn;
464
464
 
465
+ /**
466
+ * Estado de un archivo individual
467
+ */
468
+ type FileStatus = "pending" | "uploading" | "completed" | "error" | "removing";
469
+ /**
470
+ * Representa un archivo en el sistema
471
+ */
472
+ interface FileItem {
473
+ /** ID único del archivo (generado o desde servidor) */
474
+ id: string;
475
+ /** Nombre original del archivo */
476
+ name: string;
477
+ /** Tamaño en bytes */
478
+ size: number;
479
+ /** Content type MIME */
480
+ contentType: string;
481
+ /** Estado actual del archivo */
482
+ status: FileStatus;
483
+ /** Progreso de upload (0-100) */
484
+ progress: number;
485
+ /**
486
+ * Ruta relativa del archivo (sin subscriberKey)
487
+ * El subscriberKey se agrega automáticamente en el backend
488
+ */
489
+ filePath?: string;
490
+ /** URL pública para preview (si existe) */
491
+ previewUrl?: string;
492
+ /** Mensaje de error si falló */
493
+ errorMessage?: string;
494
+ /** Timestamp de creación */
495
+ createdAt: number;
496
+ /** Archivo original (solo durante upload) */
497
+ file?: File;
498
+ }
499
+ /**
500
+ * Configuración del hook
501
+ */
502
+ interface UseFileUploadOptions {
503
+ /** Tipos MIME permitidos (ej: ["image/png", "image/jpeg", "application/pdf"]) */
504
+ acceptedTypes?: string[];
505
+ /** Tamaño máximo por archivo en bytes (default: 10MB) */
506
+ maxFileSize?: number;
507
+ /** Número máximo de archivos (undefined = sin límite) */
508
+ maxFiles?: number;
509
+ /** Número mínimo de archivos requeridos (default: 0) */
510
+ minFiles?: number;
511
+ /** Callback cuando se completa un upload exitoso */
512
+ onUploadComplete?: (file: FileItem) => void;
513
+ /** Callback cuando falla un upload */
514
+ onUploadError?: (file: FileItem, error: string) => void;
515
+ /** Callback cuando se elimina un archivo */
516
+ onFileRemoved?: (file: FileItem) => void;
517
+ /** Callback cuando cambia la lista de archivos */
518
+ onFilesChange?: (files: FileItem[]) => void;
519
+ }
520
+ /**
521
+ * Resultado del hook
522
+ */
523
+ interface UseFileUploadReturn {
524
+ /** Lista de archivos actuales */
525
+ files: FileItem[];
526
+ /** Si hay uploads en progreso */
527
+ isUploading: boolean;
528
+ /** Número de uploads pendientes */
529
+ pendingCount: number;
530
+ /** Agregar archivos (dispara upload automático) */
531
+ addFiles: (files: FileList | File[]) => Promise<void>;
532
+ /** Eliminar un archivo (soft delete en S3) */
533
+ removeFile: (fileId: string) => Promise<boolean>;
534
+ /** Limpiar todos los archivos */
535
+ clearFiles: () => void;
536
+ /** Reintentar upload de un archivo fallido */
537
+ retryUpload: (fileId: string) => Promise<void>;
538
+ /** Validar si cumple requisitos mínimos */
539
+ isValid: boolean;
540
+ /** Mensaje de error de validación */
541
+ validationError: string | null;
542
+ /** Esperar a que todos los uploads terminen */
543
+ waitForUploads: () => Promise<void>;
544
+ /**
545
+ * Rutas de archivos completados (para guardar en formulario)
546
+ * Son rutas relativas sin subscriberKey - el backend lo agrega automáticamente
547
+ */
548
+ completedFilePaths: string[];
549
+ /** Inicializar con archivos existentes (para edición) */
550
+ initializeFiles: (existingFiles: Array<{
551
+ filePath: string;
552
+ name: string;
553
+ size?: number;
554
+ contentType?: string;
555
+ }>) => void;
556
+ }
557
+ /**
558
+ * Hook para manejo completo de archivos con upload a S3
559
+ *
560
+ * @example
561
+ * ```tsx
562
+ * const {
563
+ * files,
564
+ * addFiles,
565
+ * removeFile,
566
+ * isUploading,
567
+ * isValid,
568
+ * completedS3Keys
569
+ * } = useFileUpload({
570
+ * acceptedTypes: ["image/png", "image/jpeg", "application/pdf"],
571
+ * maxFileSize: 5 * 1024 * 1024, // 5MB
572
+ * maxFiles: 3,
573
+ * minFiles: 1
574
+ * });
575
+ *
576
+ * // En el submit del formulario
577
+ * const handleSubmit = async () => {
578
+ * await waitForUploads(); // Esperar uploads pendientes
579
+ * if (!isValid) return;
580
+ *
581
+ * await crudify.createItem("documents", {
582
+ * files: completedS3Keys
583
+ * });
584
+ * };
585
+ * ```
586
+ */
587
+ declare const useFileUpload: (options?: UseFileUploadOptions) => UseFileUploadReturn;
588
+
465
589
  interface CrudifyWithNotificationsOptions {
466
590
  showSuccessNotifications?: boolean;
467
591
  showErrorNotifications?: boolean;
@@ -484,4 +608,4 @@ declare const useCrudifyWithNotifications: (options?: CrudifyWithNotificationsOp
484
608
  shouldShowNotification: (response: CrudifyResponse) => boolean;
485
609
  };
486
610
 
487
- export { type LoginResult as L, SessionManager as S, type TokenData as T, type UseSessionOptions as U, type SessionConfig as a, TokenStorage as b, type StorageType as c, type SessionState as d, useUserData as e, type UseUserDataReturn as f, type UseUserDataOptions as g, type UserData as h, useAuth as i, type UseAuthReturn as j, useData as k, type UseDataReturn as l, useUserProfile as m, useCrudifyWithNotifications as n, useSession as u };
611
+ export { type FileItem as F, type LoginResult as L, SessionManager as S, type TokenData as T, type UseSessionOptions as U, type SessionConfig as a, TokenStorage as b, type StorageType as c, type SessionState as d, useUserData as e, type UseUserDataReturn as f, type UseUserDataOptions as g, type UserData as h, useAuth as i, type UseAuthReturn as j, useData as k, type UseDataReturn as l, useUserProfile as m, useFileUpload as n, type UseFileUploadOptions as o, type UseFileUploadReturn as p, type FileStatus as q, useCrudifyWithNotifications as r, useSession as u };
@@ -462,6 +462,130 @@ interface UseUserProfileReturn {
462
462
  }
463
463
  declare const useUserProfile: (options?: UseUserProfileOptions) => UseUserProfileReturn;
464
464
 
465
+ /**
466
+ * Estado de un archivo individual
467
+ */
468
+ type FileStatus = "pending" | "uploading" | "completed" | "error" | "removing";
469
+ /**
470
+ * Representa un archivo en el sistema
471
+ */
472
+ interface FileItem {
473
+ /** ID único del archivo (generado o desde servidor) */
474
+ id: string;
475
+ /** Nombre original del archivo */
476
+ name: string;
477
+ /** Tamaño en bytes */
478
+ size: number;
479
+ /** Content type MIME */
480
+ contentType: string;
481
+ /** Estado actual del archivo */
482
+ status: FileStatus;
483
+ /** Progreso de upload (0-100) */
484
+ progress: number;
485
+ /**
486
+ * Ruta relativa del archivo (sin subscriberKey)
487
+ * El subscriberKey se agrega automáticamente en el backend
488
+ */
489
+ filePath?: string;
490
+ /** URL pública para preview (si existe) */
491
+ previewUrl?: string;
492
+ /** Mensaje de error si falló */
493
+ errorMessage?: string;
494
+ /** Timestamp de creación */
495
+ createdAt: number;
496
+ /** Archivo original (solo durante upload) */
497
+ file?: File;
498
+ }
499
+ /**
500
+ * Configuración del hook
501
+ */
502
+ interface UseFileUploadOptions {
503
+ /** Tipos MIME permitidos (ej: ["image/png", "image/jpeg", "application/pdf"]) */
504
+ acceptedTypes?: string[];
505
+ /** Tamaño máximo por archivo en bytes (default: 10MB) */
506
+ maxFileSize?: number;
507
+ /** Número máximo de archivos (undefined = sin límite) */
508
+ maxFiles?: number;
509
+ /** Número mínimo de archivos requeridos (default: 0) */
510
+ minFiles?: number;
511
+ /** Callback cuando se completa un upload exitoso */
512
+ onUploadComplete?: (file: FileItem) => void;
513
+ /** Callback cuando falla un upload */
514
+ onUploadError?: (file: FileItem, error: string) => void;
515
+ /** Callback cuando se elimina un archivo */
516
+ onFileRemoved?: (file: FileItem) => void;
517
+ /** Callback cuando cambia la lista de archivos */
518
+ onFilesChange?: (files: FileItem[]) => void;
519
+ }
520
+ /**
521
+ * Resultado del hook
522
+ */
523
+ interface UseFileUploadReturn {
524
+ /** Lista de archivos actuales */
525
+ files: FileItem[];
526
+ /** Si hay uploads en progreso */
527
+ isUploading: boolean;
528
+ /** Número de uploads pendientes */
529
+ pendingCount: number;
530
+ /** Agregar archivos (dispara upload automático) */
531
+ addFiles: (files: FileList | File[]) => Promise<void>;
532
+ /** Eliminar un archivo (soft delete en S3) */
533
+ removeFile: (fileId: string) => Promise<boolean>;
534
+ /** Limpiar todos los archivos */
535
+ clearFiles: () => void;
536
+ /** Reintentar upload de un archivo fallido */
537
+ retryUpload: (fileId: string) => Promise<void>;
538
+ /** Validar si cumple requisitos mínimos */
539
+ isValid: boolean;
540
+ /** Mensaje de error de validación */
541
+ validationError: string | null;
542
+ /** Esperar a que todos los uploads terminen */
543
+ waitForUploads: () => Promise<void>;
544
+ /**
545
+ * Rutas de archivos completados (para guardar en formulario)
546
+ * Son rutas relativas sin subscriberKey - el backend lo agrega automáticamente
547
+ */
548
+ completedFilePaths: string[];
549
+ /** Inicializar con archivos existentes (para edición) */
550
+ initializeFiles: (existingFiles: Array<{
551
+ filePath: string;
552
+ name: string;
553
+ size?: number;
554
+ contentType?: string;
555
+ }>) => void;
556
+ }
557
+ /**
558
+ * Hook para manejo completo de archivos con upload a S3
559
+ *
560
+ * @example
561
+ * ```tsx
562
+ * const {
563
+ * files,
564
+ * addFiles,
565
+ * removeFile,
566
+ * isUploading,
567
+ * isValid,
568
+ * completedS3Keys
569
+ * } = useFileUpload({
570
+ * acceptedTypes: ["image/png", "image/jpeg", "application/pdf"],
571
+ * maxFileSize: 5 * 1024 * 1024, // 5MB
572
+ * maxFiles: 3,
573
+ * minFiles: 1
574
+ * });
575
+ *
576
+ * // En el submit del formulario
577
+ * const handleSubmit = async () => {
578
+ * await waitForUploads(); // Esperar uploads pendientes
579
+ * if (!isValid) return;
580
+ *
581
+ * await crudify.createItem("documents", {
582
+ * files: completedS3Keys
583
+ * });
584
+ * };
585
+ * ```
586
+ */
587
+ declare const useFileUpload: (options?: UseFileUploadOptions) => UseFileUploadReturn;
588
+
465
589
  interface CrudifyWithNotificationsOptions {
466
590
  showSuccessNotifications?: boolean;
467
591
  showErrorNotifications?: boolean;
@@ -484,4 +608,4 @@ declare const useCrudifyWithNotifications: (options?: CrudifyWithNotificationsOp
484
608
  shouldShowNotification: (response: CrudifyResponse) => boolean;
485
609
  };
486
610
 
487
- export { type LoginResult as L, SessionManager as S, type TokenData as T, type UseSessionOptions as U, type SessionConfig as a, TokenStorage as b, type StorageType as c, type SessionState as d, useUserData as e, type UseUserDataReturn as f, type UseUserDataOptions as g, type UserData as h, useAuth as i, type UseAuthReturn as j, useData as k, type UseDataReturn as l, useUserProfile as m, useCrudifyWithNotifications as n, useSession as u };
611
+ export { type FileItem as F, type LoginResult as L, SessionManager as S, type TokenData as T, type UseSessionOptions as U, type SessionConfig as a, TokenStorage as b, type StorageType as c, type SessionState as d, useUserData as e, type UseUserDataReturn as f, type UseUserDataOptions as g, type UserData as h, useAuth as i, type UseAuthReturn as j, useData as k, type UseDataReturn as l, useUserProfile as m, useFileUpload as n, type UseFileUploadOptions as o, type UseFileUploadReturn as p, type FileStatus as q, useCrudifyWithNotifications as r, useSession as u };
package/dist/index.d.mts CHANGED
@@ -1,12 +1,12 @@
1
1
  import crudify__default from '@nocios/crudify-browser';
2
2
  export * from '@nocios/crudify-browser';
3
3
  export { default as crudify } from '@nocios/crudify-browser';
4
- import { b as CrudifyLoginConfig } from './CrudiaAutoGenerate-CORiNekq.mjs';
5
- export { B as BoxScreenType, a as CrudiaAutoGenerate, g as CrudiaAutoGenerateProps, C as CrudifyLogin, c as CrudifyLoginProps, d as CrudifyLoginTranslations, L as LoginComponent, h as POLICY_ACTIONS, i as PREFERRED_POLICY_ORDER, P as Policies, f as PolicyAction, S as SessionStatus, e as UserLoginData, U as UserProfileDisplay } from './CrudiaAutoGenerate-CORiNekq.mjs';
4
+ import { c as CrudifyLoginConfig } from './CrudiaFileField-wOx3H54i.mjs';
5
+ export { B as BoxScreenType, a as CrudiaAutoGenerate, h as CrudiaAutoGenerateProps, b as CrudiaFileField, i as CrudiaFileFieldProps, C as CrudifyLogin, d as CrudifyLoginProps, e as CrudifyLoginTranslations, L as LoginComponent, j as POLICY_ACTIONS, k as PREFERRED_POLICY_ORDER, P as Policies, g as PolicyAction, S as SessionStatus, f as UserLoginData, U as UserProfileDisplay } from './CrudiaFileField-wOx3H54i.mjs';
6
6
  import React, { ReactNode } from 'react';
7
7
  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';
8
- import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-Bjn8TCuc.mjs';
9
- 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-Bjn8TCuc.mjs';
8
+ import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-B0DVORoA.mjs';
9
+ export { F as FileItem, q as FileStatus, a as SessionConfig, S as SessionManager, d as SessionState, c as StorageType, b as TokenStorage, j as UseAuthReturn, l as UseDataReturn, o as UseFileUploadOptions, p as UseFileUploadReturn, g as UseUserDataOptions, f as UseUserDataReturn, h as UserData, i as useAuth, r as useCrudifyWithNotifications, k as useData, n as useFileUpload, u as useSession, e as useUserData, m as useUserProfile } from './index-B0DVORoA.mjs';
10
10
  import * as react_jsx_runtime from 'react/jsx-runtime';
11
11
  import { ThemeOptions } from '@mui/material';
12
12
  export { A as AutoGenerateConfig, G as GlobalNotificationProvider, a as GlobalNotificationProviderProps, N as Notification, b as NotificationSeverity, d as UseAutoGenerateOptions, U as UseAutoGenerateReturn, c as useAutoGenerate, u as useGlobalNotification } from './GlobalNotificationProvider-Zq18OkpI.mjs';
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import crudify__default from '@nocios/crudify-browser';
2
2
  export * from '@nocios/crudify-browser';
3
3
  export { default as crudify } from '@nocios/crudify-browser';
4
- import { b as CrudifyLoginConfig } from './CrudiaAutoGenerate-BMWqk_Nx.js';
5
- export { B as BoxScreenType, a as CrudiaAutoGenerate, g as CrudiaAutoGenerateProps, C as CrudifyLogin, c as CrudifyLoginProps, d as CrudifyLoginTranslations, L as LoginComponent, h as POLICY_ACTIONS, i as PREFERRED_POLICY_ORDER, P as Policies, f as PolicyAction, S as SessionStatus, e as UserLoginData, U as UserProfileDisplay } from './CrudiaAutoGenerate-BMWqk_Nx.js';
4
+ import { c as CrudifyLoginConfig } from './CrudiaFileField-892NRdL9.js';
5
+ export { B as BoxScreenType, a as CrudiaAutoGenerate, h as CrudiaAutoGenerateProps, b as CrudiaFileField, i as CrudiaFileFieldProps, C as CrudifyLogin, d as CrudifyLoginProps, e as CrudifyLoginTranslations, L as LoginComponent, j as POLICY_ACTIONS, k as PREFERRED_POLICY_ORDER, P as Policies, g as PolicyAction, S as SessionStatus, f as UserLoginData, U as UserProfileDisplay } from './CrudiaFileField-892NRdL9.js';
6
6
  import React, { ReactNode } from 'react';
7
7
  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';
8
- import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-BbvxA2Se.js';
9
- 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-BbvxA2Se.js';
8
+ import { U as UseSessionOptions, T as TokenData, L as LoginResult } from './index-DP2vLBQU.js';
9
+ export { F as FileItem, q as FileStatus, a as SessionConfig, S as SessionManager, d as SessionState, c as StorageType, b as TokenStorage, j as UseAuthReturn, l as UseDataReturn, o as UseFileUploadOptions, p as UseFileUploadReturn, g as UseUserDataOptions, f as UseUserDataReturn, h as UserData, i as useAuth, r as useCrudifyWithNotifications, k as useData, n as useFileUpload, u as useSession, e as useUserData, m as useUserProfile } from './index-DP2vLBQU.js';
10
10
  import * as react_jsx_runtime from 'react/jsx-runtime';
11
11
  import { ThemeOptions } from '@mui/material';
12
12
  export { A as AutoGenerateConfig, G as GlobalNotificationProvider, a as GlobalNotificationProviderProps, N as Notification, b as NotificationSeverity, d as UseAutoGenerateOptions, U as UseAutoGenerateReturn, c as useAutoGenerate, u as useGlobalNotification } from './GlobalNotificationProvider-Zq18OkpI.js';
package/dist/index.js CHANGED
@@ -1,6 +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]}); }); } 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 _chunkOLTLD4XBjs = require('./chunk-OLTLD4XB.js');var _chunkZWSHZHIHjs = require('./chunk-ZWSHZHIH.js');var _chunkWUOGD7AZjs = require('./chunk-WUOGD7AZ.js');var _chunkNNY4A73Vjs = require('./chunk-NNY4A73V.js');var _chunkYIIUEOXCjs = require('./chunk-YIIUEOXC.js');var _chunkFC7HOMNQjs = require('./chunk-FC7HOMNQ.js');var _crudifybrowser = require('@nocios/crudify-browser'); var _crudifybrowser2 = _interopRequireDefault(_crudifybrowser); _createStarExport(_crudifybrowser);var _react = require('react');var _material = require('@mui/material');var _jsxruntime = require('react/jsx-runtime');var He=(e={})=>{try{let i=_chunkFC7HOMNQjs.a.call(void 0, "theme");if(i){let t=JSON.parse(decodeURIComponent(i));return{...e,...t}}}catch(i){console.warn("Error parsing theme from cookie:",i)}return e};function De({children:e,defaultTheme:i={},disableCssBaseline:t=!1}){let r=_react.useMemo.call(void 0, ()=>{let n=He(i);return _material.createTheme.call(void 0, n)},[i]);return _jsxruntime.jsxs.call(void 0, _material.ThemeProvider,{theme:r,children:[!t&&_jsxruntime.jsx.call(void 0, _material.CssBaseline,{}),e]})}var _reactrouterdom = require('react-router-dom');var Fe={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},$e=()=>_jsxruntime.jsx.call(void 0, "style",{children:`
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 _chunkQXYEAMMDjs = require('./chunk-QXYEAMMD.js');var _chunkKXBLNQ5Qjs = require('./chunk-KXBLNQ5Q.js');var _chunkIXDCGL4Kjs = require('./chunk-IXDCGL4K.js');var _chunkNNY4A73Vjs = require('./chunk-NNY4A73V.js');var _chunkYIIUEOXCjs = require('./chunk-YIIUEOXC.js');var _chunkFC7HOMNQjs = require('./chunk-FC7HOMNQ.js');var _crudifybrowser = require('@nocios/crudify-browser'); var _crudifybrowser2 = _interopRequireDefault(_crudifybrowser); _createStarExport(_crudifybrowser);var _react = require('react');var _material = require('@mui/material');var _jsxruntime = require('react/jsx-runtime');var Fe=(e={})=>{try{let i=_chunkFC7HOMNQjs.a.call(void 0, "theme");if(i){let t=JSON.parse(decodeURIComponent(i));return{...e,...t}}}catch(i){console.warn("Error parsing theme from cookie:",i)}return e};function Ge({children:e,defaultTheme:i={},disableCssBaseline:t=!1}){let r=_react.useMemo.call(void 0, ()=>{let n=Fe(i);return _material.createTheme.call(void 0, n)},[i]);return _jsxruntime.jsxs.call(void 0, _material.ThemeProvider,{theme:r,children:[!t&&_jsxruntime.jsx.call(void 0, _material.CssBaseline,{}),e]})}var _reactrouterdom = require('react-router-dom');var Be={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},_e=()=>_jsxruntime.jsx.call(void 0, "style",{children:`
2
2
  @keyframes spin {
3
3
  0% { transform: rotate(0deg); }
4
4
  100% { transform: rotate(360deg); }
5
5
  }
6
- `});function v({stage:e="loading",message:i}){let r=i||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, $e,{}),_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:Fe}),_jsxruntime.jsx.call(void 0, "p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:r})]})]})}var _e=/^[a-zA-Z0-9\-_./\?=&%#]+$/,Ze=[/^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,i="/")=>{if(!e||typeof e!="string")return i;let t=e.trim();if(!t)return i;if(!t.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),i;if(!_e.test(t))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),i;let r=t.toLowerCase();for(let o of Ze)if(o.test(r))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),i;let n=t.split("?")[0].split("/").filter(Boolean);if(n.length===0)return t;for(let o of n)if(o===".."||o.includes(":")||o.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",o),i;return t},T= exports.extractSafeRedirectFromUrl =(e,i="/")=>{try{let r=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!r)return i;let n=decodeURIComponent(r);return P(n,i)}catch(t){return console.warn("\u{1F6A8} Error parsing redirect parameter:",t),i}};function k({children:e,loadingComponent:i,loginPath:t="/login"}){let{isAuthenticated:r,isLoading:n,isInitialized:o,tokens:s,error:c}=_chunkWUOGD7AZjs.j.call(void 0, ),u=_reactrouterdom.useLocation.call(void 0, );if(!o||n)return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:i||_jsxruntime.jsx.call(void 0, v,{stage:"validating-session"})});let d=r&&_optionalChain([s, 'optionalAccess', _2 => _2.accessToken])&&s.accessToken.length>0;if(c||!r||!d){s&&(!s.accessToken||s.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let m=u.pathname+u.search,I=P(m),h=encodeURIComponent(I);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:`${t}?redirect=${h}`,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}function O({children:e,redirectTo:i="/"}){let{isAuthenticated:t}=_chunkWUOGD7AZjs.j.call(void 0, ),r=_reactrouterdom.useLocation.call(void 0, );if(t){let n=new URLSearchParams(r.search),o=T(n,i);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:o,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}var C=class e{constructor(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null};this.initializationPromise=null;this.highPriorityInitializerPresent=!1;this.waitingForHighPriority=new Set;this.HIGH_PRIORITY_WAIT_TIMEOUT=100}static getInstance(){return e.instance||(e.instance=new e),e.instance}registerHighPriorityInitializer(){this.highPriorityInitializerPresent=!0}isHighPriorityInitializerPresent(){return this.highPriorityInitializerPresent}getState(){return{...this.state}}async initialize(i){let{priority:t,publicApiKey:r,env:n,enableLogging:o,requestedBy:s}=i;if(this.state.status==="INITIALIZED"){this.state.publicApiKey!==r&&console.warn(`[CrudifyInitialization] ${s} attempted to initialize with different key. Already initialized with key: ${_optionalChain([this, 'access', _3 => _3.state, 'access', _4 => _4.publicApiKey, 'optionalAccess', _5 => _5.slice, 'call', _6 => _6(0,10)])}... by ${this.state.initializedBy}`);return}if(this.initializationPromise)return o&&console.log(`[CrudifyInitialization] ${s} waiting for ongoing initialization...`),this.initializationPromise;if(t==="LOW"&&this.highPriorityInitializerPresent&&this.state.status==="UNINITIALIZED"){if(o&&console.log(`[CrudifyInitialization] ${s} (LOW priority) waiting for HIGH priority initializer...`),this.waitingForHighPriority.add(s),await this.waitForHighPriorityOrTimeout(o),this.waitingForHighPriority.delete(s),this.getState().status==="INITIALIZED"){o&&console.log(`[CrudifyInitialization] ${s} found initialization completed by HIGH priority`);return}o&&console.warn(`[CrudifyInitialization] ${s} timeout waiting for HIGH priority, initializing with LOW priority`)}t==="HIGH"&&this.state.status==="INITIALIZING"&&this.state.priority==="LOW"&&(console.warn(`[CrudifyInitialization] HIGH priority request from ${s} interrupting LOW priority initialization by ${this.state.initializedBy}`),this.state.status="UNINITIALIZED",this.initializationPromise=null),o&&console.log(`[CrudifyInitialization] ${s} starting initialization (${t} priority)...`),this.state.status="INITIALIZING",this.state.priority=t,this.state.initializedBy=s,this.initializationPromise=this.performInitialization(r,n,o);try{await this.initializationPromise,this.state.status="INITIALIZED",this.state.publicApiKey=r,this.state.env=n,this.state.error=null,o&&console.log(`[CrudifyInitialization] \u2705 Successfully initialized by ${s} (${t} priority)`)}catch(c){throw this.state.status="ERROR",this.state.error=c instanceof Error?c:new Error(String(c)),this.initializationPromise=null,console.error(`[CrudifyInitialization] \u274C Initialization failed for ${s}:`,c),c}}async waitForHighPriorityOrTimeout(i){return new Promise(t=>{let n=0,o=setInterval(()=>{if(n+=10,this.state.status==="INITIALIZED"&&this.state.priority==="HIGH"){clearInterval(o),t();return}if(this.state.status==="INITIALIZING"&&this.state.priority==="HIGH"){n=0;return}n>=this.HIGH_PRIORITY_WAIT_TIMEOUT&&(clearInterval(o),i&&console.log(`[CrudifyInitialization] Timeout waiting for HIGH priority (${this.HIGH_PRIORITY_WAIT_TIMEOUT}ms)`),t())},10)})}async performInitialization(i,t,r){let n=_crudifybrowser2.default.getTokenData();if(n&&n.endpoint){r&&console.log("[CrudifyInitialization] SDK already initialized externally");return}_crudifybrowser2.default.config(t);let o=r?"debug":"none",s=await _crudifybrowser2.default.init(i,o);if(s.success===!1)throw new Error(`Crudify initialization failed: ${JSON.stringify(s.errors||"Unknown error")}`)}reset(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null},this.initializationPromise=null,this.highPriorityInitializerPresent=!1,this.waitingForHighPriority.clear()}isInitialized(){return this.state.status==="INITIALIZED"}getDiagnostics(){return{...this.state,waitingCount:this.waitingForHighPriority.size,waitingComponents:Array.from(this.waitingForHighPriority),hasActivePromise:this.initializationPromise!==null}}},x= exports.crudifyInitManager =C.getInstance();var G=_react.createContext.call(void 0, void 0),ei= exports.CrudifyInitializer =({config:e,children:i,fallback:t=null,onInitialized:r,onError:n})=>{let[o,s]=_react.useState.call(void 0, !1),[c,u]=_react.useState.call(void 0, !1),[d,m]=_react.useState.call(void 0, null),I=_react.useRef.call(void 0, !1),h=_react.useRef.call(void 0, !1);_react.useEffect.call(void 0, ()=>{I.current||(x.registerHighPriorityInitializer(),I.current=!0),h.current||(h.current=!0,(async()=>{u(!0),m(null);try{let p=_chunkFC7HOMNQjs.b.call(void 0, {publicApiKey:_optionalChain([e, 'optionalAccess', _7 => _7.publicApiKey]),env:_optionalChain([e, 'optionalAccess', _8 => _8.env]),enableDebug:_optionalChain([e, 'optionalAccess', _9 => _9.enableLogging])});if(!p.publicApiKey)throw new Error("Crudify configuration missing. Please provide publicApiKey via props or ensure cookies are set by Lambda.");await x.initialize({priority:"HIGH",publicApiKey:p.publicApiKey,env:p.env||"prod",enableLogging:_optionalChain([e, 'optionalAccess', _10 => _10.enableLogging]),requestedBy:"CrudifyInitializer"}),s(!0),u(!1),r&&r()}catch(p){let E=p instanceof Error?p:new Error(String(p));m(E),u(!1),n&&n(E)}})())},[_optionalChain([e, 'optionalAccess', _11 => _11.publicApiKey]),_optionalChain([e, 'optionalAccess', _12 => _12.env]),_optionalChain([e, 'optionalAccess', _13 => _13.enableLogging]),r,n]);let F={isInitialized:o,isInitializing:c,error:d};return c&&t?_jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:t}):(d&&console.error("[CrudifyInitializer] Initialization failed:",d),_jsxruntime.jsx.call(void 0, G.Provider,{value:F,children:i}))},ii= exports.useCrudifyInitializer =()=>{let e=_react.useContext.call(void 0, G);if(!e)throw new Error("useCrudifyInitializer must be used within CrudifyInitializer");return e};var _crudifyadmin = require('@nocios/crudify-admin'); var _crudifyadmin2 = _interopRequireDefault(_crudifyadmin);var K=!1,g=null;async function ri(){let i=_chunkWUOGD7AZjs.e.getInstance().getTokenInfo(),t=_optionalChain([i, 'optionalAccess', _14 => _14.apiEndpointAdmin]),r=_optionalChain([i, 'optionalAccess', _15 => _15.apiKeyEndpointAdmin]);return t&&r?{apiUrl:t,apiKey:r}:_chunkWUOGD7AZjs.a.waitForCredentials()}async function oi(){if(!K)return g||(g=(async()=>{try{let e=_chunkWUOGD7AZjs.e.getInstance(),{apiUrl:i,apiKey:t}=await ri();_crudifyadmin2.default.init({url:i,apiKey:t,getAdditionalHeaders:()=>{let r=e.getTokenInfo();return _optionalChain([r, 'optionalAccess', _16 => _16.crudifyTokens, 'optionalAccess', _17 => _17.accessToken])?{Authorization:`Bearer ${r.crudifyTokens.accessToken}`}:{}}}),K=!0}catch(e){throw g=null,console.error("[crudifyAdminWrapper] Initialization failed:",e),e}})(),g)}async function l(e){try{await oi();let i=await e();return!i.success&&_optionalChain([i, 'access', _18 => _18.errors, 'optionalAccess', _19 => _19.includes, 'call', _20 => _20("401")])?await _chunkWUOGD7AZjs.e.getInstance().refreshTokens()?await e():(console.error("[crudifyAdmin] Token refresh failed"),typeof window<"u"&&(window.location.href="/login"),i):i}catch(i){return console.error("[crudifyAdmin] Operation error:",i),{success:!1,errors:i instanceof Error?i.message:"Unknown error"}}}var ni={listModules:()=>l(()=>_crudifyadmin2.default.listModules()),getModule:e=>l(()=>_crudifyadmin2.default.getModule(e)),createModule:e=>l(()=>_crudifyadmin2.default.createModule(e)),editModule:(e,i)=>l(()=>_crudifyadmin2.default.editModule(e,i)),deleteModule:e=>l(()=>_crudifyadmin2.default.deleteModule(e)),activateModule:e=>l(()=>_crudifyadmin2.default.activateModule(e)),deactivateModule:e=>l(()=>_crudifyadmin2.default.deactivateModule(e)),getModuleVersions:e=>l(()=>_crudifyadmin2.default.getModuleVersions(e)),listActions:e=>l(()=>_crudifyadmin2.default.listActions(e)),getAction:e=>l(()=>_crudifyadmin2.default.getAction(e)),createAction:e=>l(()=>_crudifyadmin2.default.createAction(e)),editAction:(e,i)=>l(()=>_crudifyadmin2.default.editAction(e,i)),deleteAction:e=>l(()=>_crudifyadmin2.default.deleteAction(e)),activateAction:e=>l(()=>_crudifyadmin2.default.activateAction(e)),deactivateAction:e=>l(()=>_crudifyadmin2.default.deactivateAction(e)),getActionVersions:e=>l(()=>_crudifyadmin2.default.getActionVersions(e)),getActionsByProfile:e=>l(()=>_crudifyadmin2.default.getActionsByProfile(e)),updateActionsProfiles:e=>l(()=>_crudifyadmin2.default.updateActionsProfiles(e))};exports.AuthRoute = O; exports.CRITICAL_TRANSLATIONS = _chunkOLTLD4XBjs.a; exports.CrudiaAutoGenerate = _chunkOLTLD4XBjs.o; exports.CrudifyInitializationManager = C; exports.CrudifyInitializer = ei; exports.CrudifyLogin = _chunkOLTLD4XBjs.h; exports.CrudifyProvider = _chunkWUOGD7AZjs.b; exports.CrudifyThemeProvider = De; exports.ERROR_CODES = _chunkYIIUEOXCjs.a; exports.ERROR_SEVERITY_MAP = _chunkYIIUEOXCjs.b; exports.GlobalNotificationProvider = _chunkWUOGD7AZjs.g; exports.LoginComponent = _chunkOLTLD4XBjs.m; exports.POLICY_ACTIONS = _chunkOLTLD4XBjs.j; exports.PREFERRED_POLICY_ORDER = _chunkOLTLD4XBjs.k; exports.Policies = _chunkOLTLD4XBjs.l; exports.ProtectedRoute = k; exports.SessionDebugInfo = _chunkWUOGD7AZjs.k; exports.SessionLoadingScreen = v; exports.SessionManager = _chunkWUOGD7AZjs.e; exports.SessionProvider = _chunkWUOGD7AZjs.i; exports.SessionStatus = _chunkOLTLD4XBjs.n; exports.TokenStorage = _chunkWUOGD7AZjs.d; exports.TranslationService = _chunkOLTLD4XBjs.d; exports.TranslationsProvider = _chunkOLTLD4XBjs.f; exports.UserProfileDisplay = _chunkOLTLD4XBjs.i; exports.createErrorTranslator = _chunkFC7HOMNQjs.g; exports.crudify = _crudifybrowser2.default; exports.crudifyAdmin = ni; exports.crudifyInitManager = x; exports.decodeJwtSafely = _chunkFC7HOMNQjs.j; exports.extractSafeRedirectFromUrl = T; exports.getCookie = _chunkFC7HOMNQjs.a; exports.getCriticalLanguages = _chunkOLTLD4XBjs.b; exports.getCriticalTranslations = _chunkOLTLD4XBjs.c; exports.getCurrentUserEmail = _chunkFC7HOMNQjs.k; exports.getErrorMessage = _chunkYIIUEOXCjs.e; exports.handleCrudifyError = _chunkYIIUEOXCjs.g; exports.isTokenExpired = _chunkFC7HOMNQjs.l; exports.parseApiError = _chunkYIIUEOXCjs.c; exports.parseJavaScriptError = _chunkYIIUEOXCjs.f; exports.parseTransactionError = _chunkYIIUEOXCjs.d; exports.secureLocalStorage = _chunkNNY4A73Vjs.b; exports.secureSessionStorage = _chunkNNY4A73Vjs.a; exports.translateError = _chunkFC7HOMNQjs.f; exports.translateErrorCode = _chunkFC7HOMNQjs.d; exports.translateErrorCodes = _chunkFC7HOMNQjs.e; exports.translationService = _chunkOLTLD4XBjs.e; exports.useAuth = _chunkZWSHZHIHjs.b; exports.useAutoGenerate = _chunkWUOGD7AZjs.m; exports.useCrudify = _chunkWUOGD7AZjs.c; exports.useCrudifyInitializer = ii; exports.useCrudifyWithNotifications = _chunkZWSHZHIHjs.d; exports.useData = _chunkZWSHZHIHjs.c; exports.useGlobalNotification = _chunkWUOGD7AZjs.h; exports.useSession = _chunkWUOGD7AZjs.f; exports.useSessionContext = _chunkWUOGD7AZjs.j; exports.useTranslations = _chunkOLTLD4XBjs.g; exports.useUserData = _chunkZWSHZHIHjs.a; exports.useUserProfile = _chunkWUOGD7AZjs.l; exports.validateInternalRedirect = P;
6
+ `});function v({stage:e="loading",message:i}){let r=i||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, _e,{}),_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:Be}),_jsxruntime.jsx.call(void 0, "p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:r})]})]})}var Ve=/^[a-zA-Z0-9\-_./\?=&%#]+$/,We=[/^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,i="/")=>{if(!e||typeof e!="string")return i;let t=e.trim();if(!t)return i;if(!t.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),i;if(!Ve.test(t))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),i;let r=t.toLowerCase();for(let o of We)if(o.test(r))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),i;let n=t.split("?")[0].split("/").filter(Boolean);if(n.length===0)return t;for(let o of n)if(o===".."||o.includes(":")||o.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",o),i;return t},T= exports.extractSafeRedirectFromUrl =(e,i="/")=>{try{let r=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!r)return i;let n=decodeURIComponent(r);return P(n,i)}catch(t){return console.warn("\u{1F6A8} Error parsing redirect parameter:",t),i}};function N({children:e,loadingComponent:i,loginPath:t="/login"}){let{isAuthenticated:r,isLoading:n,isInitialized:o,tokens:s,error:p}=_chunkIXDCGL4Kjs.j.call(void 0, ),u=_reactrouterdom.useLocation.call(void 0, );if(!o||n)return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:i||_jsxruntime.jsx.call(void 0, v,{stage:"validating-session"})});let d=r&&_optionalChain([s, 'optionalAccess', _2 => _2.accessToken])&&s.accessToken.length>0;if(p||!r||!d){s&&(!s.accessToken||s.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let m=u.pathname+u.search,I=P(m),h=encodeURIComponent(I);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:`${t}?redirect=${h}`,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}function O({children:e,redirectTo:i="/"}){let{isAuthenticated:t}=_chunkIXDCGL4Kjs.j.call(void 0, ),r=_reactrouterdom.useLocation.call(void 0, );if(t){let n=new URLSearchParams(r.search),o=T(n,i);return _jsxruntime.jsx.call(void 0, _reactrouterdom.Navigate,{to:o,replace:!0})}return _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:e})}var C=class e{constructor(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null};this.initializationPromise=null;this.highPriorityInitializerPresent=!1;this.waitingForHighPriority=new Set;this.HIGH_PRIORITY_WAIT_TIMEOUT=100}static getInstance(){return e.instance||(e.instance=new e),e.instance}registerHighPriorityInitializer(){this.highPriorityInitializerPresent=!0}isHighPriorityInitializerPresent(){return this.highPriorityInitializerPresent}getState(){return{...this.state}}async initialize(i){let{priority:t,publicApiKey:r,env:n,enableLogging:o,requestedBy:s}=i;if(this.state.status==="INITIALIZED"){this.state.publicApiKey!==r&&console.warn(`[CrudifyInitialization] ${s} attempted to initialize with different key. Already initialized with key: ${_optionalChain([this, 'access', _3 => _3.state, 'access', _4 => _4.publicApiKey, 'optionalAccess', _5 => _5.slice, 'call', _6 => _6(0,10)])}... by ${this.state.initializedBy}`);return}if(this.initializationPromise)return o&&console.log(`[CrudifyInitialization] ${s} waiting for ongoing initialization...`),this.initializationPromise;if(t==="LOW"&&this.highPriorityInitializerPresent&&this.state.status==="UNINITIALIZED"){if(o&&console.log(`[CrudifyInitialization] ${s} (LOW priority) waiting for HIGH priority initializer...`),this.waitingForHighPriority.add(s),await this.waitForHighPriorityOrTimeout(o),this.waitingForHighPriority.delete(s),this.getState().status==="INITIALIZED"){o&&console.log(`[CrudifyInitialization] ${s} found initialization completed by HIGH priority`);return}o&&console.warn(`[CrudifyInitialization] ${s} timeout waiting for HIGH priority, initializing with LOW priority`)}t==="HIGH"&&this.state.status==="INITIALIZING"&&this.state.priority==="LOW"&&(console.warn(`[CrudifyInitialization] HIGH priority request from ${s} interrupting LOW priority initialization by ${this.state.initializedBy}`),this.state.status="UNINITIALIZED",this.initializationPromise=null),o&&console.log(`[CrudifyInitialization] ${s} starting initialization (${t} priority)...`),this.state.status="INITIALIZING",this.state.priority=t,this.state.initializedBy=s,this.initializationPromise=this.performInitialization(r,n,o);try{await this.initializationPromise,this.state.status="INITIALIZED",this.state.publicApiKey=r,this.state.env=n,this.state.error=null,o&&console.log(`[CrudifyInitialization] \u2705 Successfully initialized by ${s} (${t} priority)`)}catch(p){throw this.state.status="ERROR",this.state.error=p instanceof Error?p:new Error(String(p)),this.initializationPromise=null,console.error(`[CrudifyInitialization] \u274C Initialization failed for ${s}:`,p),p}}async waitForHighPriorityOrTimeout(i){return new Promise(t=>{let n=0,o=setInterval(()=>{if(n+=10,this.state.status==="INITIALIZED"&&this.state.priority==="HIGH"){clearInterval(o),t();return}if(this.state.status==="INITIALIZING"&&this.state.priority==="HIGH"){n=0;return}n>=this.HIGH_PRIORITY_WAIT_TIMEOUT&&(clearInterval(o),i&&console.log(`[CrudifyInitialization] Timeout waiting for HIGH priority (${this.HIGH_PRIORITY_WAIT_TIMEOUT}ms)`),t())},10)})}async performInitialization(i,t,r){let n=_crudifybrowser2.default.getTokenData();if(n&&n.endpoint){r&&console.log("[CrudifyInitialization] SDK already initialized externally");return}_crudifybrowser2.default.config(t);let o=r?"debug":"none",s=await _crudifybrowser2.default.init(i,o);if(s.success===!1)throw new Error(`Crudify initialization failed: ${JSON.stringify(s.errors||"Unknown error")}`)}reset(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null},this.initializationPromise=null,this.highPriorityInitializerPresent=!1,this.waitingForHighPriority.clear()}isInitialized(){return this.state.status==="INITIALIZED"}getDiagnostics(){return{...this.state,waitingCount:this.waitingForHighPriority.size,waitingComponents:Array.from(this.waitingForHighPriority),hasActivePromise:this.initializationPromise!==null}}},x= exports.crudifyInitManager =C.getInstance();var F=_react.createContext.call(void 0, void 0),ti= exports.CrudifyInitializer =({config:e,children:i,fallback:t=null,onInitialized:r,onError:n})=>{let[o,s]=_react.useState.call(void 0, !1),[p,u]=_react.useState.call(void 0, !1),[d,m]=_react.useState.call(void 0, null),I=_react.useRef.call(void 0, !1),h=_react.useRef.call(void 0, !1);_react.useEffect.call(void 0, ()=>{I.current||(x.registerHighPriorityInitializer(),I.current=!0),h.current||(h.current=!0,(async()=>{u(!0),m(null);try{let c=_chunkFC7HOMNQjs.b.call(void 0, {publicApiKey:_optionalChain([e, 'optionalAccess', _7 => _7.publicApiKey]),env:_optionalChain([e, 'optionalAccess', _8 => _8.env]),enableDebug:_optionalChain([e, 'optionalAccess', _9 => _9.enableLogging])});if(!c.publicApiKey)throw new Error("Crudify configuration missing. Please provide publicApiKey via props or ensure cookies are set by Lambda.");await x.initialize({priority:"HIGH",publicApiKey:c.publicApiKey,env:c.env||"prod",enableLogging:_optionalChain([e, 'optionalAccess', _10 => _10.enableLogging]),requestedBy:"CrudifyInitializer"}),s(!0),u(!1),r&&r()}catch(c){let E=c instanceof Error?c:new Error(String(c));m(E),u(!1),n&&n(E)}})())},[_optionalChain([e, 'optionalAccess', _11 => _11.publicApiKey]),_optionalChain([e, 'optionalAccess', _12 => _12.env]),_optionalChain([e, 'optionalAccess', _13 => _13.enableLogging]),r,n]);let K={isInitialized:o,isInitializing:p,error:d};return p&&t?_jsxruntime.jsx.call(void 0, _jsxruntime.Fragment,{children:t}):(d&&console.error("[CrudifyInitializer] Initialization failed:",d),_jsxruntime.jsx.call(void 0, F.Provider,{value:K,children:i}))},ri= exports.useCrudifyInitializer =()=>{let e=_react.useContext.call(void 0, F);if(!e)throw new Error("useCrudifyInitializer must be used within CrudifyInitializer");return e};var _crudifyadmin = require('@nocios/crudify-admin'); var _crudifyadmin2 = _interopRequireDefault(_crudifyadmin);var G=!1,g=null;async function ni(){let i=_chunkIXDCGL4Kjs.e.getInstance().getTokenInfo(),t=_optionalChain([i, 'optionalAccess', _14 => _14.apiEndpointAdmin]),r=_optionalChain([i, 'optionalAccess', _15 => _15.apiKeyEndpointAdmin]);return t&&r?{apiUrl:t,apiKey:r}:_chunkIXDCGL4Kjs.a.waitForCredentials()}async function si(){if(!G)return g||(g=(async()=>{try{let e=_chunkIXDCGL4Kjs.e.getInstance(),{apiUrl:i,apiKey:t}=await ni();_crudifyadmin2.default.init({url:i,apiKey:t,getAdditionalHeaders:()=>{let r=e.getTokenInfo();return _optionalChain([r, 'optionalAccess', _16 => _16.crudifyTokens, 'optionalAccess', _17 => _17.accessToken])?{Authorization:`Bearer ${r.crudifyTokens.accessToken}`}:{}}}),G=!0}catch(e){throw g=null,console.error("[crudifyAdminWrapper] Initialization failed:",e),e}})(),g)}async function l(e){try{await si();let i=await e();return!i.success&&_optionalChain([i, 'access', _18 => _18.errors, 'optionalAccess', _19 => _19.includes, 'call', _20 => _20("401")])?await _chunkIXDCGL4Kjs.e.getInstance().refreshTokens()?await e():(console.error("[crudifyAdmin] Token refresh failed"),typeof window<"u"&&(window.location.href="/login"),i):i}catch(i){return console.error("[crudifyAdmin] Operation error:",i),{success:!1,errors:i instanceof Error?i.message:"Unknown error"}}}var ai={listModules:()=>l(()=>_crudifyadmin2.default.listModules()),getModule:e=>l(()=>_crudifyadmin2.default.getModule(e)),createModule:e=>l(()=>_crudifyadmin2.default.createModule(e)),editModule:(e,i)=>l(()=>_crudifyadmin2.default.editModule(e,i)),deleteModule:e=>l(()=>_crudifyadmin2.default.deleteModule(e)),activateModule:e=>l(()=>_crudifyadmin2.default.activateModule(e)),deactivateModule:e=>l(()=>_crudifyadmin2.default.deactivateModule(e)),getModuleVersions:e=>l(()=>_crudifyadmin2.default.getModuleVersions(e)),listActions:e=>l(()=>_crudifyadmin2.default.listActions(e)),getAction:e=>l(()=>_crudifyadmin2.default.getAction(e)),createAction:e=>l(()=>_crudifyadmin2.default.createAction(e)),editAction:(e,i)=>l(()=>_crudifyadmin2.default.editAction(e,i)),deleteAction:e=>l(()=>_crudifyadmin2.default.deleteAction(e)),activateAction:e=>l(()=>_crudifyadmin2.default.activateAction(e)),deactivateAction:e=>l(()=>_crudifyadmin2.default.deactivateAction(e)),getActionVersions:e=>l(()=>_crudifyadmin2.default.getActionVersions(e)),getActionsByProfile:e=>l(()=>_crudifyadmin2.default.getActionsByProfile(e)),updateActionsProfiles:e=>l(()=>_crudifyadmin2.default.updateActionsProfiles(e))};exports.AuthRoute = O; exports.CRITICAL_TRANSLATIONS = _chunkQXYEAMMDjs.a; exports.CrudiaAutoGenerate = _chunkQXYEAMMDjs.o; exports.CrudiaFileField = _chunkQXYEAMMDjs.p; exports.CrudifyInitializationManager = C; exports.CrudifyInitializer = ti; exports.CrudifyLogin = _chunkQXYEAMMDjs.h; exports.CrudifyProvider = _chunkIXDCGL4Kjs.b; exports.CrudifyThemeProvider = Ge; exports.ERROR_CODES = _chunkYIIUEOXCjs.a; exports.ERROR_SEVERITY_MAP = _chunkYIIUEOXCjs.b; exports.GlobalNotificationProvider = _chunkIXDCGL4Kjs.g; exports.LoginComponent = _chunkQXYEAMMDjs.m; exports.POLICY_ACTIONS = _chunkQXYEAMMDjs.j; exports.PREFERRED_POLICY_ORDER = _chunkQXYEAMMDjs.k; exports.Policies = _chunkQXYEAMMDjs.l; exports.ProtectedRoute = N; exports.SessionDebugInfo = _chunkIXDCGL4Kjs.k; exports.SessionLoadingScreen = v; exports.SessionManager = _chunkIXDCGL4Kjs.e; exports.SessionProvider = _chunkIXDCGL4Kjs.i; exports.SessionStatus = _chunkQXYEAMMDjs.n; exports.TokenStorage = _chunkIXDCGL4Kjs.d; exports.TranslationService = _chunkQXYEAMMDjs.d; exports.TranslationsProvider = _chunkQXYEAMMDjs.f; exports.UserProfileDisplay = _chunkQXYEAMMDjs.i; exports.createErrorTranslator = _chunkFC7HOMNQjs.g; exports.crudify = _crudifybrowser2.default; exports.crudifyAdmin = ai; exports.crudifyInitManager = x; exports.decodeJwtSafely = _chunkFC7HOMNQjs.j; exports.extractSafeRedirectFromUrl = T; exports.getCookie = _chunkFC7HOMNQjs.a; exports.getCriticalLanguages = _chunkQXYEAMMDjs.b; exports.getCriticalTranslations = _chunkQXYEAMMDjs.c; exports.getCurrentUserEmail = _chunkFC7HOMNQjs.k; exports.getErrorMessage = _chunkYIIUEOXCjs.e; exports.handleCrudifyError = _chunkYIIUEOXCjs.g; exports.isTokenExpired = _chunkFC7HOMNQjs.l; exports.parseApiError = _chunkYIIUEOXCjs.c; exports.parseJavaScriptError = _chunkYIIUEOXCjs.f; exports.parseTransactionError = _chunkYIIUEOXCjs.d; exports.secureLocalStorage = _chunkNNY4A73Vjs.b; exports.secureSessionStorage = _chunkNNY4A73Vjs.a; exports.translateError = _chunkFC7HOMNQjs.f; exports.translateErrorCode = _chunkFC7HOMNQjs.d; exports.translateErrorCodes = _chunkFC7HOMNQjs.e; exports.translationService = _chunkQXYEAMMDjs.e; exports.useAuth = _chunkKXBLNQ5Qjs.b; exports.useAutoGenerate = _chunkIXDCGL4Kjs.m; exports.useCrudify = _chunkIXDCGL4Kjs.c; exports.useCrudifyInitializer = ri; exports.useCrudifyWithNotifications = _chunkKXBLNQ5Qjs.d; exports.useData = _chunkKXBLNQ5Qjs.c; exports.useFileUpload = _chunkIXDCGL4Kjs.n; exports.useGlobalNotification = _chunkIXDCGL4Kjs.h; exports.useSession = _chunkIXDCGL4Kjs.f; exports.useSessionContext = _chunkIXDCGL4Kjs.j; exports.useTranslations = _chunkQXYEAMMDjs.g; exports.useUserData = _chunkKXBLNQ5Qjs.a; exports.useUserProfile = _chunkIXDCGL4Kjs.l; exports.validateInternalRedirect = P;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import{a as $,b as B,c as _,d as Z,e as V,f as W,g as q,h as Ie,i as Ae,j as Pe,k as Re,l as Ce,m as xe,n as ze,o as Te}from"./chunk-35AID65H.mjs";import{a as Se,b as be,c as Ee,d as Me}from"./chunk-6PXLM74L.mjs";import{a as L,b as Y,c as J,d as Q,e as f,f as te,g as se,h as ae,i as le,j as y,k as ce,l as he,m as ve}from"./chunk-TZKAMU3P.mjs";import{a as we,b as Le}from"./chunk-T2CPA46I.mjs";import{a as pe,b as ue,c as de,d as fe,e as ye,f as ge,g as me}from"./chunk-BJ6PIVZR.mjs";import{a as z,b as w,d as X,e as j,f as ee,g as ie,j as re,k as oe,l as ne}from"./chunk-6GPSBDW6.mjs";import{default as Vi}from"@nocios/crudify-browser";export*from"@nocios/crudify-browser";import{useMemo as Ne}from"react";import{ThemeProvider as ke,createTheme as Ue,CssBaseline as Oe}from"@mui/material";import{jsx as Ge,jsxs as Ke}from"react/jsx-runtime";var He=(e={})=>{try{let i=z("theme");if(i){let t=JSON.parse(decodeURIComponent(i));return{...e,...t}}}catch(i){console.warn("Error parsing theme from cookie:",i)}return e};function De({children:e,defaultTheme:i={},disableCssBaseline:t=!1}){let r=Ne(()=>{let n=He(i);return Ue(n)},[i]);return Ke(ke,{theme:r,children:[!t&&Ge(Oe,{}),e]})}import{Navigate as Ve,useLocation as We}from"react-router-dom";import{Fragment as Be,jsx as A,jsxs as M}from"react/jsx-runtime";var Fe={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},$e=()=>A("style",{children:`
1
+ import{a as $,b as B,c as _,d as Z,e as V,f as W,g as q,h as Ie,i as Ae,j as Pe,k as Re,l as Ce,m as xe,n as ze,o as Te,p as be}from"./chunk-ACJBO4GO.mjs";import{a as Ee,b as we,c as Le,d as Ne}from"./chunk-66E5Q5BA.mjs";import{a as L,b as Y,c as J,d as Q,e as f,f as te,g as se,h as ae,i as le,j as y,k as pe,l as he,m as ve,n as Se}from"./chunk-4E2PRDUC.mjs";import{a as Me,b as Ue}from"./chunk-T2CPA46I.mjs";import{a as ce,b as ue,c as de,d as fe,e as ye,f as ge,g as me}from"./chunk-BJ6PIVZR.mjs";import{a as z,b as w,d as X,e as j,f as ee,g as ie,j as re,k as oe,l as ne}from"./chunk-6GPSBDW6.mjs";import{default as qi}from"@nocios/crudify-browser";export*from"@nocios/crudify-browser";import{useMemo as ke}from"react";import{ThemeProvider as Oe,createTheme as He,CssBaseline as De}from"@mui/material";import{jsx as Ke,jsxs as $e}from"react/jsx-runtime";var Fe=(e={})=>{try{let i=z("theme");if(i){let t=JSON.parse(decodeURIComponent(i));return{...e,...t}}}catch(i){console.warn("Error parsing theme from cookie:",i)}return e};function Ge({children:e,defaultTheme:i={},disableCssBaseline:t=!1}){let r=ke(()=>{let n=Fe(i);return He(n)},[i]);return $e(Oe,{theme:r,children:[!t&&Ke(De,{}),e]})}import{Navigate as qe,useLocation as Ye}from"react-router-dom";import{Fragment as Ze,jsx as A,jsxs as M}from"react/jsx-runtime";var Be={border:"5px solid rgba(0, 0, 0, 0.1)",borderTopColor:"#3B82F6",borderRadius:"50%",width:"50px",height:"50px",animation:"spin 1s linear infinite"},_e=()=>A("style",{children:`
2
2
  @keyframes spin {
3
3
  0% { transform: rotate(0deg); }
4
4
  100% { transform: rotate(360deg); }
5
5
  }
6
- `});function v({stage:e="loading",message:i}){let r=i||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return M(Be,{children:[A($e,{}),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:[A("div",{style:Fe}),A("p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:r})]})]})}var _e=/^[a-zA-Z0-9\-_./\?=&%#]+$/,Ze=[/^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,i="/")=>{if(!e||typeof e!="string")return i;let t=e.trim();if(!t)return i;if(!t.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),i;if(!_e.test(t))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),i;let r=t.toLowerCase();for(let o of Ze)if(o.test(r))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),i;let n=t.split("?")[0].split("/").filter(Boolean);if(n.length===0)return t;for(let o of n)if(o===".."||o.includes(":")||o.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",o),i;return t},T=(e,i="/")=>{try{let r=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!r)return i;let n=decodeURIComponent(r);return P(n,i)}catch(t){return console.warn("\u{1F6A8} Error parsing redirect parameter:",t),i}};import{Fragment as N,jsx as R}from"react/jsx-runtime";function k({children:e,loadingComponent:i,loginPath:t="/login"}){let{isAuthenticated:r,isLoading:n,isInitialized:o,tokens:s,error:c}=y(),u=We();if(!o||n)return R(N,{children:i||R(v,{stage:"validating-session"})});let d=r&&s?.accessToken&&s.accessToken.length>0;if(c||!r||!d){s&&(!s.accessToken||s.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let m=u.pathname+u.search,I=P(m),h=encodeURIComponent(I);return R(Ve,{to:`${t}?redirect=${h}`,replace:!0})}return R(N,{children:e})}import{Navigate as qe,useLocation as Ye}from"react-router-dom";import{Fragment as Je,jsx as U}from"react/jsx-runtime";function O({children:e,redirectTo:i="/"}){let{isAuthenticated:t}=y(),r=Ye();if(t){let n=new URLSearchParams(r.search),o=T(n,i);return U(qe,{to:o,replace:!0})}return U(Je,{children:e})}import S from"@nocios/crudify-browser";var C=class e{constructor(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null};this.initializationPromise=null;this.highPriorityInitializerPresent=!1;this.waitingForHighPriority=new Set;this.HIGH_PRIORITY_WAIT_TIMEOUT=100}static getInstance(){return e.instance||(e.instance=new e),e.instance}registerHighPriorityInitializer(){this.highPriorityInitializerPresent=!0}isHighPriorityInitializerPresent(){return this.highPriorityInitializerPresent}getState(){return{...this.state}}async initialize(i){let{priority:t,publicApiKey:r,env:n,enableLogging:o,requestedBy:s}=i;if(this.state.status==="INITIALIZED"){this.state.publicApiKey!==r&&console.warn(`[CrudifyInitialization] ${s} attempted to initialize with different key. Already initialized with key: ${this.state.publicApiKey?.slice(0,10)}... by ${this.state.initializedBy}`);return}if(this.initializationPromise)return o&&console.log(`[CrudifyInitialization] ${s} waiting for ongoing initialization...`),this.initializationPromise;if(t==="LOW"&&this.highPriorityInitializerPresent&&this.state.status==="UNINITIALIZED"){if(o&&console.log(`[CrudifyInitialization] ${s} (LOW priority) waiting for HIGH priority initializer...`),this.waitingForHighPriority.add(s),await this.waitForHighPriorityOrTimeout(o),this.waitingForHighPriority.delete(s),this.getState().status==="INITIALIZED"){o&&console.log(`[CrudifyInitialization] ${s} found initialization completed by HIGH priority`);return}o&&console.warn(`[CrudifyInitialization] ${s} timeout waiting for HIGH priority, initializing with LOW priority`)}t==="HIGH"&&this.state.status==="INITIALIZING"&&this.state.priority==="LOW"&&(console.warn(`[CrudifyInitialization] HIGH priority request from ${s} interrupting LOW priority initialization by ${this.state.initializedBy}`),this.state.status="UNINITIALIZED",this.initializationPromise=null),o&&console.log(`[CrudifyInitialization] ${s} starting initialization (${t} priority)...`),this.state.status="INITIALIZING",this.state.priority=t,this.state.initializedBy=s,this.initializationPromise=this.performInitialization(r,n,o);try{await this.initializationPromise,this.state.status="INITIALIZED",this.state.publicApiKey=r,this.state.env=n,this.state.error=null,o&&console.log(`[CrudifyInitialization] \u2705 Successfully initialized by ${s} (${t} priority)`)}catch(c){throw this.state.status="ERROR",this.state.error=c instanceof Error?c:new Error(String(c)),this.initializationPromise=null,console.error(`[CrudifyInitialization] \u274C Initialization failed for ${s}:`,c),c}}async waitForHighPriorityOrTimeout(i){return new Promise(t=>{let n=0,o=setInterval(()=>{if(n+=10,this.state.status==="INITIALIZED"&&this.state.priority==="HIGH"){clearInterval(o),t();return}if(this.state.status==="INITIALIZING"&&this.state.priority==="HIGH"){n=0;return}n>=this.HIGH_PRIORITY_WAIT_TIMEOUT&&(clearInterval(o),i&&console.log(`[CrudifyInitialization] Timeout waiting for HIGH priority (${this.HIGH_PRIORITY_WAIT_TIMEOUT}ms)`),t())},10)})}async performInitialization(i,t,r){let n=S.getTokenData();if(n&&n.endpoint){r&&console.log("[CrudifyInitialization] SDK already initialized externally");return}S.config(t);let o=r?"debug":"none",s=await S.init(i,o);if(s.success===!1)throw new Error(`Crudify initialization failed: ${JSON.stringify(s.errors||"Unknown error")}`)}reset(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null},this.initializationPromise=null,this.highPriorityInitializerPresent=!1,this.waitingForHighPriority.clear()}isInitialized(){return this.state.status==="INITIALIZED"}getDiagnostics(){return{...this.state,waitingCount:this.waitingForHighPriority.size,waitingComponents:Array.from(this.waitingForHighPriority),hasActivePromise:this.initializationPromise!==null}}},x=C.getInstance();import{createContext as Qe,useContext as Xe,useEffect as je,useRef as H,useState as b}from"react";import{Fragment as ti,jsx as D}from"react/jsx-runtime";var G=Qe(void 0),ei=({config:e,children:i,fallback:t=null,onInitialized:r,onError:n})=>{let[o,s]=b(!1),[c,u]=b(!1),[d,m]=b(null),I=H(!1),h=H(!1);je(()=>{I.current||(x.registerHighPriorityInitializer(),I.current=!0),h.current||(h.current=!0,(async()=>{u(!0),m(null);try{let p=w({publicApiKey:e?.publicApiKey,env:e?.env,enableDebug:e?.enableLogging});if(!p.publicApiKey)throw new Error("Crudify configuration missing. Please provide publicApiKey via props or ensure cookies are set by Lambda.");await x.initialize({priority:"HIGH",publicApiKey:p.publicApiKey,env:p.env||"prod",enableLogging:e?.enableLogging,requestedBy:"CrudifyInitializer"}),s(!0),u(!1),r&&r()}catch(p){let E=p instanceof Error?p:new Error(String(p));m(E),u(!1),n&&n(E)}})())},[e?.publicApiKey,e?.env,e?.enableLogging,r,n]);let F={isInitialized:o,isInitializing:c,error:d};return c&&t?D(ti,{children:t}):(d&&console.error("[CrudifyInitializer] Initialization failed:",d),D(G.Provider,{value:F,children:i}))},ii=()=>{let e=Xe(G);if(!e)throw new Error("useCrudifyInitializer must be used within CrudifyInitializer");return e};import a from"@nocios/crudify-admin";var K=!1,g=null;async function ri(){let i=f.getInstance().getTokenInfo(),t=i?.apiEndpointAdmin,r=i?.apiKeyEndpointAdmin;return t&&r?{apiUrl:t,apiKey:r}:L.waitForCredentials()}async function oi(){if(!K)return g||(g=(async()=>{try{let e=f.getInstance(),{apiUrl:i,apiKey:t}=await ri();a.init({url:i,apiKey:t,getAdditionalHeaders:()=>{let r=e.getTokenInfo();return r?.crudifyTokens?.accessToken?{Authorization:`Bearer ${r.crudifyTokens.accessToken}`}:{}}}),K=!0}catch(e){throw g=null,console.error("[crudifyAdminWrapper] Initialization failed:",e),e}})(),g)}async function l(e){try{await oi();let i=await e();return!i.success&&i.errors?.includes("401")?await f.getInstance().refreshTokens()?await e():(console.error("[crudifyAdmin] Token refresh failed"),typeof window<"u"&&(window.location.href="/login"),i):i}catch(i){return console.error("[crudifyAdmin] Operation error:",i),{success:!1,errors:i instanceof Error?i.message:"Unknown error"}}}var ni={listModules:()=>l(()=>a.listModules()),getModule:e=>l(()=>a.getModule(e)),createModule:e=>l(()=>a.createModule(e)),editModule:(e,i)=>l(()=>a.editModule(e,i)),deleteModule:e=>l(()=>a.deleteModule(e)),activateModule:e=>l(()=>a.activateModule(e)),deactivateModule:e=>l(()=>a.deactivateModule(e)),getModuleVersions:e=>l(()=>a.getModuleVersions(e)),listActions:e=>l(()=>a.listActions(e)),getAction:e=>l(()=>a.getAction(e)),createAction:e=>l(()=>a.createAction(e)),editAction:(e,i)=>l(()=>a.editAction(e,i)),deleteAction:e=>l(()=>a.deleteAction(e)),activateAction:e=>l(()=>a.activateAction(e)),deactivateAction:e=>l(()=>a.deactivateAction(e)),getActionVersions:e=>l(()=>a.getActionVersions(e)),getActionsByProfile:e=>l(()=>a.getActionsByProfile(e)),updateActionsProfiles:e=>l(()=>a.updateActionsProfiles(e))};export{O as AuthRoute,$ as CRITICAL_TRANSLATIONS,Te as CrudiaAutoGenerate,C as CrudifyInitializationManager,ei as CrudifyInitializer,Ie as CrudifyLogin,Y as CrudifyProvider,De as CrudifyThemeProvider,pe as ERROR_CODES,ue as ERROR_SEVERITY_MAP,se as GlobalNotificationProvider,xe as LoginComponent,Pe as POLICY_ACTIONS,Re as PREFERRED_POLICY_ORDER,Ce as Policies,k as ProtectedRoute,ce as SessionDebugInfo,v as SessionLoadingScreen,f as SessionManager,le as SessionProvider,ze as SessionStatus,Q as TokenStorage,Z as TranslationService,W as TranslationsProvider,Ae as UserProfileDisplay,ie as createErrorTranslator,Vi as crudify,ni as crudifyAdmin,x as crudifyInitManager,re as decodeJwtSafely,T as extractSafeRedirectFromUrl,z as getCookie,B as getCriticalLanguages,_ as getCriticalTranslations,oe as getCurrentUserEmail,ye as getErrorMessage,me as handleCrudifyError,ne as isTokenExpired,de as parseApiError,ge as parseJavaScriptError,fe as parseTransactionError,Le as secureLocalStorage,we as secureSessionStorage,ee as translateError,X as translateErrorCode,j as translateErrorCodes,V as translationService,be as useAuth,ve as useAutoGenerate,J as useCrudify,ii as useCrudifyInitializer,Me as useCrudifyWithNotifications,Ee as useData,ae as useGlobalNotification,te as useSession,y as useSessionContext,q as useTranslations,Se as useUserData,he as useUserProfile,P as validateInternalRedirect};
6
+ `});function v({stage:e="loading",message:i}){let r=i||{initializing:"Initializing application...","validating-session":"Validating session...",loading:"Loading..."}[e];return M(Ze,{children:[A(_e,{}),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:[A("div",{style:Be}),A("p",{style:{fontSize:"1.25em",fontWeight:"500",marginTop:"24px",color:"#1f2937"},children:r})]})]})}var Ve=/^[a-zA-Z0-9\-_./\?=&%#]+$/,We=[/^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,i="/")=>{if(!e||typeof e!="string")return i;let t=e.trim();if(!t)return i;if(!t.startsWith("/"))return console.warn("\u{1F6A8} Open redirect blocked (relative path):",e),i;if(!Ve.test(t))return console.warn("\u{1F6A8} Open redirect blocked (invalid characters):",e),i;let r=t.toLowerCase();for(let o of We)if(o.test(r))return console.warn("\u{1F6A8} Open redirect blocked (dangerous pattern):",e),i;let n=t.split("?")[0].split("/").filter(Boolean);if(n.length===0)return t;for(let o of n)if(o===".."||o.includes(":")||o.length>100)return console.warn("\u{1F6A8} Open redirect blocked (suspicious path part):",o),i;return t},T=(e,i="/")=>{try{let r=(typeof e=="string"?new URLSearchParams(e):e).get("redirect");if(!r)return i;let n=decodeURIComponent(r);return P(n,i)}catch(t){return console.warn("\u{1F6A8} Error parsing redirect parameter:",t),i}};import{Fragment as U,jsx as R}from"react/jsx-runtime";function N({children:e,loadingComponent:i,loginPath:t="/login"}){let{isAuthenticated:r,isLoading:n,isInitialized:o,tokens:s,error:p}=y(),u=Ye();if(!o||n)return R(U,{children:i||R(v,{stage:"validating-session"})});let d=r&&s?.accessToken&&s.accessToken.length>0;if(p||!r||!d){s&&(!s.accessToken||s.accessToken.length===0)&&localStorage.removeItem("crudify_tokens");let m=u.pathname+u.search,I=P(m),h=encodeURIComponent(I);return R(qe,{to:`${t}?redirect=${h}`,replace:!0})}return R(U,{children:e})}import{Navigate as Je,useLocation as Qe}from"react-router-dom";import{Fragment as Xe,jsx as k}from"react/jsx-runtime";function O({children:e,redirectTo:i="/"}){let{isAuthenticated:t}=y(),r=Qe();if(t){let n=new URLSearchParams(r.search),o=T(n,i);return k(Je,{to:o,replace:!0})}return k(Xe,{children:e})}import S from"@nocios/crudify-browser";var C=class e{constructor(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null};this.initializationPromise=null;this.highPriorityInitializerPresent=!1;this.waitingForHighPriority=new Set;this.HIGH_PRIORITY_WAIT_TIMEOUT=100}static getInstance(){return e.instance||(e.instance=new e),e.instance}registerHighPriorityInitializer(){this.highPriorityInitializerPresent=!0}isHighPriorityInitializerPresent(){return this.highPriorityInitializerPresent}getState(){return{...this.state}}async initialize(i){let{priority:t,publicApiKey:r,env:n,enableLogging:o,requestedBy:s}=i;if(this.state.status==="INITIALIZED"){this.state.publicApiKey!==r&&console.warn(`[CrudifyInitialization] ${s} attempted to initialize with different key. Already initialized with key: ${this.state.publicApiKey?.slice(0,10)}... by ${this.state.initializedBy}`);return}if(this.initializationPromise)return o&&console.log(`[CrudifyInitialization] ${s} waiting for ongoing initialization...`),this.initializationPromise;if(t==="LOW"&&this.highPriorityInitializerPresent&&this.state.status==="UNINITIALIZED"){if(o&&console.log(`[CrudifyInitialization] ${s} (LOW priority) waiting for HIGH priority initializer...`),this.waitingForHighPriority.add(s),await this.waitForHighPriorityOrTimeout(o),this.waitingForHighPriority.delete(s),this.getState().status==="INITIALIZED"){o&&console.log(`[CrudifyInitialization] ${s} found initialization completed by HIGH priority`);return}o&&console.warn(`[CrudifyInitialization] ${s} timeout waiting for HIGH priority, initializing with LOW priority`)}t==="HIGH"&&this.state.status==="INITIALIZING"&&this.state.priority==="LOW"&&(console.warn(`[CrudifyInitialization] HIGH priority request from ${s} interrupting LOW priority initialization by ${this.state.initializedBy}`),this.state.status="UNINITIALIZED",this.initializationPromise=null),o&&console.log(`[CrudifyInitialization] ${s} starting initialization (${t} priority)...`),this.state.status="INITIALIZING",this.state.priority=t,this.state.initializedBy=s,this.initializationPromise=this.performInitialization(r,n,o);try{await this.initializationPromise,this.state.status="INITIALIZED",this.state.publicApiKey=r,this.state.env=n,this.state.error=null,o&&console.log(`[CrudifyInitialization] \u2705 Successfully initialized by ${s} (${t} priority)`)}catch(p){throw this.state.status="ERROR",this.state.error=p instanceof Error?p:new Error(String(p)),this.initializationPromise=null,console.error(`[CrudifyInitialization] \u274C Initialization failed for ${s}:`,p),p}}async waitForHighPriorityOrTimeout(i){return new Promise(t=>{let n=0,o=setInterval(()=>{if(n+=10,this.state.status==="INITIALIZED"&&this.state.priority==="HIGH"){clearInterval(o),t();return}if(this.state.status==="INITIALIZING"&&this.state.priority==="HIGH"){n=0;return}n>=this.HIGH_PRIORITY_WAIT_TIMEOUT&&(clearInterval(o),i&&console.log(`[CrudifyInitialization] Timeout waiting for HIGH priority (${this.HIGH_PRIORITY_WAIT_TIMEOUT}ms)`),t())},10)})}async performInitialization(i,t,r){let n=S.getTokenData();if(n&&n.endpoint){r&&console.log("[CrudifyInitialization] SDK already initialized externally");return}S.config(t);let o=r?"debug":"none",s=await S.init(i,o);if(s.success===!1)throw new Error(`Crudify initialization failed: ${JSON.stringify(s.errors||"Unknown error")}`)}reset(){this.state={status:"UNINITIALIZED",priority:null,publicApiKey:null,env:null,error:null,initializedBy:null},this.initializationPromise=null,this.highPriorityInitializerPresent=!1,this.waitingForHighPriority.clear()}isInitialized(){return this.state.status==="INITIALIZED"}getDiagnostics(){return{...this.state,waitingCount:this.waitingForHighPriority.size,waitingComponents:Array.from(this.waitingForHighPriority),hasActivePromise:this.initializationPromise!==null}}},x=C.getInstance();import{createContext as je,useContext as ei,useEffect as ii,useRef as H,useState as b}from"react";import{Fragment as oi,jsx as D}from"react/jsx-runtime";var F=je(void 0),ti=({config:e,children:i,fallback:t=null,onInitialized:r,onError:n})=>{let[o,s]=b(!1),[p,u]=b(!1),[d,m]=b(null),I=H(!1),h=H(!1);ii(()=>{I.current||(x.registerHighPriorityInitializer(),I.current=!0),h.current||(h.current=!0,(async()=>{u(!0),m(null);try{let c=w({publicApiKey:e?.publicApiKey,env:e?.env,enableDebug:e?.enableLogging});if(!c.publicApiKey)throw new Error("Crudify configuration missing. Please provide publicApiKey via props or ensure cookies are set by Lambda.");await x.initialize({priority:"HIGH",publicApiKey:c.publicApiKey,env:c.env||"prod",enableLogging:e?.enableLogging,requestedBy:"CrudifyInitializer"}),s(!0),u(!1),r&&r()}catch(c){let E=c instanceof Error?c:new Error(String(c));m(E),u(!1),n&&n(E)}})())},[e?.publicApiKey,e?.env,e?.enableLogging,r,n]);let K={isInitialized:o,isInitializing:p,error:d};return p&&t?D(oi,{children:t}):(d&&console.error("[CrudifyInitializer] Initialization failed:",d),D(F.Provider,{value:K,children:i}))},ri=()=>{let e=ei(F);if(!e)throw new Error("useCrudifyInitializer must be used within CrudifyInitializer");return e};import a from"@nocios/crudify-admin";var G=!1,g=null;async function ni(){let i=f.getInstance().getTokenInfo(),t=i?.apiEndpointAdmin,r=i?.apiKeyEndpointAdmin;return t&&r?{apiUrl:t,apiKey:r}:L.waitForCredentials()}async function si(){if(!G)return g||(g=(async()=>{try{let e=f.getInstance(),{apiUrl:i,apiKey:t}=await ni();a.init({url:i,apiKey:t,getAdditionalHeaders:()=>{let r=e.getTokenInfo();return r?.crudifyTokens?.accessToken?{Authorization:`Bearer ${r.crudifyTokens.accessToken}`}:{}}}),G=!0}catch(e){throw g=null,console.error("[crudifyAdminWrapper] Initialization failed:",e),e}})(),g)}async function l(e){try{await si();let i=await e();return!i.success&&i.errors?.includes("401")?await f.getInstance().refreshTokens()?await e():(console.error("[crudifyAdmin] Token refresh failed"),typeof window<"u"&&(window.location.href="/login"),i):i}catch(i){return console.error("[crudifyAdmin] Operation error:",i),{success:!1,errors:i instanceof Error?i.message:"Unknown error"}}}var ai={listModules:()=>l(()=>a.listModules()),getModule:e=>l(()=>a.getModule(e)),createModule:e=>l(()=>a.createModule(e)),editModule:(e,i)=>l(()=>a.editModule(e,i)),deleteModule:e=>l(()=>a.deleteModule(e)),activateModule:e=>l(()=>a.activateModule(e)),deactivateModule:e=>l(()=>a.deactivateModule(e)),getModuleVersions:e=>l(()=>a.getModuleVersions(e)),listActions:e=>l(()=>a.listActions(e)),getAction:e=>l(()=>a.getAction(e)),createAction:e=>l(()=>a.createAction(e)),editAction:(e,i)=>l(()=>a.editAction(e,i)),deleteAction:e=>l(()=>a.deleteAction(e)),activateAction:e=>l(()=>a.activateAction(e)),deactivateAction:e=>l(()=>a.deactivateAction(e)),getActionVersions:e=>l(()=>a.getActionVersions(e)),getActionsByProfile:e=>l(()=>a.getActionsByProfile(e)),updateActionsProfiles:e=>l(()=>a.updateActionsProfiles(e))};export{O as AuthRoute,$ as CRITICAL_TRANSLATIONS,Te as CrudiaAutoGenerate,be as CrudiaFileField,C as CrudifyInitializationManager,ti as CrudifyInitializer,Ie as CrudifyLogin,Y as CrudifyProvider,Ge as CrudifyThemeProvider,ce as ERROR_CODES,ue as ERROR_SEVERITY_MAP,se as GlobalNotificationProvider,xe as LoginComponent,Pe as POLICY_ACTIONS,Re as PREFERRED_POLICY_ORDER,Ce as Policies,N as ProtectedRoute,pe as SessionDebugInfo,v as SessionLoadingScreen,f as SessionManager,le as SessionProvider,ze as SessionStatus,Q as TokenStorage,Z as TranslationService,W as TranslationsProvider,Ae as UserProfileDisplay,ie as createErrorTranslator,qi as crudify,ai as crudifyAdmin,x as crudifyInitManager,re as decodeJwtSafely,T as extractSafeRedirectFromUrl,z as getCookie,B as getCriticalLanguages,_ as getCriticalTranslations,oe as getCurrentUserEmail,ye as getErrorMessage,me as handleCrudifyError,ne as isTokenExpired,de as parseApiError,ge as parseJavaScriptError,fe as parseTransactionError,Ue as secureLocalStorage,Me as secureSessionStorage,ee as translateError,X as translateErrorCode,j as translateErrorCodes,V as translationService,we as useAuth,ve as useAutoGenerate,J as useCrudify,ri as useCrudifyInitializer,Ne as useCrudifyWithNotifications,Le as useData,Se as useFileUpload,ae as useGlobalNotification,te as useSession,y as useSessionContext,q as useTranslations,Ee as useUserData,he as useUserProfile,P as validateInternalRedirect};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocios/crudify-ui",
3
- "version": "4.4.26",
3
+ "version": "4.4.28",
4
4
  "description": "Biblioteca de componentes UI para Crudify",
5
5
  "author": "Nocios",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@nocios/crudify-admin": "^2.2.0",
43
- "@nocios/crudify-browser": "^4.1.8",
43
+ "@nocios/crudify-browser": "^4.1.10",
44
44
  "crypto-js": "^4.2.0",
45
45
  "dompurify": "^3.2.7",
46
46
  "uuid": "^13.0.0"