@kabeep/forex
Version:
A JavaScript foreign exchange library via fawazahmed0's API
627 lines (621 loc) • 16.8 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
BASE_URL: () => BASE_URL,
BASE_URL_VERSION: () => BASE_URL_VERSION,
ForexClient: () => forex_client_default,
LOCALE_CURRENCY: () => LOCALE_CURRENCY,
NON_STANDARD_CODES: () => NON_STANDARD_CODES
});
module.exports = __toCommonJS(src_exports);
// src/constants/index.ts
var BASE_URL = "https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api";
var BASE_URL_VERSION = "v1";
var LOCALE_CURRENCY = {
AD: "EUR",
AE: "AED",
AF: "AFN",
AG: "XCD",
AI: "XCD",
AL: "ALL",
AM: "AMD",
AO: "AOA",
AR: "ARS",
AS: "USD",
AT: "EUR",
AU: "AUD",
AW: "AWG",
AX: "EUR",
AZ: "AZN",
BA: "BAM",
BB: "BBD",
BD: "BDT",
BE: "EUR",
BF: "XOF",
BG: "BGN",
BH: "BHD",
BI: "BIF",
BJ: "XOF",
BL: "EUR",
BM: "BMD",
BN: "BND",
BO: "BOB",
BQ: "USD",
BR: "BRL",
BS: "BSD",
BT: "BTN",
BV: "NOK",
BW: "BWP",
BY: "BYN",
BZ: "BZD",
CA: "CAD",
CC: "AUD",
CD: "CDF",
CF: "XAF",
CG: "XAF",
CH: "CHF",
CI: "XOF",
CK: "NZD",
CL: "CLP",
CM: "XAF",
CN: "CNY",
CO: "COP",
CR: "CRC",
CU: "CUP",
CV: "CVE",
CW: "ANG",
CX: "AUD",
CY: "EUR",
CZ: "CZK",
DE: "EUR",
DJ: "DJF",
DK: "DKK",
DM: "XCD",
DO: "DOP",
DZ: "DZD",
EC: "USD",
EE: "EUR",
EG: "EGP",
EH: "MAD",
ER: "ERN",
ES: "EUR",
ET: "ETB",
FI: "EUR",
FJ: "FJD",
FK: "FKP",
FM: "USD",
FO: "DKK",
FR: "EUR",
GA: "XAF",
GB: "GBP",
GD: "XCD",
GE: "GEL",
GF: "EUR",
GG: "GBP",
GH: "GHS",
GI: "GIP",
GL: "DKK",
GM: "GMD",
GN: "GNF",
GP: "EUR",
GQ: "XAF",
GR: "EUR",
GS: "GBP",
GT: "GTQ",
GU: "USD",
GW: "XOF",
GY: "GYD",
HK: "HKD",
HM: "AUD",
HN: "HNL",
HR: "EUR",
HT: "HTG",
HU: "HUF",
ID: "IDR",
IE: "EUR",
IL: "ILS",
IM: "GBP",
IN: "INR",
IO: "USD",
IQ: "IQD",
IR: "IRR",
IS: "ISK",
IT: "EUR",
JE: "GBP",
JM: "JMD",
JO: "JOD",
JP: "JPY",
KE: "KES",
KG: "KGS",
KH: "KHR",
KI: "AUD",
KM: "KMF",
KN: "XCD",
KP: "KPW",
KR: "KRW",
KW: "KWD",
KY: "KYD",
KZ: "KZT",
LA: "LAK",
LB: "LBP",
LC: "XCD",
LI: "CHF",
LK: "LKR",
LR: "LRD",
LS: "LSL",
LT: "EUR",
LU: "EUR",
LV: "EUR",
LY: "LYD",
MA: "MAD",
MC: "EUR",
MD: "MDL",
ME: "EUR",
MF: "EUR",
MG: "MGA",
MH: "USD",
MK: "MKD",
ML: "XOF",
MM: "MMK",
MN: "MNT",
MO: "MOP",
MP: "USD",
MQ: "EUR",
MR: "MRO",
MS: "XCD",
MT: "EUR",
MU: "MUR",
MV: "MVR",
MW: "MWK",
MX: "MXN",
MY: "MYR",
MZ: "MZN",
NA: "NAD",
NC: "XPF",
NE: "XOF",
NF: "AUD",
NG: "NGN",
NI: "NIO",
NL: "EUR",
NO: "NOK",
NP: "NPR",
NR: "AUD",
NU: "NZD",
NZ: "NZD",
OM: "OMR",
PA: "PAB",
PE: "PEN",
PF: "XPF",
PG: "PGK",
PH: "PHP",
PK: "PKR",
PL: "PLN",
PM: "EUR",
PN: "NZD",
PR: "USD",
PS: "ILS",
PT: "EUR",
PW: "USD",
PY: "PYG",
QA: "QAR",
RE: "EUR",
RO: "RON",
RS: "RSD",
RU: "RUB",
RW: "RWF",
SA: "SAR",
SB: "SBD",
SC: "SCR",
SD: "SDG",
SE: "SEK",
SG: "SGD",
SH: "SHP",
SI: "EUR",
SJ: "NOK",
SK: "EUR",
SL: "SLL",
SM: "EUR",
SN: "XOF",
SO: "SOS",
SR: "SRD",
ST: "STD",
SV: "SVC",
SX: "ANG",
SY: "SYP",
SZ: "SZL",
TC: "USD",
TD: "XAF",
TF: "EUR",
TG: "XOF",
TH: "THB",
TJ: "TJS",
TK: "NZD",
TL: "USD",
TM: "TMT",
TN: "TND",
TO: "TOP",
TR: "TRY",
TT: "TTD",
TV: "AUD",
TW: "TWD",
TZ: "TZS",
UA: "UAH",
UG: "UGX",
UM: "USD",
US: "USD",
UY: "UYU",
UZ: "UZS",
VA: "EUR",
VC: "XCD",
VE: "VEF",
VG: "USD",
VI: "USD",
VN: "VND",
VU: "VUV",
WF: "XPF",
WS: "WST",
YE: "YER",
YT: "EUR",
ZA: "ZAR",
ZM: "ZMW",
ZW: "ZWL"
};
var NON_STANDARD_CODES = {
BDS: "BBD",
CNT: "TWD",
NIS: "ILS",
NTD: "TWD",
STG: "GBP",
RMB: "CNY"
};
// src/utils/http-request.ts
var _HttpRequest = class _HttpRequest {
constructor(options = {}) {
__publicField(this, "timeout");
__publicField(this, "headers");
this.timeout = options.timeout || _HttpRequest.TIMEOUT;
this.headers = options.headers || _HttpRequest.REQUEST_HEADER;
}
_fetch(options) {
return __async(this, null, function* () {
var _a, _b, _c, _d;
let timeoutId;
const requestHeader = __spreadValues({}, options);
if (!requestHeader.signal) {
const controller = new AbortController();
requestHeader.signal = controller.signal;
timeoutId = setTimeout(() => controller.abort(), this.timeout);
}
try {
const response = yield fetch(options.url, requestHeader);
timeoutId && clearTimeout(timeoutId);
if (!response.ok) {
return this.createResponse(
(_a = response.status) != null ? _a : 500,
(_b = response.statusText) != null ? _b : "Internal Server Error"
);
}
const contentType = response.headers.get("Content-Type");
const data = (contentType == null ? void 0 : contentType.includes("application/json")) ? yield response.json() : yield response.text();
return this.createResponse(
(_c = response.status) != null ? _c : 200,
(_d = response.statusText) != null ? _d : "OK",
data
);
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") {
throw new Error("Request timeout or aborted");
}
throw error;
}
});
}
createResponse(code, message, data) {
return { code, message, data };
}
};
__publicField(_HttpRequest, "TIMEOUT", 5e3);
__publicField(_HttpRequest, "REQUEST_HEADER");
var HttpRequest = _HttpRequest;
var http_request_default = HttpRequest;
// src/utils/http-client.ts
var HttpClient = class extends http_request_default {
constructor(options = {}) {
super(options);
}
get(_0) {
return __async(this, arguments, function* (url, options = {}) {
const requestOptions = new Request(url, __spreadProps(__spreadValues({}, options), {
method: "GET",
headers: __spreadValues(__spreadValues({}, this.headers), options.headers)
}));
return this._fetch(requestOptions);
});
}
};
var http_client_default = HttpClient;
// src/services/forex-client.ts
var _ForexClient = class _ForexClient extends http_client_default {
/**
* Creates a new instance of ForexClient
* @param {ForexClientOptions} [options={}] - The options for configuring the client
* @param {string} options.baseCurrency - The base currency code
* @param {boolean} options.minified - Minified JSON format
* @param {number} options.timeout - Request timeout (milliseconds)
* @param {HeadersInit} options.headers - Request header
*/
constructor(options = {}) {
const _a = options, {
baseCurrency,
minified = _ForexClient.MINIFIED
} = _a, restOptions = __objRest(_a, [
"baseCurrency",
"minified"
]);
super(restOptions);
__publicField(this, "options");
this.options = { baseCurrency, minified };
}
/**
* Fetches the list of available currencies
* @param {Date | "latest"} [date="latest"] - The date for fetching currencies, or `"latest"` for the most recent
* @param {RequestInit} [options={}] - Additional request options
* @returns {Promise<HttpResponse<AvailableCurrency[]>>} A list of available currencies
*
* @example
* // => {
* // code: 200,
* // message: 'OK',
* // data: [
* // { code: 'eur', name: 'Euro' },
* // { code: 'usd', name: 'US Dollar' },
* // { code: 'cny', name: 'Chinese Yuan Renminbi' },
* // ... More items
* // ]
* // }
* new ForexClient().getCurrencies('latest');
*/
getCurrencies() {
return __async(this, arguments, function* (date = "latest", options = {}) {
const url = this.getApiUrl(date, "currencies");
const response = yield this.get(url, options);
return __spreadProps(__spreadValues({}, response), {
data: this.composeDataList(
response.data,
"name"
)
});
});
}
/**
* Fetches the exchange rates for a specific currency
* @param {string | undefined} [code=this.options.baseCurrency] - The currency code or locale code to get rates for
* @param {Date | "latest"} [date="latest"] - The date for the rates, or `'latest'` for the most recent
* @param {RequestInit} [options={}] - Additional request options
* @returns {Promise<HttpResponse<ExchangeRate[]>>} A list of exchange rates
*
* @example
* // => {
* // code: 200,
* // message: 'OK',
* // data: [
* // { code: 'eur', rate: 100_000 },
* // { code: 'usd', rate: 100_000 },
* // { code: 'cny', rate: 100_000 },
* // ... More items
* // ]
* // }
* new ForexClient().getRates('BTC');
*/
getRates() {
return __async(this, arguments, function* (code = this.options.baseCurrency, date = "latest", options = {}) {
var _a;
const lowercaseCode = this.validCurrencyCode(code).toLowerCase();
const url = this.getApiUrl(date, `currencies/${lowercaseCode}`);
const response = yield this.get(url, options);
return __spreadProps(__spreadValues({}, response), {
data: this.composeDataList(
(_a = response.data) == null ? void 0 : _a[lowercaseCode],
"rate"
)
});
});
}
/**
* Fetches the exchange rate between two currencies
* @param {string | undefined} [baseCode=this.options.baseCurrency] - The base currency code or locale code
* @param {string} destCode - The destination currency code or locale code
* @param {Date | "latest"} [date="latest"] - The date for the rate, or `'latest'` for the most recent
* @param {RequestInit} [options={}] - Additional request options
* @returns {Promise<HttpResponse<number>>} The exchange rate
*
* @example
* // => {
* // code: 200,
* // message: 'OK',
* // data: 100_000
* // }
* new ForexClient().getRate('BTC', 'USD');
*/
getRate() {
return __async(this, arguments, function* (baseCode = this.options.baseCurrency, destCode, date = "latest", options = {}) {
var _a;
const lowercaseCode = this.validCurrencyCode(baseCode).toLowerCase();
const url = this.getApiUrl(date, `currencies/${lowercaseCode}`);
const response = yield this.get(url, options);
const rates = (_a = response.data) == null ? void 0 : _a[lowercaseCode];
const lowercaseDestCode = this.validCurrencyCode(
destCode,
"destination"
).toLowerCase();
return __spreadProps(__spreadValues({}, response), { data: rates == null ? void 0 : rates[lowercaseDestCode] });
});
}
/**
* Get a valid currency code based on locale
* @param {string} localeCode - The locale code to get currency code for
* @returns {string} The corresponding currency code
*
* @example
* // => 'USD'
* new ForexClient().getCode('US');
*
* @example
* // => 'CNH'
* new ForexClient().getCode('HK');
*
* @example
* // => 'CNY'
* new ForexClient().getCode('RMB');
*/
getCode(localeCode) {
return this.validCurrencyCode(localeCode, "locale");
}
/**
* Converts an amount from one currency to another
* @param {string | undefined} [baseCode=this.options.baseCurrency] - The base currency code or locale code
* @param {string} destCode - The destination currency code or locale code
* @param {number} [amount=0] - The amount to convert
* @param {Date | "latest"} [date="latest"] - The date for the conversion rate, or `'latest'` for the most recent
* @param {RequestInit} [options={}] - Additional request options
* @returns {Promise<HttpResponse<number>>} The converted amount
*
* @example
* // => {
* // code: 200,
* // message: 'OK',
* // data: 100_000
* // }
* new ForexClient().convert('BTC', 'USD', 1);
*
* @example
* // => {
* // code: 200,
* // message: 'OK',
* // data: 7.27
* // }
* new ForexClient().convert('US', 'HK', 1);
*/
convert() {
return __async(this, arguments, function* (baseCode = this.options.baseCurrency, destCode, amount = 0, date = "latest", options = {}) {
const response = yield this.getRate(baseCode, destCode, date, options);
const _a = response, { data } = _a, restOptions = __objRest(_a, ["data"]);
return __spreadValues({
data: data ? Number(amount) * data : void 0
}, restOptions);
});
}
composeDataList(record, key) {
if (!record) return [];
return Object.entries(record).map(([code, value]) => ({
code,
[key]: value
}));
}
validCurrencyCode(code, type = "base") {
var _a;
if (!code) throw new Error(`Please specify the ${type} currency code.`);
const additionalCodes = __spreadValues(__spreadValues({}, LOCALE_CURRENCY), NON_STANDARD_CODES);
return (_a = additionalCodes[code.toUpperCase()]) != null ? _a : code;
}
getApiUrl(date, source) {
const dateString = this.formatDate(date);
const prefix = `${BASE_URL}@${dateString}/${BASE_URL_VERSION}`;
const sourceExtension = this.options.minified ? "min.json" : "json";
return `${prefix}/${source}.${sourceExtension}`;
}
formatDate(date) {
if (date === "latest" || !this.isValidDate(date)) {
return "latest";
}
return `${date.getFullYear()}-${this.paddedDate(date.getMonth() + 1)}-${this.paddedDate(date.getDate())}`;
}
isValidDate(value) {
return this.isDate(value) && !Number.isNaN(value.getTime());
}
isDate(value) {
return value instanceof Date || typeof value === "object" && Object.prototype.toString.call(value) === "[object Date]";
}
paddedDate(value, length = 2, padding = "0") {
return `${value}`.padStart(length, padding);
}
};
__publicField(_ForexClient, "MINIFIED", true);
var ForexClient = _ForexClient;
var forex_client_default = ForexClient;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BASE_URL,
BASE_URL_VERSION,
ForexClient,
LOCALE_CURRENCY,
NON_STANDARD_CODES
});