npm package: @infosel-sdk/calendar
Description: Economic calendar SDK for Infosel platform. Provides tools for accessing and managing economic calendar data, including events, dates, and economic indicators.
Author: Infosel Team
Latest version: 0.1.0

# @infosel-sdk/calendar

[![npm version](https://badge.fury.io/js/@infosel-sdk%2Fcalendar.svg)](https://badge.fury.io/js/@infosel-sdk%2Fcalendar)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)

SDK de Calendario Económico para la plataforma de servicios financieros Infosel. Proporciona herramientas para acceder y gestionar datos del calendario económico, incluyendo eventos económicos, fechas e indicadores económicos.

## 🚀 Características

- **📅 Calendario Económico**: Acceso completo a eventos económicos y sus detalles
- **🌍 Información por País**: Datos de eventos económicos filtrados por país
- **📊 Indicadores Económicos**: Valores actuales, previos y unidades de medida
- **🔍 Filtrado por Fechas**: Consultas por rangos de fechas con paginación
- **⚡ Integración Core**: Completamente integrado con @infosel-sdk/core
- **🌍 Multi-Ambiente**: Soporte para QA, preproducción y producción

## 📦 Instalación

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

### Dependencias

- **@infosel-sdk/core**: ^0.0.5 (requerido como peer dependency)
- **tslib**: ^2.8.1 (para TypeScript)

## 🔧 Prerrequisitos

Este SDK requiere que el paquete `@infosel-sdk/core` esté instalado y configurado:

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

## 🏗️ Configuración

### Configurar el SDK Core

Primero, necesitas configurar el SDK Core con autenticación:

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

// Configurar autenticación KeyCloak
const authConfig = AuthConfigurationBuilder
  .keyCloak()
  .withRealm('calendar-realm')
  .withEnvironment('qa') // o 'preprod', 'prod'
  .withCredentials({
    grant_type: 'client_credentials',
    client_id: 'your-calendar-client',
    client_secret: 'your-calendar-secret',
  })
  .build();

// Inicializar el SDK Core
const sdkManager = InfoselSdkManager.initWithConfiguration({
  authConfiguration: authConfig,
});

// Inicializar el SDK de Calendario Económico
const calendarSDK = InfoselEconomicCalendar.init({
  sdkManager,
});
```

### Configuración con Modo Legacy

```typescript
import { InfoselSdkManager } from '@infosel-sdk/core';
import InfoselEconomicCalendar from '@infosel-sdk/calendar';

// Inicializar el gestor del SDK
const sdkManager = InfoselSdkManager.init({
  mode: 'prod', // 'qa', 'preprod', o 'prod'
  realm: 'your-realm',
  authProviderConfig: {
    type: 'key-cloak',
    credentials: {
      grant_type: 'client_credentials',
      client_id: 'your-client-id',
      client_secret: 'your-client-secret',
    },
  },
});

// Inicializar el SDK de Calendario Económico
const calendarSDK = InfoselEconomicCalendar.init({
  sdkManager,
});
```

## 📚 Referencia de la API

### Métodos Disponibles

#### `getEconomicCalendar(request: GetEconomicCalendarRequest)`

Obtiene eventos del calendario económico basados en un rango de fechas y parámetros de paginación opcionales.

**Parámetros:**

```typescript
type GetEconomicCalendarRequest = {
  readonly startDate: string;  // Fecha de inicio (formato ISO 8601: YYYY-MM-DD)
  readonly endDate: string;    // Fecha de fin (formato ISO 8601: YYYY-MM-DD)
  readonly limit?: number;     // Número máximo de resultados (opcional)
  readonly offset?: number;   // Desplazamiento para paginación (opcional)
};
```

**Retorna:**

```typescript
Promise<EconomicCalendar[]>
```

**Tipo de Respuesta:**

```typescript
type EconomicCalendar = {
  readonly id: number;              // ID único del evento
  readonly date: string;             // Fecha del evento (formato ISO 8601)
  readonly title: string;            // Título del evento económico
  readonly description: string;      // Descripción detallada del evento
  readonly currentValue: string;      // Valor actual del indicador
  readonly previousValue: string;    // Valor previo del indicador
  readonly units: string;            // Unidades de medida (ej: "USD", "%", "Index")
  readonly countryId: number;        // ID del país asociado
  readonly countryName: string;     // Nombre del país
};

type Country = {
  readonly id: number;
  readonly name: string;
};
```

## 💡 Ejemplos de Uso

### Ejemplo 1: Obtener Eventos del Calendario Económico

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

// Configurar SDK
const authConfig = AuthConfigurationBuilder
  .keyCloak()
  .withRealm('calendar-realm')
  .withEnvironment('prod')
  .withCredentials({
    grant_type: 'client_credentials',
    client_id: 'your-client-id',
    client_secret: 'your-client-secret',
  })
  .build();

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

const calendarSDK = InfoselEconomicCalendar.init({
  sdkManager,
});

// Obtener eventos del calendario económico
try {
  const events = await calendarSDK.getEconomicCalendar({
    startDate: '2024-01-01',
    endDate: '2024-01-31',
  });

  console.log(`Se encontraron ${events.length} eventos económicos`);
  
  events.forEach((event) => {
    console.log(`
      Fecha: ${event.date}
      Título: ${event.title}
      País: ${event.countryName}
      Valor Actual: ${event.currentValue} ${event.units}
      Valor Previo: ${event.previousValue} ${event.units}
    `);
  });
} catch (error) {
  console.error('Error al obtener el calendario económico:', error);
}
```

### Ejemplo 2: Consulta con Paginación

```typescript
// Primera página (primeros 20 resultados)
const firstPage = await calendarSDK.getEconomicCalendar({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  limit: 20,
  offset: 0,
});

console.log(`Primera página: ${firstPage.length} eventos`);

// Segunda página (siguientes 20 resultados)
const secondPage = await calendarSDK.getEconomicCalendar({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  limit: 20,
  offset: 20,
});

console.log(`Segunda página: ${secondPage.length} eventos`);
```

### Ejemplo 3: Filtrar Eventos por País

```typescript
// Obtener todos los eventos y filtrar por país específico
const allEvents = await calendarSDK.getEconomicCalendar({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
});

// Filtrar eventos de Estados Unidos (asumiendo countryId: 1)
const usEvents = allEvents.filter((event) => event.countryId === 1);

console.log(`Eventos de Estados Unidos: ${usEvents.length}`);

// Filtrar eventos de México (asumiendo countryId: 2)
const mexicoEvents = allEvents.filter((event) => event.countryId === 2);

console.log(`Eventos de México: ${mexicoEvents.length}`);
```

### Ejemplo 4: Obtener Eventos de la Semana Actual

```typescript
// Calcular fechas de inicio y fin de la semana actual
const today = new Date();
const startOfWeek = new Date(today);
startOfWeek.setDate(today.getDate() - today.getDay()); // Domingo de esta semana

const endOfWeek = new Date(startOfWeek);
endOfWeek.setDate(startOfWeek.getDate() + 6); // Sábado de esta semana

// Formatear fechas como YYYY-MM-DD
const formatDate = (date: Date): string => {
  return date.toISOString().split('T')[0];
};

const weekEvents = await calendarSDK.getEconomicCalendar({
  startDate: formatDate(startOfWeek),
  endDate: formatDate(endOfWeek),
});

console.log(`Eventos económicos de esta semana: ${weekEvents.length}`);
weekEvents.forEach((event) => {
  console.log(`${event.date}: ${event.title} (${event.countryName})`);
});
```

### Ejemplo 5: Análisis de Indicadores Económicos

```typescript
// Obtener eventos y analizar cambios en indicadores
const events = await calendarSDK.getEconomicCalendar({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
});

// Agrupar eventos por país
const eventsByCountry = events.reduce((acc, event) => {
  if (!acc[event.countryName]) {
    acc[event.countryName] = [];
  }
  acc[event.countryName].push(event);
  return acc;
}, {} as Record<string, typeof events>);

// Mostrar estadísticas por país
Object.entries(eventsByCountry).forEach(([country, countryEvents]) => {
  console.log(`
    País: ${country}
    Total de eventos: ${countryEvents.length}
    Eventos con valores: ${countryEvents.filter(e => e.currentValue && e.previousValue).length}
  `);
});

// Encontrar eventos con cambios significativos
const significantChanges = events.filter((event) => {
  if (!event.currentValue || !event.previousValue) return false;
  
  const current = parseFloat(event.currentValue);
  const previous = parseFloat(event.previousValue);
  
  if (isNaN(current) || isNaN(previous)) return false;
  
  const changePercent = ((current - previous) / previous) * 100;
  return Math.abs(changePercent) > 5; // Cambio mayor al 5%
});

console.log(`Eventos con cambios significativos: ${significantChanges.length}`);
```

## 🔍 Tipos y Entidades

### Tipos Exportados

El SDK exporta los siguientes tipos para su uso en TypeScript:

```typescript
// Importar tipos
import type {
  EconomicCalendar,
  GetEconomicCalendarRequest,
  Country,
} from '@infosel-sdk/calendar';

// Usar en tu código
const request: GetEconomicCalendarRequest = {
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  limit: 50,
  offset: 0,
};

const events: EconomicCalendar[] = await calendarSDK.getEconomicCalendar(request);
```

## 🌍 Ambientes Disponibles

El SDK soporta tres ambientes diferentes:

- **QA**: `https://api-qa.infosel.com/calendar/api/v1`
- **Preproducción**: `https://api-pre.infosel.com/calendar/api/v1`
- **Producción**: `https://api.infosel.com/calendar/api/v1`

El ambiente se configura automáticamente según el `mode` del `InfoselSdkManager`:

```typescript
// QA
const sdkManager = InfoselSdkManager.init({
  mode: 'qa',
  // ...
});

// Preproducción
const sdkManager = InfoselSdkManager.init({
  mode: 'preprod',
  // ...
});

// Producción
const sdkManager = InfoselSdkManager.init({
  mode: 'prod',
  // ...
});
```

## 🚨 Manejo de Errores

El SDK utiliza el sistema de manejo de errores de `@infosel-sdk/core`. Los errores pueden ser de tipo:

- **Errores de autenticación**: Cuando las credenciales son inválidas
- **Errores de red**: Cuando hay problemas de conectividad
- **Errores de validación**: Cuando los parámetros de la petición son inválidos
- **Errores del servidor**: Cuando el servidor retorna un error

```typescript
try {
  const events = await calendarSDK.getEconomicCalendar({
    startDate: '2024-01-01',
    endDate: '2024-01-31',
  });
} catch (error) {
  if (error instanceof Error) {
    console.error('Error:', error.message);
    // Manejar diferentes tipos de errores
  }
}
```

## 📝 Notas Importantes

1. **Formato de Fechas**: Las fechas deben estar en formato ISO 8601 (`YYYY-MM-DD`)
2. **Paginación**: Usa `limit` y `offset` para paginar resultados grandes
3. **Autenticación**: Asegúrate de que el SDK Core esté correctamente configurado antes de usar el SDK de Calendar
4. **Ambientes**: El ambiente se determina automáticamente por el `mode` del SDK Manager

## 🤝 Contribuir

Las contribuciones son bienvenidas. Por favor, lee las guías de contribución del proyecto antes de enviar un pull request.

## 📄 Licencia

Este proyecto está licenciado bajo la Licencia MIT - ver el archivo [LICENSE.md](LICENSE.md) para más detalles.

## 🔗 Enlaces Relacionados

- [@infosel-sdk/core](../core/README.md) - SDK Core para autenticación y configuración
- [Documentación de la API](https://docs.infosel.com) - Documentación completa de la API
- [NPM Package](https://www.npmjs.com/package/@infosel-sdk/calendar) - Paquete en NPM