first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
# @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.