bnb-exchange-rate 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AllRatesToday (https://allratestoday.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Bulgarian National Bank Exchange Rate API client
2
+
3
+ Official **Bulgarian National Bank** (Bulgaria) daily exchange rates in Node.js / TypeScript — ~29 currencies against the EUR, with history back to 2016. Zero dependencies, works in Node 18+, Bun, Deno, and edge runtimes (uses global `fetch`).
4
+
5
+ These are the *published central bank rates* required for tax filings, customs valuations, audits, and compliant invoicing — not moving market rates. Every response carries the bank's own publication date.
6
+
7
+ Powered by [AllRatesToday](https://allratestoday.com/central-bank-rates-api/bnb/). Get a free API key at [allratestoday.com/register](https://allratestoday.com/register) — 300 requests/month, no credit card.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install bnb-exchange-rate
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```js
18
+ import { getRate, getLatestRates } from 'bnb-exchange-rate';
19
+
20
+ // One pair at the official Bulgarian National Bank rate
21
+ const pair = await getRate('EUR', 'USD', { apiKey: 'art_live_...' });
22
+ console.log(pair.rate, pair.rate_date); // e.g. EUR -> USD on the bank's own date
23
+
24
+ // The bank's full published table
25
+ const table = await getLatestRates({ apiKey: 'art_live_...' });
26
+ console.log(table.rate_date, table.rates.length);
27
+ ```
28
+
29
+ ## Historical data (paid plans)
30
+
31
+ ```js
32
+ import { getRatesForDate, getHistory } from 'bnb-exchange-rate';
33
+
34
+ // The official table for an invoice date — weekends/holidays return the
35
+ // most recent published date, flagged via published_on_requested_date.
36
+ const day = await getRatesForDate('2026-06-30', { apiKey: 'art_live_...' });
37
+
38
+ // Daily series for one pair
39
+ const series = await getHistory(
40
+ { source: 'EUR', target: 'USD', from: '2026-01-01' },
41
+ { apiKey: 'art_live_...' }
42
+ );
43
+ ```
44
+
45
+ ## Published vs derived rates
46
+
47
+ If Bulgarian National Bank does not print a pair directly, the API resolves it from the bank's table (inverse, or a cross rate via EUR) and flags it `derived: true` with the `method` — so official and computed values are never confused.
48
+
49
+ ## Notes
50
+
51
+ - Every request counts toward your AllRatesToday monthly quota. Rates change once per business day — cache a day's table locally and a small quota goes a long way.
52
+ - Latest rates are on every plan (including free); historical dates and time series need a [paid plan](https://allratestoday.com/pricing/).
53
+ - Full API reference: [allratestoday.com/docs#central-bank](https://allratestoday.com/docs/#central-bank) · All covered banks: [central bank rates API](https://allratestoday.com/central-bank-rates-api/)
54
+
55
+ ## License
56
+
57
+ MIT
package/index.cjs ADDED
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+ // Bulgarian National Bank exchange rates via the AllRatesToday API.
3
+ const BASE = 'https://allratestoday.com/api/v1/central-bank/bnb';
4
+ const KEY_HINT = 'An apiKey is required — get a free key at https://allratestoday.com/register (300 requests/month, no credit card).';
5
+
6
+ async function request(path, params, options) {
7
+ const apiKey = options && options.apiKey;
8
+ if (!apiKey) throw new Error(KEY_HINT);
9
+ const url = new URL(BASE + path);
10
+ for (const [k, v] of Object.entries(params || {})) {
11
+ if (v !== undefined && v !== null) url.searchParams.set(k, v);
12
+ }
13
+ const res = await fetch(url, { headers: { Authorization: 'Bearer ' + apiKey } });
14
+ let body;
15
+ try { body = await res.json(); } catch { body = {}; }
16
+ if (!res.ok) {
17
+ const err = new Error(body.error || ('Request failed: HTTP ' + res.status));
18
+ err.status = res.status;
19
+ err.body = body;
20
+ throw err;
21
+ }
22
+ return body;
23
+ }
24
+
25
+ /** Latest published table (all plans, including free). */
26
+ async function getLatestRates(options) {
27
+ return request('/latest', {}, options);
28
+ }
29
+
30
+ /** Latest rate for one pair, e.g. getRate('EUR', 'USD', { apiKey }). */
31
+ async function getRate(source, target, options) {
32
+ return request('/latest', { source, target }, options);
33
+ }
34
+
35
+ /** Published table for a date (YYYY-MM-DD). Paid plans. Weekends/holidays return the most recent published date. */
36
+ async function getRatesForDate(date, options) {
37
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(String(date))) throw new Error('date must be YYYY-MM-DD');
38
+ return request('/' + date, options && options.source ? { source: options.source, target: options.target } : {}, options);
39
+ }
40
+
41
+ /** Daily time series. Pass { symbol } or { source, target }, optional from/to (YYYY-MM-DD). Paid plans. */
42
+ async function getHistory(query, options) {
43
+ const { symbol, source, target, from, to } = query || {};
44
+ return request('/history', { symbol, source, target, from, to }, options);
45
+ }
46
+
47
+ module.exports = { getLatestRates, getRate, getRatesForDate, getHistory };
package/index.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ export interface RequestOptions {
2
+ /** AllRatesToday API key — free at https://allratestoday.com/register */
3
+ apiKey: string;
4
+ }
5
+
6
+ export interface RateEntry {
7
+ base: string;
8
+ quote: string;
9
+ type: string;
10
+ value: number;
11
+ }
12
+
13
+ export interface LatestRates {
14
+ bank: 'bnb';
15
+ name: string;
16
+ rate_date: string;
17
+ rates: RateEntry[];
18
+ disclaimer: string;
19
+ }
20
+
21
+ export interface PairRate {
22
+ bank: 'bnb';
23
+ name: string;
24
+ rate_date: string;
25
+ source: string;
26
+ target: string;
27
+ rate: number;
28
+ rate_type: string;
29
+ /** true when the pair was computed (inverse/cross) rather than published directly */
30
+ derived: boolean;
31
+ method: 'published' | 'inverse' | 'cross';
32
+ disclaimer: string;
33
+ }
34
+
35
+ export interface DatedRates extends Omit<LatestRates, 'rate_date'> {
36
+ requested_date: string;
37
+ rate_date: string;
38
+ published_on_requested_date: boolean;
39
+ }
40
+
41
+ export interface HistoryQuery {
42
+ symbol?: string;
43
+ source?: string;
44
+ target?: string;
45
+ from?: string;
46
+ to?: string;
47
+ }
48
+
49
+ export declare function getLatestRates(options: RequestOptions): Promise<LatestRates>;
50
+ export declare function getRate(source: string, target: string, options: RequestOptions): Promise<PairRate>;
51
+ export declare function getRatesForDate(date: string, options: RequestOptions & { source?: string; target?: string }): Promise<DatedRates>;
52
+ export declare function getHistory(query: HistoryQuery, options: RequestOptions): Promise<unknown>;
package/index.mjs ADDED
@@ -0,0 +1,44 @@
1
+ // Bulgarian National Bank exchange rates via the AllRatesToday API.
2
+ const BASE = 'https://allratestoday.com/api/v1/central-bank/bnb';
3
+ const KEY_HINT = 'An apiKey is required — get a free key at https://allratestoday.com/register (300 requests/month, no credit card).';
4
+
5
+ async function request(path, params, options) {
6
+ const apiKey = options && options.apiKey;
7
+ if (!apiKey) throw new Error(KEY_HINT);
8
+ const url = new URL(BASE + path);
9
+ for (const [k, v] of Object.entries(params || {})) {
10
+ if (v !== undefined && v !== null) url.searchParams.set(k, v);
11
+ }
12
+ const res = await fetch(url, { headers: { Authorization: 'Bearer ' + apiKey } });
13
+ let body;
14
+ try { body = await res.json(); } catch { body = {}; }
15
+ if (!res.ok) {
16
+ const err = new Error(body.error || ('Request failed: HTTP ' + res.status));
17
+ err.status = res.status;
18
+ err.body = body;
19
+ throw err;
20
+ }
21
+ return body;
22
+ }
23
+
24
+ /** Latest published table (all plans, including free). */
25
+ export async function getLatestRates(options) {
26
+ return request('/latest', {}, options);
27
+ }
28
+
29
+ /** Latest rate for one pair, e.g. getRate('EUR', 'USD', { apiKey }). */
30
+ export async function getRate(source, target, options) {
31
+ return request('/latest', { source, target }, options);
32
+ }
33
+
34
+ /** Published table for a date (YYYY-MM-DD). Paid plans. Weekends/holidays return the most recent published date. */
35
+ export async function getRatesForDate(date, options) {
36
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(String(date))) throw new Error('date must be YYYY-MM-DD');
37
+ return request('/' + date, options && options.source ? { source: options.source, target: options.target } : {}, options);
38
+ }
39
+
40
+ /** Daily time series. Pass { symbol } or { source, target }, optional from/to (YYYY-MM-DD). Paid plans. */
41
+ export async function getHistory(query, options) {
42
+ const { symbol, source, target, from, to } = query || {};
43
+ return request('/history', { symbol, source, target, from, to }, options);
44
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "bnb-exchange-rate",
3
+ "version": "1.0.1",
4
+ "description": "Official Bulgarian National Bank (Bulgaria) daily exchange rates — ~29 currencies vs EUR, history since 2016. Zero-dependency Node.js/TypeScript client.",
5
+ "keywords": [
6
+ "bnb",
7
+ "bulgarian",
8
+ "national",
9
+ "bank",
10
+ "exchange-rate",
11
+ "exchange-rates",
12
+ "currency",
13
+ "forex",
14
+ "fx",
15
+ "eur",
16
+ "central-bank",
17
+ "official-rates",
18
+ "bulgaria",
19
+ "api",
20
+ "typescript"
21
+ ],
22
+ "homepage": "https://allratestoday.com/central-bank-rates-api/bnb/",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/AllRates-Today/bnb-exchange-rate.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/AllRates-Today/bnb-exchange-rate/issues"
29
+ },
30
+ "license": "MIT",
31
+ "author": "AllRatesToday <hello@allratestoday.com> (https://allratestoday.com)",
32
+ "type": "module",
33
+ "main": "./index.cjs",
34
+ "module": "./index.mjs",
35
+ "types": "./index.d.ts",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./index.d.ts",
39
+ "import": "./index.mjs",
40
+ "require": "./index.cjs"
41
+ }
42
+ },
43
+ "files": [
44
+ "index.mjs",
45
+ "index.cjs",
46
+ "index.d.ts",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "engines": {
51
+ "node": ">=18"
52
+ },
53
+ "sideEffects": false
54
+ }