127 lines
7.2 KiB
Markdown
127 lines
7.2 KiB
Markdown
# @suaveplan/currency-providers - Universal slim core for currency providers: CurrencyProviderRegistry, defineCurrencyProvider factory, shared httpRequest/composeAbortSignal helper, typed CurrencyProviderError + 8-code registry, and the ApiKeyConfig / NoKeyConfig / HttpFetchOptions / ProviderConfigBase shared types. Concrete providers (ECB, Fixer, Open Exchange Rates, Binance, CoinGecko, CoinMarketCap, CryptoCompare, Kraken, Virtual) ship as sibling @suaveplan/currency-provider-<name> packages.
|
|
|
|
Slim plugin core for `@suaveplan/currency` rate providers. Ships the
|
|
`CurrencyProviderRegistry` (name-keyed lookup), the
|
|
`defineCurrencyProvider` factory, the shared `httpRequest` /
|
|
`composeAbortSignal` helper, the typed `CurrencyProviderError` with the
|
|
8-code `CURRENCY_PROVIDER_*` registry, and the four shared config types
|
|
(`ApiKeyConfig`, `NoKeyConfig`, `HttpFetchOptions`, `ProviderConfigBase`)
|
|
that every sibling provider extends.
|
|
|
|
The concrete provider classes (ECB, Fixer, Open Exchange Rates, Binance,
|
|
CoinGecko, CoinMarketCap, CryptoCompare, Kraken, Virtual) live in
|
|
sibling `@suaveplan/currency-provider-<name>` packages — install only the
|
|
ones you wire in.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `CURRENCY_PROVIDER_CODES` registry and the `CurrencyProviderError` class every provider in `@suavepl…
|
|
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `CURRENCY_PROVIDER_CODES` registry and the `CurrencyProviderError` class every provider in `@suavepl…
|
|
- [factory](./src/factory/factory.md) — Exposes `defineCurrencyProvider`, the low-ceremony factory that sibling `@suaveplan/currency-provider-<name>` packages…
|
|
- [factory](./src/factory/factory.md) — Exposes `defineCurrencyProvider`, the low-ceremony factory that sibling `@suaveplan/currency-provider-<name>` packages…
|
|
- [http](./src/http/http.md) — Exposes the two HTTP utilities every sibling `@suaveplan/currency-provider-<name>` package repeats: `httpRequest` (an a…
|
|
- [http](./src/http/http.md) — Exposes the two HTTP utilities every sibling `@suaveplan/currency-provider-<name>` package repeats: `httpRequest` (an a…
|
|
- [registry](./src/registry/registry.md) — Defines `CurrencyProviderRegistry`, the in-memory registry that sibling `@suaveplan/currency-provider-<name>` packages…
|
|
- [registry](./src/registry/registry.md) — Defines `CurrencyProviderRegistry`, the in-memory registry that sibling `@suaveplan/currency-provider-<name>` packages…
|
|
- [types](./src/types/configs.md) — Defines the three configuration interfaces every concrete provider in `@suaveplan/currency-providers` consumes: `ApiKey…
|
|
- [configs](./src/types/configs.md) — Defines the three configuration interfaces every concrete provider in `@suaveplan/currency-providers` consumes: `ApiKey…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/currency-providers @suaveplan/currency
|
|
# plus whichever sibling provider packages you need:
|
|
bun add @suaveplan/currency-provider-ecb @suaveplan/currency-provider-coingecko
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```ts
|
|
import { CurrencyConverter } from "@suaveplan/currency";
|
|
import { CurrencyProviderRegistry } from "@suaveplan/currency-providers";
|
|
import { EcbProvider } from "@suaveplan/currency-provider-ecb";
|
|
import { CoinGeckoProvider } from "@suaveplan/currency-provider-coingecko";
|
|
|
|
const registry = new CurrencyProviderRegistry();
|
|
registry.register(new EcbProvider());
|
|
registry.register(new CoinGeckoProvider());
|
|
|
|
const converter = new CurrencyConverter({
|
|
provider: registry.get("ecb"),
|
|
fallbackProviders: [registry.get("coingecko")],
|
|
});
|
|
|
|
const rate = await converter.getRate("USD", "EUR");
|
|
```
|
|
|
|
Direct instantiation without the registry is equally supported — the
|
|
registry is a convenience for callers that wire many providers and want a
|
|
single lookup surface. Sibling packages remain `CurrencyProvider`-compatible
|
|
so `new CurrencyConverter({ provider: new EcbProvider() })` continues to work.
|
|
|
|
## Features
|
|
|
|
- `CurrencyProviderRegistry` — register / get / has / list / unregister.
|
|
Typed `PROVIDER_NOT_REGISTERED` / `PROVIDER_ALREADY_REGISTERED` errors;
|
|
`list()` returns a sorted snapshot for deterministic downstream tests
|
|
- `defineCurrencyProvider` — factory for sibling packages that prefer the
|
|
object-literal idiom over a hand-rolled class. Returns an
|
|
`Object.freeze`-d `CurrencyProvider`
|
|
- `httpRequest` — shared HTTP helper used by every sibling provider:
|
|
abort-signal composition, timeout derivation, non-2xx → `HTTP_ERROR`
|
|
mapping, returns the raw `Response`
|
|
- `composeAbortSignal` — pure four-way composition of caller + timeout
|
|
`AbortSignal`s (`undefined`, single, single, `AbortSignal.any`)
|
|
- Typed `CurrencyProviderError` extending `SuaveplanError` with 8 stable
|
|
codes (`HTTP_ERROR`, `PARSE_ERROR`, `UPSTREAM_ERROR`, `UNSUPPORTED_BASE`,
|
|
`MISSING_CONFIG`, `UNKNOWN_CURRENCY`, `PROVIDER_NOT_REGISTERED`,
|
|
`PROVIDER_ALREADY_REGISTERED`)
|
|
- Shared config types — `ApiKeyConfig`, `NoKeyConfig`, `HttpFetchOptions`,
|
|
`ProviderConfigBase` with optional injectable `FetchLike`
|
|
- Universal — zero browser/Node APIs, runs unchanged under Node ≥ 18,
|
|
Bun, modern browsers, and Web Workers
|
|
- Five subpath exports; explicit named barrels; 100/100/100/100 istanbul
|
|
coverage
|
|
|
|
## Modules
|
|
|
|
- [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) —
|
|
`CURRENCY_PROVIDER_CODES` registry + `CurrencyProviderError` class
|
|
- [`src/types/configs.md`](./src/types/configs.md) — `ApiKeyConfig`,
|
|
`NoKeyConfig`, `HttpFetchOptions`, `ProviderConfigBase`
|
|
- [`src/registry/registry.md`](./src/registry/registry.md) —
|
|
`CurrencyProviderRegistry`
|
|
- [`src/factory/factory.md`](./src/factory/factory.md) —
|
|
`defineCurrencyProvider` factory + `DefineCurrencyProviderInput`
|
|
- [`src/http/http.md`](./src/http/http.md) — `httpRequest` +
|
|
`composeAbortSignal` shared HTTP helpers
|
|
|
|
## Sibling provider packages
|
|
|
|
| Provider | Sibling package |
|
|
|--------------------------|-------------------------------------------------------|
|
|
| European Central Bank | `@suaveplan/currency-provider-ecb` |
|
|
| Fixer.io | `@suaveplan/currency-provider-fixer` |
|
|
| Open Exchange Rates | `@suaveplan/currency-provider-open-exchange-rates` |
|
|
| Binance | `@suaveplan/currency-provider-binance` |
|
|
| CoinGecko | `@suaveplan/currency-provider-coingecko` |
|
|
| CoinMarketCap | `@suaveplan/currency-provider-coinmarketcap` |
|
|
| CryptoCompare | `@suaveplan/currency-provider-cryptocompare` |
|
|
| Kraken | `@suaveplan/currency-provider-kraken` |
|
|
| Virtual (game / loyalty) | `@suaveplan/currency-provider-virtual` |
|
|
|
|
Each sibling depends on this slim core for the registry, factory, HTTP
|
|
helper, error class, and config types — and re-implements only its own
|
|
provider-specific logic.
|
|
|
|
## Status
|
|
|
|
`0.1.0` (pre-graduation). Slim refactor of the 2026-05-17 migration:
|
|
provider classes moved out to sibling packages; the registry / factory /
|
|
HTTP helper landed here. See
|
|
the design proposal for the
|
|
refactor record and migration notes.
|
|
|