UNPKG

@kabeep/forex

Version:

A JavaScript foreign exchange library via fawazahmed0's API

627 lines (621 loc) 16.8 kB
"use strict"; 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 });