easy-currencies 1.10.2 → 2.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.
@@ -1,6 +1,8 @@
1
+ import { RetryOptions } from "./parts/requester";
1
2
  import { Provider, ProviderReference } from "./parts/providers";
2
- import { Config, ProxyConfiguration } from "./parts/config";
3
+ import { Config } from "./parts/config";
3
4
  export { Chainer as Convert } from "./parts/chainer";
5
+ import { HttpClient } from "./parts/client";
4
6
  /**
5
7
  * A simple map object for rates
6
8
  *
@@ -18,6 +20,17 @@ export interface rateObject {
18
20
  * as before.
19
21
  */
20
22
  export declare const RATES_BASE: unique symbol;
23
+ /**
24
+ * The enumerable twin of `RATES_BASE`.
25
+ *
26
+ * A symbol is invisible to `JSON.stringify`, spread, `Object.assign` and
27
+ * `structuredClone`, so a table that has been through a cache loses the marker
28
+ * and a conversion against the wrong base is then accepted silently. That is
29
+ * the caching workflow this guard exists for, so the base also travels as an
30
+ * ordinary key. Underscores are not valid in a currency code, see
31
+ * `CURRENCY_CODE`, so this can never collide with a rate.
32
+ */
33
+ export declare const RATES_BASE_KEY = "__base";
21
34
  /**
22
35
  * Regular converter class definition.
23
36
  *
@@ -32,6 +45,30 @@ export declare class Converter {
32
45
  * @memberof Converter
33
46
  */
34
47
  config: Config;
48
+ /**
49
+ * Called with each handled provider error before the next provider is tried.
50
+ *
51
+ * A library does not own the consumer's stderr, so this is the single point
52
+ * where that reporting happens. It defaults to the previous behaviour;
53
+ * assign your own to route the errors elsewhere, or assign a no-op to
54
+ * silence them entirely.
55
+ *
56
+ * @example
57
+ * const converter = new Converter();
58
+ * converter.onError = () => {}; // silence
59
+ * converter.onError = (e) => logger.warn(e); // or route
60
+ *
61
+ * @memberof Converter
62
+ */
63
+ onError: (error: unknown) => void;
64
+ /**
65
+ * Reports a provider failure without letting the report become the failure.
66
+ *
67
+ * `onError` is consumer code, and the default is `console.error`, which
68
+ * throws on a closed stdout: a CLI piped into `head` would abort the whole
69
+ * chain on EPIPE and never reach the healthy provider behind it.
70
+ */
71
+ private report;
35
72
  /**
36
73
  * Creates an instance of Converter.
37
74
  * @param {(...ProviderReference[] | undefined[] | string[])} config
@@ -48,15 +85,43 @@ export declare class Converter {
48
85
  get providers(): Provider[];
49
86
  get active(): Provider[];
50
87
  add: Config["add"];
51
- addProvider: Config["add"];
52
88
  addMultiple: Config["addMultiple"];
53
- addMultipleProviders: Config["addMultiple"];
54
89
  remove: Config["remove"];
55
90
  /**
56
- * Method to set the proxy configuration.
57
- * @param proxyConfiguration The proxy configuration.
91
+ * Replaces the HTTP client.
92
+ *
93
+ * The default client uses the global fetch, which has no proxy option, so
94
+ * proxying (or a custom agent, or instrumentation) means supplying your own.
95
+ *
96
+ * @example
97
+ * import { ProxyAgent } from "undici";
98
+ * const dispatcher = new ProxyAgent("http://proxy:8080");
99
+ * converter.setClient({
100
+ * get: (url) =>
101
+ * fetch(url, { dispatcher } as any).then(async (r) => ({
102
+ * status: r.status,
103
+ * data: await r.json()
104
+ * }))
105
+ * });
106
+ *
107
+ * @param {HttpClient} client - the client to use
58
108
  */
59
- setProxyConfiguration: (proxyConfiguration: ProxyConfiguration) => void;
109
+ setClient: (client: HttpClient) => void;
110
+ /**
111
+ * Tunes retries and the time a conversion may take.
112
+ *
113
+ * `budgetMs` is wall clock for the whole call, spent across every provider
114
+ * rather than reset for each one, and it covers the requests themselves: a
115
+ * client that never settles cannot hold a conversion open past it. Fields
116
+ * merge, so one can be set without restating the rest.
117
+ *
118
+ * @example
119
+ * converter.setRetryOptions({ budgetMs: 5000 }); // an HTTP handler
120
+ * converter.setRetryOptions({ maxRetries: 0 }); // never retry a 429
121
+ *
122
+ * @param {RetryOptions} options - the tuning to apply
123
+ */
124
+ setRetryOptions: (options: RetryOptions) => void;
60
125
  /**
61
126
  * Conversion function (non chainable).
62
127
  *
@@ -69,23 +134,35 @@ export declare class Converter {
69
134
  * @param {string} from - base currency
70
135
  * @param {string} to - conversion currency
71
136
  * @param {any} rates - conversion rates, if they were pre-fetched
137
+ * @throws {Error} - if the amount is not finite, or a currency is missing
72
138
  * @returns {Promise<number>} - converted amount
73
139
  */
74
140
  convert: (amount: number, from: string, to: string, rates?: any) => Promise<number>;
75
141
  /**
76
142
  * Performs safe multiplication to get the result amount.
143
+ *
144
+ * A usable rate is finite and greater than zero; anything else multiplies
145
+ * into a plausible-looking wrong amount.
146
+ *
77
147
  * @param {number} amount - amount to be converted
78
148
  * @param {string} to - conversion currency
79
149
  * @param {any} rates - conversion rates, if they were pre-fetched
80
- * @returns
150
+ * @throws {Error} - if the amount, the currency, the rates or the rate is invalid
151
+ * @returns {number} - converted amount
81
152
  */
82
153
  convertRate: (amount: number, to: string, rates?: any) => number;
83
154
  /**
84
- * Rate fetch function
155
+ * Rate fetch function.
156
+ *
157
+ * Walks a snapshot of the chain, so concurrent calls do not shrink each
158
+ * other's list. A failure applies to the call, not the chain: no provider is
159
+ * removed, so one unknown currency cannot degrade a long-lived converter.
160
+ *
85
161
  * @param {string} from - base currency
86
162
  * @param {string} to - conversion currency
87
163
  * @param {boolean} multiple - determines conversion mode
88
- * @returns
164
+ * @throws {Error} - if a currency is missing, or every provider failed
165
+ * @returns {Promise<rateObject>} - the fetched rates
89
166
  */
90
167
  getRates: (from: string, to: string, multiple?: boolean) => Promise<rateObject>;
91
168
  }