npm package: @infosel-sdk/widgets
Description: Widgets SDK for Infosel platform. Provides comprehensive tools for creating, managing, and configuring widgets for financial applications.
Author: Infosel Team
Latest version: 1.0.1

# @infosel-sdk/widgets

SDK de Widgets para la plataforma Infosel. Proporciona herramientas completas para crear, gestionar y configurar widgets, espacios de trabajo e instrumentos para aplicaciones financieras.

## 🚀 Características

- **Gestión de Widgets**: Crear, actualizar, eliminar y duplicar widgets financieros personalizables
- **Gestión de Espacios de Trabajo**: Organizar y gestionar espacios de trabajo de usuarios
- **Gestión de Instrumentos**: Crear y gestionar instrumentos financieros personalizados
- **Configuración Avanzada**: Soporte para múltiples tipos de widgets (gráficos, tablas, noticias, etc.)
- **API GraphQL**: Comunicación eficiente mediante GraphQL

## 📦 Instalación

```bash
npm install @infosel-sdk/widgets
```

## 🚀 Inicio Rápido

### ✨ Configuración Moderna (Recomendado)

La nueva API del core proporciona una configuración más limpia y validada:

```typescript
import InfoselWidgets from '@infosel-sdk/widgets';
import { InfoselSdkManager, AuthConfigurationBuilder } from '@infosel-sdk/core';

// Configuración moderna con Builder Pattern
const authConfig = AuthConfigurationBuilder.keyCloak()
  .withRealm('hub')
  .withEnvironment('qa')
  .withCredentials({
    grant_type: 'client_credentials',
    client_id: 'tu-client-id',
    client_secret: 'tu-client-secret',
  })
  .build();

// Inicializar SDK Manager con configuración moderna
const sdkManager = InfoselSdkManager.initWithConfiguration({
  authConfiguration: authConfig,
});

// Inicializar SDK de Widgets
const widgetsSDK = InfoselWidgets.init({ sdkManager });

// Crear un espacio de trabajo
const workspace = await widgetsSDK.createWorkspace({
  name: 'Mi Dashboard',
  description: 'Espacio de trabajo personal',
});
```

### Configuración con Token Existente

```typescript
import InfoselWidgets from '@infosel-sdk/widgets';
import {
  InfoselSdkManager,
  AuthConfigurationBuilder,
  Token,
} from '@infosel-sdk/core';

// Configuración con token existente
const token: Token = {
  accessToken: 'tu-access-token',
  refreshToken: 'tu-refresh-token',
};

const authConfig = AuthConfigurationBuilder.existingToken()
  .withRealm('hub')
  .withEnvironment('prod')
  .withClientId('hub-app')
  .withToken(token)
  .build();

const sdkManager = InfoselSdkManager.initWithConfiguration({
  authConfiguration: authConfig,
});

const widgetsSDK = InfoselWidgets.init({ sdkManager });
```

## 🔍 Validación de Configuración

La nueva API incluye validaciones robustas:

```typescript
import { AuthConfigurationBuilder } from '@infosel-sdk/core';

const builder = AuthConfigurationBuilder.keyCloak()
  .withRealm('invalid@realm') // Caracteres inválidos
  .withCredentials({
    grant_type: 'client_credentials',
    client_id: '', // Client ID vacío
    client_secret: 'secret',
  });

// Validar antes de construir
const validation = builder.validate();
if (!validation.isValid) {
  console.log('Errores:', validation.errors);
  // ['Realm contains invalid characters...', 'Client ID is required...']
}

// O validar automáticamente al construir
try {
  const config = builder.build();
} catch (error) {
  console.error(error.message); // Lista todos los errores de validación
}
```

## 📚 API Completa del SDK

### 🏢 Gestión de Espacios de Trabajo

#### Crear Espacio de Trabajo

```typescript
const workspace = await widgetsSDK.createWorkspace({
  name: 'Mi Dashboard de Trading',
  description: 'Espacio de trabajo personal para análisis de mercado',
  userId: 'user-123', // Opcional: asociar a usuario específico
  projectId: 'project-123', // Opcional: asociar a proyecto específico
});

console.log('Espacio de trabajo creado:', workspace);
```

#### Obtener Espacios de Trabajo

```typescript
// Obtener todos los espacios de trabajo de un proyecto
const allWorkspaces = await widgetsSDK.getWorkspaces({
  projectId: 'project-123',
});

// Obtener espacios de trabajo por usuario
const userWorkspaces = await widgetsSDK.getWorkspacesByUser({
  userId: 'user-123',
});

// Obtener espacios de trabajo específicos del usuario (por connectionId)
const specificUserWorkspaces = await widgetsSDK.getUserWorkspaces({
  connectionId: 'connection-123',
  projectId: 'project-123',
});

// Obtener espacios de trabajo por ID de proyecto
const projectWorkspaces = await widgetsSDK.getWorkspacesByProjectId({
  projectId: 'project-123',
});

console.log('Espacios de trabajo:', allWorkspaces);
```

#### Obtener Detalles del Espacio de Trabajo

```typescript
const workspaceDetails = await widgetsSDK.getWorkspace({
  workspaceId: 'workspace-123',
});

console.log('Detalles del workspace:', workspaceDetails);
console.log('Widgets en el workspace:', workspaceDetails.widgets);
```

#### Actualizar Espacio de Trabajo

```typescript
const updatedWorkspace = await widgetsSDK.updateWorkspace({
  id: 'workspace-123',
  name: 'Dashboard Actualizado',
  description: 'Nueva descripción del espacio de trabajo',
});

console.log('Espacio de trabajo actualizado:', updatedWorkspace);
```

#### Duplicar Espacio de Trabajo

```typescript
const duplicatedWorkspace = await widgetsSDK.duplicateWorkspace({
  id: 'workspace-123',
  name: 'Copia de Mi Dashboard',
});

console.log('Espacio de trabajo duplicado:', duplicatedWorkspace);
```

#### Eliminar Espacio de Trabajo

```typescript
const result = await widgetsSDK.deleteWorkspace({
  id: 'workspace-123',
});

console.log('Resultado:', result); // ID del workspace eliminado
```

### 🎯 Gestión de Widgets

#### Crear Widget

```typescript
// Widget de gráfico
const chartWidget = await widgetsSDK.createWidget({
  workspaceId: 'workspace-123',
  type: 'CHART',
  name: 'Gráfico de AAPL',
  instruments: [
    {
      uniqueKey: 'AAPL_US',
      symbol: 'AAPL',
    },
  ],
});

// Widget de tabla dinámica
const tableWidget = await widgetsSDK.createWidget({
  workspaceId: 'workspace-123',
  type: 'DYNAMIC_TABLE',
  name: 'Tabla de Precios',
  instruments: [
    {
      uniqueKey: 'AAPL_US',
      symbol: 'AAPL',
    },
    {
      uniqueKey: 'MSFT_US',
      symbol: 'MSFT',
    },
  ],
});

// Widget de lista de noticias
const newsWidget = await widgetsSDK.createWidget({
  workspaceId: 'workspace-123',
  type: 'NEWS_LIST',
  name: 'Noticias Financieras',
  newsConfiguration: {
    period: 12,
    listType: 9,
    limit: 20,
    offset: 0,
    sourcesId: '',
    newsTypeId: '',
  },
  sizes: {
    create: {
      node: {
        width: 12,
        height: 18,
        minWidth: 12,
        minHeight: 12,
        maxWidth: 18,
        maxHeight: 18,
        x: 0,
        y: 0,
      },
    },
  },
});

console.log('Widget creado:', chartWidget);
```

#### Tipos de Widgets Disponibles

```typescript
// Tipos soportados:
// - 'FINANCIAL_STATEMENTS': Estados financieros
// - 'DYNAMIC_TABLE': Tabla dinámica
// - 'PREDEFINED_TABLE': Tabla predefinida
// - 'NEWS_LIST': Lista de noticias
// - 'TICKER_TAPE': Cinta de ticker
// - 'CHART': Gráfico
// - 'CUSTOM_TABLE': Tabla personalizada
// - 'SHORT_SALES': Ventas en corto
// - 'MARKET_TOTAL': Total de mercado
// - 'TRADED_PACKAGES': Paquetes negociados
// - 'BROKERAGE_TRADES': Operaciones de corretaje
// - 'BROKERAGE_CONCENTRATION': Concentración de corretaje
// - 'BROKERAGE_PARTICIPATION': Participación de corretaje
// - 'DECREED_RIGHTS_SEARCHER': Buscador de derechos decretados
// - 'INDICES_COMPONENTS': Componentes de índices
```

#### Actualizar Instrumentos del Widget

```typescript
const updatedInstruments = await widgetsSDK.updateWidgetInstruments({
  widgetId: 'widget-123',
  instruments: {
    keys: ['AAPL_US', 'MSFT_US', 'GOOGL_US'],
  },
});

console.log('Instrumentos actualizados:', updatedInstruments);
```

#### Actualizar Configuración del Gráfico del Widget

```typescript
const result = await widgetsSDK.updateWidgetChart({
  widgetId: 'widget-123',
  chartConfiguration: {
    id: 'chart-config-123',
    globalConfiguration: JSON.stringify({
      // Configuración del gráfico
      type: 'line',
      colors: ['#FF5733', '#33FF57'],
    }),
  },
});

console.log('Configuración actualizada:', result);
```

#### Duplicar Widget

```typescript
const duplicatedWidget = await widgetsSDK.duplicateWidget({
  widgetId: 'widget-123',
  workspaceId: 'workspace-456',
  name: 'Copia del Widget',
});

console.log('Widget duplicado:', duplicatedWidget);
```

#### Eliminar Widget

```typescript
const result = await widgetsSDK.deleteWidget('widget-123');
console.log('Resultado:', result); // ID del widget eliminado
```

#### Obtener Widgets del Proyecto

```typescript
const projectWidgets = await widgetsSDK.getProjectWidgets({
  projectId: 'project-123',
});

console.log('Widgets del proyecto:', projectWidgets);
console.log('Widgets por workspace:', projectWidgets.workspaces);
```

#### Obtener Widgets del Usuario

```typescript
const userWidgets = await widgetsSDK.getUserWidgets({
  id: 'user-123',
});

console.log('Widgets del usuario:', userWidgets);
console.log('Total de widgets:', userWidgets.widgets.length);
```

### 🔧 Gestión de Instrumentos

#### Crear Instrumento Personalizado

```typescript
const newInstrument = await widgetsSDK.createInstrument({
  symbol: 'CUSTOM_STOCK',
  uniqueKey: 'CUSTOM_001',
  widgetId: 'widget-123',
});

console.log('Instrumento creado:', newInstrument);
```

#### Obtener Lista de Instrumentos

```typescript
const instruments = await widgetsSDK.getInstruments({
  workspaceId: 'workspace-123',
  // Parámetros opcionales de paginación
  limit: 50,
  offset: 0,
});

console.log('Total de instrumentos:', instruments.total);
console.log('Instrumentos:', instruments.fields);
```

#### Eliminar Instrumento

```typescript
const result = await widgetsSDK.deleteInstrument('instrument-id-123');
console.log('Resultado:', result); // ID del instrumento eliminado
```

## 🔧 Ejemplos Prácticos Completos

### 📱 Dashboard Completo de Widgets

```typescript
import InfoselWidgets from '@infosel-sdk/widgets';
import { InfoselSdkManager, AuthConfigurationBuilder } from '@infosel-sdk/core';

class WidgetsDashboard {
  private widgetsSDK: InfoselWidgets;

  constructor() {
    this.initializeSDK();
  }

  private async initializeSDK() {
    const authConfig = AuthConfigurationBuilder.keyCloak()
      .withRealm('hub')
      .withEnvironment('qa')
      .withCredentials({
        grant_type: 'client_credentials',
        client_id: process.env.KEYCLOAK_CLIENT_ID!,
        client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
      })
      .build();

    const sdkManager = InfoselSdkManager.initWithConfiguration({
      authConfiguration: authConfig,
    });

    this.widgetsSDK = InfoselWidgets.init({ sdkManager });
  }

  // Crear dashboard completo
  async createCompleteDashboard(userId: string, projectId: string) {
    try {
      // 1. Crear espacio de trabajo
      const workspace = await this.widgetsSDK.createWorkspace({
        name: 'Dashboard de Trading',
        description: 'Dashboard completo para análisis de mercado',
        userId,
        projectId,
      });

      // 2. Crear widget de gráfico para AAPL
      const chartWidget = await this.widgetsSDK.createWidget({
        workspaceId: workspace.id,
        type: 'CHART',
        name: 'Gráfico AAPL',
        instruments: [{ uniqueKey: 'AAPL_US', symbol: 'AAPL' }],
      });

      // 3. Crear widget de tabla para múltiples instrumentos
      const tableWidget = await this.widgetsSDK.createWidget({
        workspaceId: workspace.id,
        type: 'DYNAMIC_TABLE',
        name: 'Portafolio',
        instruments: [
          { uniqueKey: 'AAPL_US', symbol: 'AAPL' },
          { uniqueKey: 'MSFT_US', symbol: 'MSFT' },
          { uniqueKey: 'GOOGL_US', symbol: 'GOOGL' },
        ],
      });

      // 4. Crear widget de noticias
      const newsWidget = await this.widgetsSDK.createWidget({
        workspaceId: workspace.id,
        type: 'NEWS_LIST',
        name: 'Noticias Financieras',
        newsConfiguration: {
          period: 12,
          listType: 9,
          limit: 20,
          offset: 0,
          sourcesId: '',
          newsTypeId: '',
        },
      });

      return {
        workspace,
        widgets: [chartWidget, tableWidget, newsWidget],
      };
    } catch (error) {
      console.error('Error creando dashboard:', error);
      throw error;
    }
  }

  // Duplicar workspace completo
  async duplicateWorkspaceWithWidgets(workspaceId: string, newName: string) {
    try {
      // 1. Obtener workspace original
      const originalWorkspace = await this.widgetsSDK.getWorkspace({
        workspaceId,
      });

      // 2. Duplicar workspace
      const duplicatedWorkspace = await this.widgetsSDK.duplicateWorkspace({
        id: workspaceId,
        name: newName,
      });

      return duplicatedWorkspace;
    } catch (error) {
      console.error('Error duplicando workspace:', error);
      throw error;
    }
  }
}

// Uso del dashboard
async function main() {
  const dashboard = new WidgetsDashboard();

  try {
    // Crear dashboard completo
    const result = await dashboard.createCompleteDashboard(
      'user-123',
      'project-123',
    );
    console.log('Dashboard creado:', result);

    // Duplicar workspace
    const duplicated = await dashboard.duplicateWorkspaceWithWidgets(
      result.workspace.id,
      'Copia del Dashboard',
    );
    console.log('Workspace duplicado:', duplicated);
  } catch (error) {
    console.error('Error en main:', error);
  }
}

main();
```

### 🎯 Gestor de Widgets Avanzado

```typescript
class AdvancedWidgetManager {
  private widgetsSDK: InfoselWidgets;

  constructor(widgetsSDK: InfoselWidgets) {
    this.widgetsSDK = widgetsSDK;
  }

  // Crear widget de gráfico con configuración
  async createChartWidget(
    workspaceId: string,
    instrument: string,
    name: string,
  ) {
    try {
      const widget = await this.widgetsSDK.createWidget({
        workspaceId,
        type: 'CHART',
        name,
        instruments: [{ uniqueKey: instrument, symbol: instrument }],
        sizes: {
          create: {
            node: {
              width: 800,
              height: 600,
              minWidth: 400,
              minHeight: 300,
              maxWidth: 1200,
              maxHeight: 900,
              x: 0,
              y: 0,
            },
          },
        },
      });

      return widget;
    } catch (error) {
      console.error('Error creando widget de gráfico:', error);
      throw error;
    }
  }

  // Crear widget de tabla con múltiples instrumentos
  async createTableWidget(
    workspaceId: string,
    instruments: string[],
    name: string,
  ) {
    try {
      const widget = await this.widgetsSDK.createWidget({
        workspaceId,
        type: 'DYNAMIC_TABLE',
        name,
        instruments: instruments.map(instrument => ({
          uniqueKey: instrument,
          symbol: instrument,
        })),
      });

      return widget;
    } catch (error) {
      console.error('Error creando widget de tabla:', error);
      throw error;
    }
  }

  // Actualizar instrumentos de un widget
  async updateWidgetInstruments(widgetId: string, instruments: string[]) {
    try {
      const updatedInstruments = await this.widgetsSDK.updateWidgetInstruments({
        widgetId,
        instruments: { keys: instruments },
      });

      return updatedInstruments;
    } catch (error) {
      console.error('Error actualizando instrumentos:', error);
      throw error;
    }
  }

  // Duplicar widget a otro workspace
  async duplicateWidgetToWorkspace(
    widgetId: string,
    targetWorkspaceId: string,
    newName?: string,
  ) {
    try {
      const duplicatedWidget = await this.widgetsSDK.duplicateWidget({
        widgetId,
        workspaceId: targetWorkspaceId,
        name: newName || `Copia de Widget ${widgetId}`,
      });

      return duplicatedWidget;
    } catch (error) {
      console.error('Error duplicando widget:', error);
      throw error;
    }
  }

  // Eliminar widget
  async deleteWidget(widgetId: string) {
    try {
      const result = await this.widgetsSDK.deleteWidget(widgetId);
      return result;
    } catch (error) {
      console.error('Error eliminando widget:', error);
      throw error;
    }
  }
}

// Uso del gestor de widgets
const widgetManager = new AdvancedWidgetManager(widgetsSDK);

// Crear widgets en un workspace
async function setupWorkspaceWidgets(workspaceId: string) {
  try {
    // Widget de gráfico para AAPL
    const chartWidget = await widgetManager.createChartWidget(
      workspaceId,
      'AAPL_US',
      'Gráfico de Apple',
    );

    // Widget de tabla para portafolio
    const tableWidget = await widgetManager.createTableWidget(
      workspaceId,
      ['AAPL_US', 'MSFT_US', 'GOOGL_US'],
      'Portafolio Principal',
    );

    console.log('Widgets creados:', { chartWidget, tableWidget });
    return { chartWidget, tableWidget };
  } catch (error) {
    console.error('Error configurando widgets:', error);
    throw error;
  }
}
```

### 🏢 Gestor de Espacios de Trabajo

```typescript
class WorkspaceManager {
  private widgetsSDK: InfoselWidgets;

  constructor(widgetsSDK: InfoselWidgets) {
    this.widgetsSDK = widgetsSDK;
  }

  // Crear workspace con widgets iniciales
  async createWorkspaceWithWidgets(
    name: string,
    description: string,
    userId: string,
    projectId: string,
    initialInstruments: string[] = [],
  ) {
    try {
      // 1. Crear workspace
      const workspace = await this.widgetsSDK.createWorkspace({
        name,
        description,
        userId,
        projectId,
      });

      // 2. Crear widgets iniciales si hay instrumentos
      const widgets = [];
      if (initialInstruments.length > 0) {
        const chartWidget = await this.widgetsSDK.createWidget({
          workspaceId: workspace.id,
          type: 'CHART',
          name: 'Gráfico Principal',
          instruments: initialInstruments.map(instrument => ({
            uniqueKey: instrument,
            symbol: instrument,
          })),
        });
        widgets.push(chartWidget);
      }

      return { workspace, widgets };
    } catch (error) {
      console.error('Error creando workspace con widgets:', error);
      throw error;
    }
  }

  // Obtener todos los workspaces de un usuario
  async getUserWorkspaces(userId: string) {
    try {
      const workspaces = await this.widgetsSDK.getWorkspacesByUser({
        userId,
      });

      return workspaces;
    } catch (error) {
      console.error('Error obteniendo workspaces del usuario:', error);
      throw error;
    }
  }

  // Actualizar workspace
  async updateWorkspace(
    workspaceId: string,
    updates: { name?: string; description?: string },
  ) {
    try {
      const updatedWorkspace = await this.widgetsSDK.updateWorkspace({
        id: workspaceId,
        ...updates,
      });

      return updatedWorkspace;
    } catch (error) {
      console.error('Error actualizando workspace:', error);
      throw error;
    }
  }

  // Duplicar workspace completo
  async duplicateWorkspace(workspaceId: string, newName: string) {
    try {
      const duplicatedWorkspace = await this.widgetsSDK.duplicateWorkspace({
        id: workspaceId,
        name: newName,
      });

      return duplicatedWorkspace;
    } catch (error) {
      console.error('Error duplicando workspace:', error);
      throw error;
    }
  }

  // Eliminar workspace
  async deleteWorkspace(workspaceId: string) {
    try {
      const result = await this.widgetsSDK.deleteWorkspace({
        id: workspaceId,
      });

      return result;
    } catch (error) {
      console.error('Error eliminando workspace:', error);
      throw error;
    }
  }
}

// Uso del gestor de workspaces
const workspaceManager = new WorkspaceManager(widgetsSDK);

// Crear workspace con widgets iniciales
async function createUserDashboard(userId: string, projectId: string) {
  try {
    const result = await workspaceManager.createWorkspaceWithWidgets(
      'Mi Dashboard Personal',
      'Dashboard para análisis de mercado',
      userId,
      projectId,
      ['AAPL_US', 'MSFT_US', 'GOOGL_US'],
    );

    console.log('Dashboard creado:', result);
    return result;
  } catch (error) {
    console.error('Error creando dashboard:', error);
    throw error;
  }
}
```

## 📚 Referencia de API

### Clases Principales

#### `InfoselWidgets`

Punto de entrada principal para el SDK de Widgets. Se inicializa usando el método estático `init()` que recibe el `InfoselSdkManager`.

#### `InfoselSdkManager`

Gestor central del SDK que maneja la configuración, autenticación y modo de operación. Se inicializa usando el método estático `initWithConfiguration()` con configuración moderna o `init()` con configuración legacy.

#### `AuthConfigurationBuilder`

Builder para crear configuraciones de autenticación validadas y centralizadas. Proporciona una API fluida para configurar autenticación KeyCloak y basada en tokens.

#### `WidgetsMapper`

Mapeador de datos para convertir entre modelos de API y dominio.

### Métodos Disponibles

#### 🏢 Gestión de Espacios de Trabajo

| Método                       | Descripción                                         | Parámetros                   |
| ---------------------------- | --------------------------------------------------- | ---------------------------- |
| `createWorkspace()`          | Crear nuevo espacio de trabajo                      | `CreateWorkspaceRequest`     |
| `getWorkspaces()`            | Obtener espacios de trabajo de un proyecto          | `GetWorkspacesRequest`       |
| `getWorkspacesByUser()`      | Obtener espacios de trabajo del usuario             | `GetWorkspacesByUserRequest` |
| `getUserWorkspaces()`        | Obtener espacios de trabajo específicos del usuario | `GetUserWorkspacesRequest`   |
| `getWorkspacesByProjectId()` | Obtener espacios de trabajo por ID de proyecto      | `GetWorkspacesRequest`       |
| `getWorkspace()`             | Obtener detalles del workspace                      | `GetWorkspaceRequest`        |
| `updateWorkspace()`          | Actualizar espacio de trabajo                       | `UpdateWorkspaceRequest`     |
| `duplicateWorkspace()`       | Duplicar espacio de trabajo                         | `DuplicateWorkspaceRequest`  |
| `deleteWorkspace()`          | Eliminar espacio de trabajo                         | `DeleteWorkspaceRequest`     |

#### 🎯 Gestión de Widgets

| Método                      | Descripción                          | Parámetros                       |
| --------------------------- | ------------------------------------ | -------------------------------- |
| `createWidget()`            | Crear nuevo widget                   | `CreateWidgetRequest`            |
| `duplicateWidget()`         | Duplicar widget                      | `DuplicateWidgetRequest`         |
| `updateWidgetInstruments()` | Actualizar instrumentos del widget   | `UpdateWidgetInstrumentsRequest` |
| `updateWidgetChart()`       | Actualizar configuración del gráfico | `UpdateWidgetChartRequest`       |
| `deleteWidget()`            | Eliminar widget                      | `string` (ID)                    |
| `getProjectWidgets()`       | Obtener widgets del proyecto         | `GetProjectWidgetsRequest`       |
| `getUserWidgets()`          | Obtener widgets del usuario          | `GetUserWidgetsRequest`          |

#### 🔧 Gestión de Instrumentos

| Método               | Descripción                   | Parámetros                |
| -------------------- | ----------------------------- | ------------------------- |
| `createInstrument()` | Crear nuevo instrumento       | `CreateInstrumentRequest` |
| `deleteInstrument()` | Eliminar instrumento          | `string` (ID)             |
| `getInstruments()`   | Obtener lista de instrumentos | `GetInstrumentsRequest`   |

### Entidades

#### Entidades Principales

- `Widget`: Configuración y datos del widget
- `Workspace`: Espacio de trabajo del usuario
- `Instrument`: Representación de instrumento financiero
- `WorkspaceWidgets`: Workspace con sus widgets asociados
- `UserWidgets`: Widgets del usuario
- `UserWorkspaces`: Espacios de trabajo del usuario
- `ProjectWidgetsContainer`: Contenedor de widgets del proyecto
- `WorkspacesContainer`: Contenedor de espacios de trabajo
- `InstrumentsResponse`: Respuesta con lista de instrumentos

#### Entidades de Solicitud/Respuesta

- `CreateWidgetRequest`: Parámetros de creación de widget
- `CreateWorkspaceRequest`: Parámetros de creación de espacio de trabajo
- `CreateInstrumentRequest`: Parámetros de creación de instrumento
- `UpdateWidgetInstrumentsRequest`: Parámetros de actualización de instrumentos
- `UpdateWidgetChartRequest`: Parámetros de actualización de gráfico
- `UpdateWorkspaceRequest`: Parámetros de actualización de workspace
- `DuplicateWidgetRequest`: Parámetros de duplicación de widget
- `DuplicateWorkspaceRequest`: Parámetros de duplicación de workspace
- `DeleteWorkspaceRequest`: Parámetros de eliminación de workspace
- `GetWorkspaceRequest`: Parámetros para obtener workspace
- `GetWorkspacesRequest`: Parámetros para obtener workspaces
- `GetWorkspacesByUserRequest`: Parámetros para obtener workspaces por usuario
- `GetUserWorkspacesRequest`: Parámetros para obtener workspaces del usuario
- `GetUserWidgetsRequest`: Parámetros para obtener widgets del usuario
- `GetProjectWidgetsRequest`: Parámetros para obtener widgets del proyecto
- `GetInstrumentsRequest`: Parámetros para obtener instrumentos

#### Tipos de Widgets

- `FINANCIAL_STATEMENTS`: Estados financieros
- `DYNAMIC_TABLE`: Tabla dinámica con datos en tiempo real
- `PREDEFINED_TABLE`: Tabla predefinida con estructura fija
- `CUSTOM_TABLE`: Tabla personalizable
- `NEWS_LIST`: Lista de noticias financieras
- `TICKER_TAPE`: Cinta de ticker con precios
- `CHART`: Gráfico de precios y volúmenes
- `SHORT_SALES`: Ventas en corto
- `MARKET_TOTAL`: Total de mercado
- `TRADED_PACKAGES`: Paquetes negociados
- `BROKERAGE_TRADES`: Operaciones de corretaje
- `BROKERAGE_CONCENTRATION`: Concentración de corretaje
- `BROKERAGE_PARTICIPATION`: Participación de corretaje
- `DECREED_RIGHTS_SEARCHER`: Buscador de derechos decretados
- `INDICES_COMPONENTS`: Componentes de índices

## 🔗 Dependencias

- `@infosel-sdk/core`: Funcionalidad core del SDK (versión ^0.0.5)
- `dayjs`: Manejo de fechas y horas
- `tslib`: Biblioteca runtime de TypeScript

## 🆕 Novedades en Core v0.0.5

### ✨ Configuration Builder Pattern

- **Nueva API fluida** para configuración sin duplicaciones
- **Validaciones centralizadas** con mensajes de error descriptivos
- **Single source of truth** para configuración de realm
- **Compatibilidad hacia atrás** mantenida

### 🔧 Mejoras en Configuración

- **Configuración dinámica de realm** para múltiples ambientes
- **Validación de formatos** de realm, client_id y credenciales
- **Valores por defecto inteligentes** basados en el tipo de autenticación
- **Type safety mejorado** con TypeScript

## 🧪 Testing

### Pruebas Unitarias

```bash
# Ejecutar tests unitarios
npm test

# Ejecutar tests con cobertura
npm run test:coverage
```

## 📞 Soporte

Para soporte y preguntas, por favor contacta al equipo de desarrollo de Infosel.

## 🔗 Paquetes Relacionados

- `@infosel-sdk/core`: Funcionalidad core del SDK (versión ^0.0.5)
- `@infosel-sdk/markets`: SDK de mercados financieros
- `@infosel-sdk/news`: SDK de noticias y contenido
- `@infosel-sdk/securities`: SDK de valores y trading

---