bitpay-rates 3.0.0 → 3.1.0

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/README.md CHANGED
@@ -1,19 +1,18 @@
1
1
  # bitpay-rates
2
2
 
3
- ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/colkito/bitpay-rates/ci.yml?style=flat-square)
3
+ [![CI](https://img.shields.io/github/actions/workflow/status/colkito/bitpay-rates/ci.yml?style=flat-square&label=CI)](https://github.com/colkito/bitpay-rates/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/bitpay-rates.svg?style=flat-square)](https://www.npmjs.com/package/bitpay-rates)
5
- [![BundlePhobia](https://img.shields.io/bundlephobia/min/bitpay-rates.svg?style=flat-square)](https://bundlephobia.com/result?p=bitpay-rates)
6
- [![BundlePhobia](https://img.shields.io/bundlephobia/minzip/bitpay-rates.svg?style=flat-square)](https://bundlephobia.com/result?p=bitpay-rates)
7
5
 
8
6
  A lightweight Node.js wrapper for [BitPay exchange rates](https://www.bitpay.com/exchange-rates), written in TypeScript.
9
7
 
10
- Zero runtime dependencies, promise-based, dual ESM + CommonJS. Talks to the
11
- official public [Rates API](https://developer.bitpay.com/reference/rates)
8
+ Zero runtime dependencies, promise-based, ESM (and `require()` on Node 22.12+).
9
+ Talks to the official public
10
+ [Rates API](https://developer.bitpay.com/reference/rates)
12
11
  (`X-Accept-Version: 2.0.0`).
13
12
 
14
13
  ## Requirements
15
14
 
16
- - Node.js >= 22
15
+ - Node.js >= 22.12
17
16
 
18
17
  ```bash
19
18
  npm install bitpay-rates
@@ -28,12 +27,15 @@ npm install bitpay-rates
28
27
  `get({ base: 'ETH', quote: 'USD' })`.
29
28
  - `get({ base })` returns the **whole table** for that base, which v2 could not
30
29
  express. `get({ quote })` returns that one rate against BTC.
31
- - Dual ESM + CJS with an `exports` map (`import` and `require` both work).
32
- - Node.js >= 22.
30
+ - Dual ESM + CJS (the CJS file is gone in 3.1 see below).
31
+ - Node.js >= 22 (3.1 requires >= 22.12).
33
32
  - Requests time out after 10 seconds.
34
33
  - Currency codes are validated (`/^[A-Z0-9]{2,10}$/`); anything else rejects
35
34
  with a `TypeError` before a request is made.
36
35
 
36
+ v3.1 ships a **single ESM file**. `require('bitpay-rates')` still works on
37
+ Node 22.12+ (`require(esm)`). Node 22.0–22.11 need `import` or an upgrade.
38
+
37
39
  ## Usage
38
40
 
39
41
  ### ESM / TypeScript
package/dist/index.d.mts CHANGED
@@ -42,9 +42,8 @@ export declare function get(query: {
42
42
  quote: string;
43
43
  }): Promise<RateObj>;
44
44
  /**
45
- * Namespace object, so both import styles work in ESM and CommonJS:
46
- * `import { get }` / `const { get } = require(...)`, and
47
- * `import bitpayRates` / `const bitpayRates = require(...)` + `bitpayRates.get()`.
45
+ * Namespace object, so `import bitpayRates` / `require(...)` + `.get()` works
46
+ * the same as the named export.
48
47
  */
49
48
  declare const _default: {
50
49
  get: typeof get;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const e=`https://bitpay.com/rates`,t=1e4,n=/^[A-Z0-9]{2,10}$/,r={"X-Accept-Version":`2.0.0`,Accept:`application/json`,"User-Agent":`bitpay-rates`};async function i(n={}){let{quote:r}=n,i=a(n.base??`BTC`,`base`),s=r===void 0,c=s?`${e}/${i}`:`${e}/${i}/${a(r,`quote`)}`,l=new AbortController,u,d=new Promise((e,n)=>{u=setTimeout(()=>{let e=Error(`Request to ${c} timed out after ${t}ms`);l.abort(e),n(e)},t)});try{return await Promise.race([o(c,l.signal,s),d])}finally{u!==void 0&&clearTimeout(u)}}function a(e,t){let r=e.toUpperCase();if(!n.test(r))throw TypeError(`Invalid ${t} currency code: ${JSON.stringify(e)}`);return r}async function o(e,t,n){let i=await fetch(e,{headers:r,signal:t}),a=await i.text(),o;try{o=JSON.parse(a)}catch(t){throw i.ok?t:Error(`Request to ${e} failed with HTTP ${i.status}`)}if(s(o)&&o.error!=null)throw Error(String(o.error));if(!i.ok)throw Error(`Request to ${e} failed with HTTP ${i.status}`);let l=s(o)?o.data:void 0;if(n){if(!Array.isArray(l)||!l.every(c))throw Error(`Unexpected response from ${e}: expected a list of rates`)}else if(!c(l))throw Error(`Unexpected response from ${e}: expected a single rate`);return l}function s(e){return typeof e==`object`&&!!e}function c(e){return s(e)&&typeof e.code==`string`&&typeof e.name==`string`&&typeof e.rate==`number`}var l={get:i};export{l as default,i as get};
1
+ const e=`https://bitpay.com/rates`,t=1e4,n=/^[A-Z0-9]{2,10}$/,r={"X-Accept-Version":`2.0.0`,Accept:`application/json`,"User-Agent":`bitpay-rates`};async function i(n={}){let{quote:r}=n,i=a(n.base??`BTC`,`base`),c=r===void 0,l=c?`${e}/${i}`:`${e}/${i}/${a(r,`quote`)}`;try{return await o(l,AbortSignal.timeout(t),c)}catch(e){throw s(e)?Error(`Request to ${l} timed out after ${t}ms`):e}}function a(e,t){let r=e.toUpperCase();if(!n.test(r))throw TypeError(`Invalid ${t} currency code: ${JSON.stringify(e)}`);return r}async function o(e,t,n){let i=await fetch(e,{headers:r,signal:t}),a=await i.text(),o;try{o=JSON.parse(a)}catch(t){throw i.ok?t:Error(`Request to ${e} failed with HTTP ${i.status}`)}if(c(o)&&o.error!=null)throw Error(String(o.error));if(!i.ok)throw Error(`Request to ${e} failed with HTTP ${i.status}`);let s=c(o)?o.data:void 0;if(n){if(!Array.isArray(s)||!s.every(l))throw Error(`Unexpected response from ${e}: expected a list of rates`)}else if(!l(s))throw Error(`Unexpected response from ${e}: expected a single rate`);return s}function s(e){return e instanceof Error?e.name===`TimeoutError`||e.cause instanceof Error&&e.cause.name===`TimeoutError`:!1}function c(e){return typeof e==`object`&&!!e}function l(e){return c(e)&&typeof e.code==`string`&&typeof e.name==`string`&&typeof e.rate==`number`}var u={get:i};export{u as default,i as get};
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "bitpay-rates",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "A tiny Node.js wrapper for the BitPay Rates API",
5
5
  "engines": {
6
- "node": ">=22"
6
+ "node": ">=22.12"
7
7
  },
8
8
  "keywords": [
9
9
  "bitcoin",
@@ -14,24 +14,18 @@
14
14
  ],
15
15
  "author": "colkito <dev@colkito.com>",
16
16
  "license": "MIT",
17
- "type": "commonjs",
18
- "main": "./dist/index.cjs",
19
- "types": "./dist/index.d.cts",
17
+ "type": "module",
18
+ "main": "./dist/index.mjs",
19
+ "types": "./dist/index.d.mts",
20
20
  "exports": {
21
21
  ".": {
22
- "import": {
23
- "types": "./dist/index.d.mts",
24
- "default": "./dist/index.mjs"
25
- },
26
- "require": {
27
- "types": "./dist/index.d.cts",
28
- "default": "./dist/index.cjs"
29
- }
22
+ "types": "./dist/index.d.mts",
23
+ "default": "./dist/index.mjs"
30
24
  }
31
25
  },
32
26
  "repository": {
33
27
  "type": "git",
34
- "url": "https://github.com/colkito/bitpay-rates.git"
28
+ "url": "git+https://github.com/colkito/bitpay-rates.git"
35
29
  },
36
30
  "bugs": {
37
31
  "url": "https://github.com/colkito/bitpay-rates/issues"
@@ -58,7 +52,7 @@
58
52
  },
59
53
  "devDependencies": {
60
54
  "@biomejs/biome": "2.5.13",
61
- "@types/node": "26.4.1",
55
+ "@types/node": "22.20.2",
62
56
  "knip": "6.35.1",
63
57
  "tsdown": "0.23.0",
64
58
  "typescript": "7.0.2"
package/dist/index.cjs DELETED
@@ -1 +0,0 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=`https://bitpay.com/rates`,t=1e4,n=/^[A-Z0-9]{2,10}$/,r={"X-Accept-Version":`2.0.0`,Accept:`application/json`,"User-Agent":`bitpay-rates`};async function i(n={}){let{quote:r}=n,i=a(n.base??`BTC`,`base`),s=r===void 0,c=s?`${e}/${i}`:`${e}/${i}/${a(r,`quote`)}`,l=new AbortController,u,d=new Promise((e,n)=>{u=setTimeout(()=>{let e=Error(`Request to ${c} timed out after ${t}ms`);l.abort(e),n(e)},t)});try{return await Promise.race([o(c,l.signal,s),d])}finally{u!==void 0&&clearTimeout(u)}}function a(e,t){let r=e.toUpperCase();if(!n.test(r))throw TypeError(`Invalid ${t} currency code: ${JSON.stringify(e)}`);return r}async function o(e,t,n){let i=await fetch(e,{headers:r,signal:t}),a=await i.text(),o;try{o=JSON.parse(a)}catch(t){throw i.ok?t:Error(`Request to ${e} failed with HTTP ${i.status}`)}if(s(o)&&o.error!=null)throw Error(String(o.error));if(!i.ok)throw Error(`Request to ${e} failed with HTTP ${i.status}`);let l=s(o)?o.data:void 0;if(n){if(!Array.isArray(l)||!l.every(c))throw Error(`Unexpected response from ${e}: expected a list of rates`)}else if(!c(l))throw Error(`Unexpected response from ${e}: expected a single rate`);return l}function s(e){return typeof e==`object`&&!!e}function c(e){return s(e)&&typeof e.code==`string`&&typeof e.name==`string`&&typeof e.rate==`number`}var l={get:i};exports.default=l,exports.get=i;
package/dist/index.d.cts DELETED
@@ -1,53 +0,0 @@
1
- //#region src/index.d.mts
2
- export type RateObj = {
3
- code: string;
4
- name: string;
5
- rate: number;
6
- };
7
- export type RateResponse = RateObj | RateObj[];
8
- /** Arguments for {@link get}. Named so neither code can be passed in the wrong position. */
9
- export type RateQuery = {
10
- /**
11
- * Base cryptocurrency: the asset being priced.
12
- *
13
- * @defaultValue `'BTC'`
14
- */
15
- base?: string;
16
- /**
17
- * Quote currency: what to price `base` in. Omit for every rate against
18
- * `base`.
19
- */
20
- quote?: string;
21
- };
22
- /**
23
- * Fetch BitPay exchange rates.
24
- *
25
- * @param query - `{ base, quote }`. Omit `quote` for the full table, omit both for BTC.
26
- * @returns Every rate for `base` when `quote` is omitted, otherwise that single {@link RateObj}.
27
- * @throws `TypeError` if a code is not 2-10 alphanumeric characters, before any request is made.
28
- *
29
- * @example
30
- * await get(); // every rate against BTC
31
- * await get({ base: 'ETH' }); // every rate against ETH
32
- * await get({ quote: 'USD' }); // BTC/USD
33
- * await get({ base: 'ETH', quote: 'USD' }); // ETH/USD
34
- */
35
- export declare function get(): Promise<RateObj[]>;
36
- export declare function get(query: {
37
- base?: string;
38
- quote?: undefined;
39
- }): Promise<RateObj[]>;
40
- export declare function get(query: {
41
- base?: string;
42
- quote: string;
43
- }): Promise<RateObj>;
44
- /**
45
- * Namespace object, so both import styles work in ESM and CommonJS:
46
- * `import { get }` / `const { get } = require(...)`, and
47
- * `import bitpayRates` / `const bitpayRates = require(...)` + `bitpayRates.get()`.
48
- */
49
- declare const _default: {
50
- get: typeof get;
51
- };
52
- //#endregion
53
- export { _default as default };