npm package: @jloria13/bccr-exchange-rates
Description: TypeScript library to fetch Costa Rican exchange rates from Banco Central de Costa Rica (BCCR)
Author: jloria13
Latest version: 1.0.2

# BCCR Exchange Rates

TypeScript library to fetch Costa Rican exchange rates from Banco Central de Costa Rica (BCCR).

This is a TypeScript port of the Python library [bccr-exchange-rates](https://github.com/jloria13/bccr-exchange-rates).

## Features

- Fetch current exchange rates from 39+ financial entities
- Retrieve historical exchange rate data
- Search and filter entities by name or type
- Support for both flat and hierarchical data formats
- Fully typed with TypeScript
- No authentication required
- Supports both ESM and CommonJS

## Installation

```bash
npm install @jloria13/bccr-exchange-rates
# or
pnpm add @jloria13/bccr-exchange-rates
# or
yarn add @jloria13/bccr-exchange-rates
```

## Quick Start

```typescript
import { getCurrentRates, getRatesByDate, searchEntities } from '@username/bccr-exchange-rates';

// Get current exchange rates
const rates = await getCurrentRates();
console.log(rates);

// Get historical rates for a specific date
const historicalRates = await getRatesByDate('2025-11-04');

// Search for specific entities
const bancoNacional = await searchEntities('Banco Nacional');
```

## API Reference

### `getCurrentRates(format?)`

Gets current exchange rates from BCCR.

**Parameters:**
- `format` (optional): `'flat'` (default) or `'hierarchical'`

**Returns:** `Promise<EntityData[] | HierarchicalData>`

**Example:**
```typescript
// Get flat list of all entities
const rates = await getCurrentRates();

// Get rates organized by entity type
const ratesByType = await getCurrentRates('hierarchical');
```

### `getRatesByDate(date, format?)`

Gets exchange rates for a specific date.

**Parameters:**
- `date`: Date in `YYYY-MM-DD` or `DD/MM/YYYY` format
- `format` (optional): `'flat'` (default) or `'hierarchical'`

**Returns:** `Promise<EntityData[] | HierarchicalData>`

**Throws:** `BCCRDateError` if date is invalid or out of range

**Example:**
```typescript
// Get rates for a specific date
const rates = await getRatesByDate('2025-11-04');

// Get rates organized by entity type
const ratesByType = await getRatesByDate('2025-11-04', 'hierarchical');
```

### `searchEntities(query, date?, format?)`

Searches for entities matching a query string.

**Parameters:**
- `query`: Search query (searches in entity name and type)
- `date` (optional): Date in `YYYY-MM-DD` or `DD/MM/YYYY` format
- `format` (optional): `'flat'` (default) or `'hierarchical'`

**Returns:** `Promise<EntityData[] | HierarchicalData>`

**Example:**
```typescript
// Search for entities containing "Nacional"
const results = await searchEntities('Nacional');

// Search in historical data
const historicalResults = await searchEntities('Banco', '2025-11-04');

// Search and organize by type
const resultsByType = await searchEntities('Banco', undefined, 'hierarchical');
```

### `getEntityByName(entityName, date?)`

Gets exchange rate data for a specific entity by name.

**Parameters:**
- `entityName`: Exact or partial entity name to search for
- `date` (optional): Date in `YYYY-MM-DD` or `DD/MM/YYYY` format

**Returns:** `Promise<EntityData | null>`

**Example:**
```typescript
// Get current rates for Banco Nacional
const entity = await getEntityByName('Banco Nacional');

// Get historical rates for a specific entity
const historicalEntity = await getEntityByName('Banco Nacional', '2025-11-04');
```

## Data Types

### `EntityData`

```typescript
interface EntityData {
  entity_type: string;        // e.g., "Bancos Estatales"
  entity_name: string;        // e.g., "Banco Nacional"
  buy_rate: number | null;    // Buy rate in colones
  sell_rate: number | null;   // Sell rate in colones
  spread: number | null;      // Differential
  last_update: string;        // ISO timestamp
  last_update_str: string;    // Original format
}
```

### `HierarchicalData`

```typescript
interface HierarchicalData {
  [entityType: string]: EntityData[];
}
```

## Error Handling

The library provides custom error types for different failure scenarios:

```typescript
import {
  BCCRError,
  BCCRScrapingError,
  BCCRDateError,
  BCCRConnectionError,
  BCCRParseError,
} from '@username/bccr-exchange-rates';

try {
  const rates = await getRatesByDate('2025-11-04');
} catch (error) {
  if (error instanceof BCCRDateError) {
    console.error('Invalid date:', error.message);
  } else if (error instanceof BCCRConnectionError) {
    console.error('Connection failed:', error.message);
  } else if (error instanceof BCCRScrapingError) {
    console.error('Scraping failed:', error.message);
  }
}
```

### Error Types

- **`BCCRError`**: Base error class for all BCCR-related errors
- **`BCCRScrapingError`**: Raised when scraping the BCCR website fails
- **`BCCRDateError`**: Raised when date validation or parsing fails
- **`BCCRConnectionError`**: Raised when connection to BCCR website fails
- **`BCCRParseError`**: Raised when parsing HTML response fails

## Entity Types

The BCCR provides exchange rates from the following entity types:

- Bancos Estatales (State Banks)
- Bancos Privados (Private Banks)
- Casas de Cambio (Exchange Houses)
- Financieras (Financial Companies)
- Cooperativas (Cooperatives)
- Fondos de Inversión (Mutual Funds)
- Puestos de Bolsa (Stock Brokers)

## Development

### Setup

```bash
pnpm install
```

### Build

```bash
pnpm build
```

### Test

```bash
# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run tests with UI
pnpm test:ui
```

### Type Check

```bash
pnpm type-check
```

## License

MIT

## Credits

Based on the Python library [bccr-exchange-rates](https://github.com/jloria13/bccr-exchange-rates) by @jloria13.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Disclaimer

This library is not officially affiliated with Banco Central de Costa Rica (BCCR). The data is scraped from their public website and is subject to their terms of use.