@allratestoday/sdk 1.4.5 → 1.4.7
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/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +78 -58
- package/dist/index.mjs +78 -58
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -166,6 +166,15 @@ declare class AllRatesToday {
|
|
|
166
166
|
private resolveKey;
|
|
167
167
|
private request;
|
|
168
168
|
private formatDate;
|
|
169
|
+
/**
|
|
170
|
+
* The history endpoint serves fixed windows ending today (7d, 30d, 1y) and
|
|
171
|
+
* one target per call, so pick the smallest window that reaches `start`.
|
|
172
|
+
*/
|
|
173
|
+
private windowFor;
|
|
174
|
+
private requireSymbols;
|
|
175
|
+
private historyPoints;
|
|
176
|
+
/** Rate on `date`, or the closest earlier point (the 1y window is weekly). */
|
|
177
|
+
private rateOn;
|
|
169
178
|
/**
|
|
170
179
|
* Get the latest exchange rates.
|
|
171
180
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -166,6 +166,15 @@ declare class AllRatesToday {
|
|
|
166
166
|
private resolveKey;
|
|
167
167
|
private request;
|
|
168
168
|
private formatDate;
|
|
169
|
+
/**
|
|
170
|
+
* The history endpoint serves fixed windows ending today (7d, 30d, 1y) and
|
|
171
|
+
* one target per call, so pick the smallest window that reaches `start`.
|
|
172
|
+
*/
|
|
173
|
+
private windowFor;
|
|
174
|
+
private requireSymbols;
|
|
175
|
+
private historyPoints;
|
|
176
|
+
/** Rate on `date`, or the closest earlier point (the 1y window is weekly). */
|
|
177
|
+
private rateOn;
|
|
169
178
|
/**
|
|
170
179
|
* Get the latest exchange rates.
|
|
171
180
|
*
|
package/dist/index.js
CHANGED
|
@@ -92,6 +92,43 @@ var AllRatesToday = class {
|
|
|
92
92
|
}
|
|
93
93
|
return date;
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The history endpoint serves fixed windows ending today (7d, 30d, 1y) and
|
|
97
|
+
* one target per call, so pick the smallest window that reaches `start`.
|
|
98
|
+
*/
|
|
99
|
+
windowFor(start) {
|
|
100
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
101
|
+
const days = Math.round((Date.parse(`${today}T00:00:00Z`) - Date.parse(`${start}T00:00:00Z`)) / 864e5);
|
|
102
|
+
if (Number.isNaN(days)) throw new AllRatesTodayError(`Invalid date: ${start}. Use YYYY-MM-DD.`);
|
|
103
|
+
if (days < 0) throw new AllRatesTodayError(`Date ${start} is in the future.`);
|
|
104
|
+
if (days <= 6) return "7d";
|
|
105
|
+
if (days <= 29) return "30d";
|
|
106
|
+
if (days <= 364) return "1y";
|
|
107
|
+
throw new AllRatesTodayError(`Historical market rates cover the last 365 days; ${start} is older.`);
|
|
108
|
+
}
|
|
109
|
+
requireSymbols(symbols, method) {
|
|
110
|
+
if (!symbols?.length) {
|
|
111
|
+
throw new AllRatesTodayError(`${method}() needs symbols, e.g. { symbols: ['EUR'] }.`);
|
|
112
|
+
}
|
|
113
|
+
return symbols;
|
|
114
|
+
}
|
|
115
|
+
async historyPoints(source, target, period, key) {
|
|
116
|
+
const raw = await this.request(
|
|
117
|
+
"/api/historical-rates",
|
|
118
|
+
{ source, target, period },
|
|
119
|
+
key
|
|
120
|
+
);
|
|
121
|
+
return (raw.data ?? []).slice().sort((a, b) => a.timestamp - b.timestamp);
|
|
122
|
+
}
|
|
123
|
+
/** Rate on `date`, or the closest earlier point (the 1y window is weekly). */
|
|
124
|
+
async rateOn(source, target, date, key) {
|
|
125
|
+
let rate;
|
|
126
|
+
for (const p of await this.historyPoints(source, target, this.windowFor(date), key)) {
|
|
127
|
+
if (p.date.slice(0, 10) > date) break;
|
|
128
|
+
rate = p.rate;
|
|
129
|
+
}
|
|
130
|
+
return rate;
|
|
131
|
+
}
|
|
95
132
|
// -------------------------------------------------------------------------
|
|
96
133
|
// Public API
|
|
97
134
|
// -------------------------------------------------------------------------
|
|
@@ -144,29 +181,13 @@ var AllRatesToday = class {
|
|
|
144
181
|
async forDate(date, options = {}) {
|
|
145
182
|
const key = this.resolveKey(options.apiKey);
|
|
146
183
|
const dateStr = this.formatDate(date);
|
|
147
|
-
const
|
|
148
|
-
source: options.base || "USD",
|
|
149
|
-
from: dateStr,
|
|
150
|
-
to: dateStr
|
|
151
|
-
};
|
|
152
|
-
if (options.symbols?.length) {
|
|
153
|
-
params.target = options.symbols.join(",");
|
|
154
|
-
}
|
|
155
|
-
const raw = await this.request(
|
|
156
|
-
"/api/historical-rates",
|
|
157
|
-
params,
|
|
158
|
-
key
|
|
159
|
-
);
|
|
184
|
+
const source = options.base || "USD";
|
|
160
185
|
const rates = {};
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
186
|
+
for (const target of this.requireSymbols(options.symbols, "forDate")) {
|
|
187
|
+
const rate = await this.rateOn(source, target, dateStr, key);
|
|
188
|
+
if (rate !== void 0) rates[target] = rate;
|
|
165
189
|
}
|
|
166
|
-
|
|
167
|
-
rates[raw.target] = raw.current.rate;
|
|
168
|
-
}
|
|
169
|
-
return { base: params.source, date: dateStr, rates };
|
|
190
|
+
return { base: source, date: dateStr, rates };
|
|
170
191
|
}
|
|
171
192
|
/**
|
|
172
193
|
* Get exchange rate time series between two dates.
|
|
@@ -186,25 +207,14 @@ var AllRatesToday = class {
|
|
|
186
207
|
const start = this.formatDate(startDate);
|
|
187
208
|
const end = this.formatDate(endDate);
|
|
188
209
|
const source = options.base || "USD";
|
|
189
|
-
const
|
|
190
|
-
source,
|
|
191
|
-
from: start,
|
|
192
|
-
to: end
|
|
193
|
-
};
|
|
194
|
-
if (options.symbols?.length) {
|
|
195
|
-
params.target = options.symbols.join(",");
|
|
196
|
-
}
|
|
197
|
-
const raw = await this.request(
|
|
198
|
-
"/api/historical-rates",
|
|
199
|
-
params,
|
|
200
|
-
key
|
|
201
|
-
);
|
|
210
|
+
const period = this.windowFor(start);
|
|
202
211
|
const rates = {};
|
|
203
|
-
|
|
204
|
-
for (const point of
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
207
|
-
rates[
|
|
212
|
+
for (const target of this.requireSymbols(options.symbols, "timeSeries")) {
|
|
213
|
+
for (const point of await this.historyPoints(source, target, period, key)) {
|
|
214
|
+
const day = point.date.slice(0, 10);
|
|
215
|
+
if (day < start || day > end) continue;
|
|
216
|
+
if (!rates[day]) rates[day] = {};
|
|
217
|
+
rates[day][target] = point.rate;
|
|
208
218
|
}
|
|
209
219
|
}
|
|
210
220
|
return { base: source, startDate: start, endDate: end, rates };
|
|
@@ -223,7 +233,10 @@ var AllRatesToday = class {
|
|
|
223
233
|
*/
|
|
224
234
|
async symbols(options = {}) {
|
|
225
235
|
const key = this.resolveKey(options.apiKey);
|
|
226
|
-
|
|
236
|
+
const raw = await this.request("/api/v1/symbols", {}, key);
|
|
237
|
+
const symbols = {};
|
|
238
|
+
for (const c of raw.currencies ?? []) symbols[c.code] = c.name;
|
|
239
|
+
return { symbols };
|
|
227
240
|
}
|
|
228
241
|
/**
|
|
229
242
|
* Latest table of OFFICIAL rates published by a central bank or tax
|
|
@@ -290,7 +303,18 @@ var AllRatesToday = class {
|
|
|
290
303
|
const key = this.resolveKey(options.apiKey);
|
|
291
304
|
const params = { source: from, target: to };
|
|
292
305
|
if (amount !== void 0) params.amount = String(amount);
|
|
293
|
-
|
|
306
|
+
const raw = await this.request("/api/v1/rates", params, key);
|
|
307
|
+
if (Array.isArray(raw) || !("from" in raw)) {
|
|
308
|
+
const r = Array.isArray(raw) ? raw[0] : raw;
|
|
309
|
+
if (!r) throw new AllRatesTodayError(`No rate returned for ${from}/${to}`);
|
|
310
|
+
return {
|
|
311
|
+
from: { currency: r.source, amount: 1 },
|
|
312
|
+
to: { currency: r.target, amount: r.rate },
|
|
313
|
+
rate: r.rate,
|
|
314
|
+
source: "interbank"
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return raw;
|
|
294
318
|
}
|
|
295
319
|
/**
|
|
296
320
|
* Get authenticated exchange rates with metadata.
|
|
@@ -316,11 +340,15 @@ var AllRatesToday = class {
|
|
|
316
340
|
*/
|
|
317
341
|
async getHistoricalRates(source, target, period = "7d", options = {}) {
|
|
318
342
|
const key = this.resolveKey(options.apiKey);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
343
|
+
const points = await this.historyPoints(source, target, period, key);
|
|
344
|
+
const rates = points.map((p) => ({ rate: p.rate, time: p.date }));
|
|
345
|
+
return {
|
|
346
|
+
source,
|
|
347
|
+
target,
|
|
348
|
+
period,
|
|
349
|
+
current: rates[rates.length - 1] ?? { rate: 0, time: "" },
|
|
350
|
+
rates
|
|
351
|
+
};
|
|
324
352
|
}
|
|
325
353
|
/**
|
|
326
354
|
* Convert an amount between two currencies.
|
|
@@ -339,18 +367,10 @@ var AllRatesToday = class {
|
|
|
339
367
|
const key = this.resolveKey(options.apiKey);
|
|
340
368
|
if (options.date) {
|
|
341
369
|
const dateStr = this.formatDate(options.date);
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
to: dateStr
|
|
347
|
-
};
|
|
348
|
-
const raw = await this.request(
|
|
349
|
-
"/api/historical-rates",
|
|
350
|
-
params,
|
|
351
|
-
key
|
|
352
|
-
);
|
|
353
|
-
const rate = raw.current?.rate ?? raw.rates?.[0]?.rate ?? 0;
|
|
370
|
+
const rate = await this.rateOn(from, to, dateStr, key);
|
|
371
|
+
if (rate === void 0) {
|
|
372
|
+
throw new AllRatesTodayError(`No ${from}/${to} rate available on or before ${dateStr}`);
|
|
373
|
+
}
|
|
354
374
|
return { from, to, amount, result: Number((amount * rate).toFixed(6)), rate, date: dateStr };
|
|
355
375
|
}
|
|
356
376
|
const data = await this.request(
|
package/dist/index.mjs
CHANGED
|
@@ -66,6 +66,43 @@ var AllRatesToday = class {
|
|
|
66
66
|
}
|
|
67
67
|
return date;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The history endpoint serves fixed windows ending today (7d, 30d, 1y) and
|
|
71
|
+
* one target per call, so pick the smallest window that reaches `start`.
|
|
72
|
+
*/
|
|
73
|
+
windowFor(start) {
|
|
74
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
75
|
+
const days = Math.round((Date.parse(`${today}T00:00:00Z`) - Date.parse(`${start}T00:00:00Z`)) / 864e5);
|
|
76
|
+
if (Number.isNaN(days)) throw new AllRatesTodayError(`Invalid date: ${start}. Use YYYY-MM-DD.`);
|
|
77
|
+
if (days < 0) throw new AllRatesTodayError(`Date ${start} is in the future.`);
|
|
78
|
+
if (days <= 6) return "7d";
|
|
79
|
+
if (days <= 29) return "30d";
|
|
80
|
+
if (days <= 364) return "1y";
|
|
81
|
+
throw new AllRatesTodayError(`Historical market rates cover the last 365 days; ${start} is older.`);
|
|
82
|
+
}
|
|
83
|
+
requireSymbols(symbols, method) {
|
|
84
|
+
if (!symbols?.length) {
|
|
85
|
+
throw new AllRatesTodayError(`${method}() needs symbols, e.g. { symbols: ['EUR'] }.`);
|
|
86
|
+
}
|
|
87
|
+
return symbols;
|
|
88
|
+
}
|
|
89
|
+
async historyPoints(source, target, period, key) {
|
|
90
|
+
const raw = await this.request(
|
|
91
|
+
"/api/historical-rates",
|
|
92
|
+
{ source, target, period },
|
|
93
|
+
key
|
|
94
|
+
);
|
|
95
|
+
return (raw.data ?? []).slice().sort((a, b) => a.timestamp - b.timestamp);
|
|
96
|
+
}
|
|
97
|
+
/** Rate on `date`, or the closest earlier point (the 1y window is weekly). */
|
|
98
|
+
async rateOn(source, target, date, key) {
|
|
99
|
+
let rate;
|
|
100
|
+
for (const p of await this.historyPoints(source, target, this.windowFor(date), key)) {
|
|
101
|
+
if (p.date.slice(0, 10) > date) break;
|
|
102
|
+
rate = p.rate;
|
|
103
|
+
}
|
|
104
|
+
return rate;
|
|
105
|
+
}
|
|
69
106
|
// -------------------------------------------------------------------------
|
|
70
107
|
// Public API
|
|
71
108
|
// -------------------------------------------------------------------------
|
|
@@ -118,29 +155,13 @@ var AllRatesToday = class {
|
|
|
118
155
|
async forDate(date, options = {}) {
|
|
119
156
|
const key = this.resolveKey(options.apiKey);
|
|
120
157
|
const dateStr = this.formatDate(date);
|
|
121
|
-
const
|
|
122
|
-
source: options.base || "USD",
|
|
123
|
-
from: dateStr,
|
|
124
|
-
to: dateStr
|
|
125
|
-
};
|
|
126
|
-
if (options.symbols?.length) {
|
|
127
|
-
params.target = options.symbols.join(",");
|
|
128
|
-
}
|
|
129
|
-
const raw = await this.request(
|
|
130
|
-
"/api/historical-rates",
|
|
131
|
-
params,
|
|
132
|
-
key
|
|
133
|
-
);
|
|
158
|
+
const source = options.base || "USD";
|
|
134
159
|
const rates = {};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
160
|
+
for (const target of this.requireSymbols(options.symbols, "forDate")) {
|
|
161
|
+
const rate = await this.rateOn(source, target, dateStr, key);
|
|
162
|
+
if (rate !== void 0) rates[target] = rate;
|
|
139
163
|
}
|
|
140
|
-
|
|
141
|
-
rates[raw.target] = raw.current.rate;
|
|
142
|
-
}
|
|
143
|
-
return { base: params.source, date: dateStr, rates };
|
|
164
|
+
return { base: source, date: dateStr, rates };
|
|
144
165
|
}
|
|
145
166
|
/**
|
|
146
167
|
* Get exchange rate time series between two dates.
|
|
@@ -160,25 +181,14 @@ var AllRatesToday = class {
|
|
|
160
181
|
const start = this.formatDate(startDate);
|
|
161
182
|
const end = this.formatDate(endDate);
|
|
162
183
|
const source = options.base || "USD";
|
|
163
|
-
const
|
|
164
|
-
source,
|
|
165
|
-
from: start,
|
|
166
|
-
to: end
|
|
167
|
-
};
|
|
168
|
-
if (options.symbols?.length) {
|
|
169
|
-
params.target = options.symbols.join(",");
|
|
170
|
-
}
|
|
171
|
-
const raw = await this.request(
|
|
172
|
-
"/api/historical-rates",
|
|
173
|
-
params,
|
|
174
|
-
key
|
|
175
|
-
);
|
|
184
|
+
const period = this.windowFor(start);
|
|
176
185
|
const rates = {};
|
|
177
|
-
|
|
178
|
-
for (const point of
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
rates[
|
|
186
|
+
for (const target of this.requireSymbols(options.symbols, "timeSeries")) {
|
|
187
|
+
for (const point of await this.historyPoints(source, target, period, key)) {
|
|
188
|
+
const day = point.date.slice(0, 10);
|
|
189
|
+
if (day < start || day > end) continue;
|
|
190
|
+
if (!rates[day]) rates[day] = {};
|
|
191
|
+
rates[day][target] = point.rate;
|
|
182
192
|
}
|
|
183
193
|
}
|
|
184
194
|
return { base: source, startDate: start, endDate: end, rates };
|
|
@@ -197,7 +207,10 @@ var AllRatesToday = class {
|
|
|
197
207
|
*/
|
|
198
208
|
async symbols(options = {}) {
|
|
199
209
|
const key = this.resolveKey(options.apiKey);
|
|
200
|
-
|
|
210
|
+
const raw = await this.request("/api/v1/symbols", {}, key);
|
|
211
|
+
const symbols = {};
|
|
212
|
+
for (const c of raw.currencies ?? []) symbols[c.code] = c.name;
|
|
213
|
+
return { symbols };
|
|
201
214
|
}
|
|
202
215
|
/**
|
|
203
216
|
* Latest table of OFFICIAL rates published by a central bank or tax
|
|
@@ -264,7 +277,18 @@ var AllRatesToday = class {
|
|
|
264
277
|
const key = this.resolveKey(options.apiKey);
|
|
265
278
|
const params = { source: from, target: to };
|
|
266
279
|
if (amount !== void 0) params.amount = String(amount);
|
|
267
|
-
|
|
280
|
+
const raw = await this.request("/api/v1/rates", params, key);
|
|
281
|
+
if (Array.isArray(raw) || !("from" in raw)) {
|
|
282
|
+
const r = Array.isArray(raw) ? raw[0] : raw;
|
|
283
|
+
if (!r) throw new AllRatesTodayError(`No rate returned for ${from}/${to}`);
|
|
284
|
+
return {
|
|
285
|
+
from: { currency: r.source, amount: 1 },
|
|
286
|
+
to: { currency: r.target, amount: r.rate },
|
|
287
|
+
rate: r.rate,
|
|
288
|
+
source: "interbank"
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return raw;
|
|
268
292
|
}
|
|
269
293
|
/**
|
|
270
294
|
* Get authenticated exchange rates with metadata.
|
|
@@ -290,11 +314,15 @@ var AllRatesToday = class {
|
|
|
290
314
|
*/
|
|
291
315
|
async getHistoricalRates(source, target, period = "7d", options = {}) {
|
|
292
316
|
const key = this.resolveKey(options.apiKey);
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
317
|
+
const points = await this.historyPoints(source, target, period, key);
|
|
318
|
+
const rates = points.map((p) => ({ rate: p.rate, time: p.date }));
|
|
319
|
+
return {
|
|
320
|
+
source,
|
|
321
|
+
target,
|
|
322
|
+
period,
|
|
323
|
+
current: rates[rates.length - 1] ?? { rate: 0, time: "" },
|
|
324
|
+
rates
|
|
325
|
+
};
|
|
298
326
|
}
|
|
299
327
|
/**
|
|
300
328
|
* Convert an amount between two currencies.
|
|
@@ -313,18 +341,10 @@ var AllRatesToday = class {
|
|
|
313
341
|
const key = this.resolveKey(options.apiKey);
|
|
314
342
|
if (options.date) {
|
|
315
343
|
const dateStr = this.formatDate(options.date);
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
to: dateStr
|
|
321
|
-
};
|
|
322
|
-
const raw = await this.request(
|
|
323
|
-
"/api/historical-rates",
|
|
324
|
-
params,
|
|
325
|
-
key
|
|
326
|
-
);
|
|
327
|
-
const rate = raw.current?.rate ?? raw.rates?.[0]?.rate ?? 0;
|
|
344
|
+
const rate = await this.rateOn(from, to, dateStr, key);
|
|
345
|
+
if (rate === void 0) {
|
|
346
|
+
throw new AllRatesTodayError(`No ${from}/${to} rate available on or before ${dateStr}`);
|
|
347
|
+
}
|
|
328
348
|
return { from, to, amount, result: Number((amount * rate).toFixed(6)), rate, date: dateStr };
|
|
329
349
|
}
|
|
330
350
|
const data = await this.request(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allratestoday/sdk",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
4
4
|
"description": "Exchange Rate API — Real-time mid-market currency exchange rates for Node.js and browsers. 160+ currencies, zero dependencies, free tier.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|