@unirate/adonis
v0.1.0
Published
Official AdonisJS v6 provider for the UniRate currency-exchange API. Registers a singleton `unirate` client in the IoC container, a typed defineConfig, a `node ace configure` hook, and a container-service accessor.
Maintainers
Readme
@unirate/adonis
Official AdonisJS v6 provider for the
UniRate currency-exchange API. Registers a singleton
unirate client in the IoC container, ships a typed defineConfig, a
node ace configure hook, and a container-service accessor so you can
import unirate from '@unirate/adonis/services/main'.
UniRate offers free real-time exchange rates for 170+ currencies plus VAT data; historical rates and time-series are Pro-tier endpoints.
Install
npm install @unirate/adonis
node ace configure @unirate/adonisnode ace configure publishes config/unirate.ts, adds UNIRATE_API_KEY to
your .env validation, and registers the provider in adonisrc.ts.
@adonisjs/core ^6.2.0 is a peer dependency (use the version your app already
pins). Native fetch is required (Node ≥ 20.11). This package has zero
runtime dependencies.
Configuration
config/unirate.ts (published by the configure hook):
import env from '#start/env'
import { defineConfig } from '@unirate/adonis'
export default defineConfig({
apiKey: env.get('UNIRATE_API_KEY'),
// baseUrl: 'https://api.unirateapi.com', // rarely needed
// timeoutMs: 30000,
})Get a free API key at unirateapi.com.
Usage
Container-service accessor (simplest)
import router from '@adonisjs/core/services/router'
import unirate from '@unirate/adonis/services/main'
router.get('/convert', async ({ request }) => {
const { from = 'USD', to = 'EUR', amount = 1 } = request.qs()
return { result: await unirate.convert(to, Number(amount), from) }
})Dependency injection
import type { HttpContext } from '@adonisjs/core/http'
import { inject } from '@adonisjs/core'
import { UniRateClient } from '@unirate/adonis'
@inject()
export default class PricesController {
constructor(private unirate: UniRateClient) {}
async rates({ params }: HttpContext) {
return this.unirate.getRate(params.base) // { EUR: 0.92, ... }
}
}Resolve from the container by binding key
const client = await app.container.make('unirate') // typed as UniRateClient
const rate = await client.getRate('USD', 'EUR')The package augments @adonisjs/core/types's ContainerBindings so both the
'unirate' string key and the UniRateClient class resolve with full types.
UniRateClient API
| Method | Returns | Notes |
|---|---|---|
| getRate(from, to) | Promise<number> | Single pair |
| getRate(from) | Promise<Record<string, number>> | Full snapshot keyed by ISO code |
| convert(to, amount, from) | Promise<number> | |
| getSupportedCurrencies() | Promise<string[]> | |
| getVatRates(country?) | Promise<VATRatesAll \| VATRateOne> | |
| getHistoricalRate(date, amount, from, to?) | Promise<number \| Record<string, number>> | Pro |
| getTimeSeries(start, end, amount, base, currencies?) | Promise<Record<date, Record<currency, number>>> | Pro |
| getHistoricalLimits() | Promise<HistoricalLimitsResponse> | Pro |
Dates are YYYY-MM-DD. Currency and country codes are case-insensitive on
input and normalised to uppercase before being sent to the API.
Error handling
Every method throws typed error subclasses for the documented HTTP errors:
AuthenticationError— 401, bad / missing keyRateLimitError— 429InvalidCurrencyError— 404, unknown currency codeInvalidRequestError— 400, bad paramsProRequiredError— 403, endpoint requires a Pro subscriptionUniRateError— base class for any other failure (network, 503, malformed response, …)
import { RateLimitError, ProRequiredError } from '@unirate/adonis'
try {
await unirate.getHistoricalRate('2020-01-01', 1, 'USD', 'EUR')
} catch (err) {
if (err instanceof ProRequiredError) {
// upgrade prompt — historical is Pro-gated
} else if (err instanceof RateLimitError) {
// back off
}
}Rate limits
The free tier is rate-limited; a 429 surfaces as RateLimitError. Cache
snapshots (getRate(base) returns every pair in one call) and avoid tight
polling loops.
Standalone client
The underlying client is dependency-free and usable outside an Adonis context (CLI scripts, workers):
import { UniRateClient } from '@unirate/adonis/client'
const client = new UniRateClient({ apiKey: process.env.UNIRATE_API_KEY! })
const currencies = await client.getSupportedCurrencies()Other UniRate clients
UniRate ships official client libraries and framework integrations across the ecosystem. The repos below are all maintained under the UniRate-API org.
- Languages: Python · Node.js / TypeScript · Go · Rust · Java · Ruby · PHP · .NET · Swift
- Web frameworks: NestJS · AdonisJS · Django / Wagtail · FastAPI · Flask · React · tRPC
- Static-site generators: Astro · Eleventy · Hugo
- Data / orchestration: Airflow · dbt · LangChain
- Workflow / no-code: n8n · Google Sheets · MCP server
Get a free API key at unirateapi.com.
License
MIT © Unirate Team
