-
Notifications
You must be signed in to change notification settings - Fork 30
/
index.js
366 lines (330 loc) · 12.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
const cheerio = require("cheerio")
const request = require("request")
class CurrencyConverter {
currencies = {
"AFN": "Afghan Afghani",
"ALL": "Albanian Lek",
"DZD": "Algerian Dinar",
"AOA": "Angolan Kwanza",
"ARS": "Argentine Peso",
"AMD": "Armenian Dram",
"AWG": "Aruban Florin",
"AUD": "Australian Dollar",
"AZN": "Azerbaijani M anat",
"BSD": "Bahamian Dollar",
"BHD": "Bahraini Dinar",
"BBD": "Bajan Dollar",
"BDT": "Bangladeshi Taka",
"BYN": "Belarusian Ruble",
"BZD": "Belize Dollar",
"BMD": "Bermudan Dollar",
"BTN": "Bhutan currency",
"BOB": "Bolivian Boliviano",
"BAM": "Bosnia-Herzegovina Convertible Mark",
"BWP": "Botswanan Pula",
"BRL": "Brazilian Real",
"BND": "Brunei Dollar",
"BGN": "Bulgarian Lev",
"BIF": "Burundian Fra nc",
"XPF": "CFP Franc",
"KHR": "Cambodian riel",
"CAD": "Canadian Dollar",
"CVE": "Cape Verdean Escudo",
"KYD": "Cayman Islands Dollar",
"FCFA": "Central African CFA Franc",
"CLP": "Chilean Peso",
"CLF": "Chilean Unit of Account (UF)",
"CNY": "Chinese Yuan",
"CNY": "Chinese Yuan (offshore)",
"COP": "Colombian Peso",
"KMF": "Comorian Franc",
"CDF": "Congolese Franc",
"CRC": "Costa Rican Colón",
"HRK": "Croatian Kuna",
"CUC": "Cuban Peso",
"CZK": "Czech Koruna",
"DKK": "Danish Krone",
"DJF": "Djiboutian Franc",
"DOP": "Dominican Pe so",
"XCD": "East Caribbean Dollar",
"EGP": "Egyptian Pound",
"ETB": "Ethiopian Birr",
"FJD": "Fijian Dollar",
"GMD": "Gambian dalasi",
"GEL": "Georgian Lari",
"GHS": "Ghanaian Cedi",
"GTQ": "Guatemalan Quetzal",
"GNF": "Guinean Franc",
"GYD": "Guyanaese Dollar",
"HTG": "Haitian Gourde",
"HNL": "Honduran Lempira",
"HKD": "Hong Kong Dollar",
"HUF": "Hungarian Forint",
"ISK": "Icelandic Króna",
"INR": "Indian Rupee",
"IDR": "Indonesian Rupiah",
"IRR": "Iranian Rial",
"IQD": "Iraqi Dinar",
"ILS": "Israeli New Shekel",
"JMD": "Jamaican Dollar",
"JPY": "Japanese Yen",
"JOD": "Jordanian Dinar",
"KZT": "Kazakhstani Tenge",
"KES": "Kenyan Shilling",
"KWD": "Kuwaiti Dinar",
"KGS": "Kyrgystani Som",
"LAK": "Laotian Kip",
"LBP": "Lebanese pound",
"LSL": "Lesotho Loti",
"LRD": "Liberian Dollar",
"LYD": "Libyan Dinar",
"MOP": "Macanese Pataca",
"MKD": "Macedonian Denar",
"MGA": "Malagasy Ariary",
"MWK": "Malawian Kwacha",
"MYR": "Malaysian Ringgit",
"MVR": "Maldivian Rufiyaa",
"MRO": "Mauritanian Ouguiya",
"MUR": "Mauritian Rupee",
"MXN": "Mexican Peso",
"MDL": "Moldovan Leu",
"MAD": "Moroccan Dirham",
"MZN": "Mozambican metical",
"MMK": "Myanmar Kyat",
"NAD": "Namibian dol lar",
"NPR": "Nepalese Rupee",
"ANG": "Netherlands Antillean Guilder",
"NZD": "New Zealand Dollar",
"NIO": "Nicaraguan Córdoba",
"NGN": "Nigerian Naira",
"NOK": "Norwegian Krone",
"OMR": "Omani Rial",
"PKR": "Pakistani Rupee",
"PAB": "Panamanian Balboa",
"PGK": "Papua New Guinean Kina",
"PYG": "Paraguayan Guarani",
"PHP": "Philippine peso",
"PLN": "Poland Złoty",
"GBP": "Pound sterling",
"QAR": "Qatari Rial",
"RON": "Romania n Leu",
"RUB": "Russian Ruble",
"RWF": "Rwandan franc",
"SVC": "Salvadoran Colón",
"SAR": "Saudi Riyal",
"RSD": "Serbian Dinar",
"SCR": "Seychellois Rupee",
"SLL": "Sierra Leonean Leone",
"SGD": "Singapore Dollar",
"SBD": "Solomon Islands Dollar",
"SOS": "Somali Shilling",
"ZAR": "South African Rand",
"KRW": "South Korean won",
"VES": "Sovereign Bolivar",
"LKR": "Sri Lankan Rupee",
"SDG": "Sudanese pound",
"SRD": "Surinamese Dollar",
"SZL": "Swazi Lilangeni",
"SEK": "Swedish Krona",
"CF": "Swiss Franc",
"CHF": "Swiss Franc",
"TJS": "Tajikistani Somoni",
"TZS": "Tanzanian Shilling",
"THB": "Thai Baht",
"TOP": "Tongan Pa\"anga",
"TTD": "Trinidad and Tobago Dollar",
"TND": "Tunisian Dinar",
"TRY": "Turkish lira",
"TMT": "Turkmenistan manat",
"UGX": "Ugandan Shilling",
"UAH": "Ukrainian hryvnia",
"AED": "United Arab Emirates Dirham",
"USD": "United States Dollar",
"UYU": "Uruguayan Peso",
"UZS": "Uzbekistani Som",
"VND": "Vietnamese dong",
"XAF": "Central African CFA franc",
"XOF": "West African CFA franc",
"YER": "Yemeni Rial",
"ZMW": "Zambian Kwacha",
"XBT": "Bitcoin",
"ETH": "Ether",
"EUR": "Euro",
"LTC": "Litecoin",
"TWD": "NT$",
"PEN": "Peruvian Sol"
}
currencyCode = ["AFN", "ALL", "DZD", "AOA", "ARS", "AMD", "AWG", "AUD", "AZN", "BSD", "BHD", "BBD", "BDT", "BYN", "BZD", "BMD", "BTN", "XBT", "BOB", "BAM", "BWP", "BRL", "BND", "BGN", "BIF", "XPF", "KHR", "CAD", "CVE", "KYD", "FCFA", "CLP", "CLF", "CNY", "CNY", "COP", "CF", "CHF", "CDF", "CRC", "HRK", "CUC", "CZK", "DKK", "DJF", "DOP", "XCD", "EGP", "ETB", "FJD", "GMD", "GBP", "GEL", "GHS", "GTQ", "GNF", "GYD", "HTG", "HNL", "HKD", "HUF", "ISK", "INR", "IDR", "IRR", "IQD", "ILS", "JMD", "JPY", "JOD", "KMF", "KZT", "KES", "KWD", "KGS", "LAK", "LBP", "LSL", "LRD", "LYD", "MOP", "MKD", "MGA" , "MWK", "MYR", "MVR", "MRO", "MUR", "MXN", "MDL", "MAD", "MZN", "MMK", "NAD", "NPR", "ANG", "NZD", "NIO", "NGN", "NOK", "OMR", "PKR", "PAB", "PGK", "PYG", "PHP", "PLN", "QAR", "RON", "RUB", "RWF", "SVC", "SAR", "RSD", "SCR", "SLL", "SGD", "SBD", "SOS", "ZAR", "KRW", "VES", "LKR", "SDG", "SRD", "SZL", "SEK", "CHF", "TJS", "TZS", "THB", "TOP", "TTD", "TND", "TRY" , "TMT", "UGX", "UAH", "AED", "USD", "UYU", "UZS", "VND", "XAF", "XOF", "YER", "ZMW", "ETH", "EUR", "LTC", "TWD", "PEN"]
constructor(params) {
this.currencyFrom = ""
this.currencyTo = ""
this.currencyAmount = 1
this.convertedValue = 0
this.isDecimalComma = false;
this.isRatesCaching = false;
this.ratesCacheDuration = 0;
this.ratesCache = {};
if (params != undefined) {
if (params["from"] !== undefined)
this.from(params["from"])
if (params["to"] !== undefined)
this.to(params["to"])
if (params["amount"] !== undefined)
this.amount(params["amount"])
if (params["isDecimalComma"] !== undefined)
this.setDecimalComma(params["isDecimalComma"])
}
}
from(currencyFrom) {
if (typeof currencyFrom !== "string")
throw new TypeError("currency code should be a string")
if (!this.currencyCode.includes(currencyFrom.toUpperCase()))
throw new Error(`${currencyFrom} is not a valid currency code`)
this.currencyFrom = currencyFrom.toUpperCase()
return this
}
to(currencyTo) {
if (typeof currencyTo !== "string")
throw new TypeError("currency code should be a string")
if (!this.currencyCode.includes(currencyTo.toUpperCase()))
throw new Error(`${currencyTo} is not a valid currency code`)
this.currencyTo = currencyTo
return this
}
amount(currencyAmount) {
if (typeof currencyAmount !== "number")
throw new TypeError("amount should be a number")
if (currencyAmount <= 0)
throw new Error("amount should be a positive number")
this.currencyAmount = currencyAmount
return this
}
setDecimalComma(isDecimalComma) {
if (typeof isDecimalComma !== "boolean")
throw new TypeError("isDecimalComma should be a boolean")
this.isDecimalComma = isDecimalComma
return this
}
replaceAll(text, queryString, replaceString) {
let text_ = ""
for (let i = 0; i < text.length; i++) {
if (text[i] === queryString) {
text_ += replaceString
} else {
text_ += text[i]
}
}
return text_
}
setupRatesCache(ratesCacheOptions) {
if (typeof ratesCacheOptions != "object")
throw new TypeError("ratesCacheOptions should be an object")
if (ratesCacheOptions.isRatesCaching === undefined)
throw new Error(`ratesCacheOptions should have a property called isRatesCaching`)
if (typeof ratesCacheOptions.isRatesCaching != "boolean")
throw new TypeError("ratesCacheOptions.isRatesCaching should be a boolean")
if (typeof ratesCacheOptions.ratesCacheDuration != "number")
throw new TypeError("ratesCacheOptions.ratesCacheDuration should be a number")
if (ratesCacheOptions.ratesCacheDuration <= 0)
throw new Error("ratesCacheOptions.ratesCacheDuration should be a positive number of seconds")
this.isRatesCaching = ratesCacheOptions.isRatesCaching;
if (ratesCacheOptions.ratesCacheDuration === undefined)
this.ratesCacheDuration = 3600; // Defaults to 3600 seconds (1 hour)
else
this.ratesCacheDuration = ratesCacheOptions.ratesCacheDuration;
return this
}
rates() {
if (this.currencyFrom === this.currencyTo) {
return new Promise((resolve, _) => {
resolve(1)
})
} else {
let currencyPair = this.currencyFrom.toUpperCase() + this.currencyTo.toUpperCase();
let now = new Date();
if (currencyPair in this.ratesCache && now < this.ratesCache[currencyPair].expiryDate) {
return new Promise((resolve, _) => {
resolve(this.ratesCache[currencyPair].rate);
});
} else {
return new Promise((resolve, reject) => {
request(`https://www.google.com/search?q=${this.currencyAmount}+${this.currencyFrom}+to+${this.currencyTo}+&hl=en`, function(error, response, body) {
if (error) {
return reject(error);
} else {
resolve(body);
}
});
}).then((body) => {
return cheerio.load(body)
})
.then(($) => {
return $(".iBp4i").text().split(" ")[0]
})
.then((rates) => {
if (this.isDecimalComma) {
if (rates.includes("."))
rates = this.replaceAll(rates, ".", "")
if (rates.includes(","))
rates = this.replaceAll(rates, ",", ".")
} else {
if (rates.includes(","))
rates = this.replaceAll(rates, ",", "")
}
rates = parseFloat(rates) / this.currencyAmount
if (this.isRatesCaching) {
this.addRateToRatesCache(currencyPair, rates);
}
return rates
})
}
}
}
convert(currencyAmount) {
if (currencyAmount !== undefined) {
this.amount(currencyAmount)
}
if (this.currencyFrom == "")
throw new Error("currency code cannot be an empty string")
if (this.currencyTo == "")
throw new Error("currency code cannot be an empty string")
if (this.currencyAmount == 0)
throw new Error("currency amount should be a positive value")
return this.rates().then((rates) => {
this.convertedValue = rates * this.currencyAmount
return this.convertedValue
})
}
currencyName(currencyCode_) {
if (typeof currencyCode_ != "string")
throw new TypeError("currency code should be a string")
if (!this.currencyCode.includes(currencyCode_.toUpperCase()))
throw new Error(`${currencyCode_} is not a valid currency code`)
return this.currencies[currencyCode_]
}
addRateToRatesCache(currencyPair, rate_) {
if (typeof currencyPair != "string")
throw new TypeError("currency pair should be a string")
if (typeof rate_ != "number")
throw new TypeError("rate should be a number")
let now = new Date();
if (currencyPair in this.ratesCache) {
if (now > this.ratesCache[currencyPair].expiryDate) {
let newExpiry = new Date();
newExpiry.setSeconds(newExpiry.getSeconds() + this.ratesCacheDuration);
this.ratesCache[currencyPair] = {
rate: rate_,
expiryDate: newExpiry
};
}
} else {
let newExpiry = new Date();
newExpiry.setSeconds(newExpiry.getSeconds() + this.ratesCacheDuration);
this.ratesCache[currencyPair] = {
rate: rate_,
expiryDate: newExpiry
};
}
}
}
module.exports = CurrencyConverter