+28
-23
| #!/usr/bin/env node | ||
| 'use strict'; | ||
| var pkg = require('./package.json'); | ||
| var currency = require('./'); | ||
| var argv = process.argv.slice(2); | ||
| const currency = require('./') | ||
| const argv = process.argv.slice(2) | ||
| const updateNotifier = require('update-notifier'); | ||
| updateNotifier({pkg}).notify(); | ||
| const updateNotifier = require('update-notifier') | ||
| const pkg = require('./package.json') | ||
| updateNotifier({pkg}).notify() | ||
| function help() { | ||
| console.log([ | ||
| '', | ||
| ' ' + pkg.description, | ||
| ' ' + pkg.description, | ||
| '', | ||
| ' Example', | ||
| ' currency 10 usd dkk', | ||
| ' $ currency 10 usd dkk', | ||
| ' => 10 USD = 62.208 DKK', | ||
| '', | ||
| ' => 57.75516' | ||
| ].join('\n')); | ||
| ' See readme.md for detailed usage.' | ||
| ].join('\n')) | ||
| } | ||
| if (argv.indexOf('--help') !== -1) { | ||
| help(); | ||
| return; | ||
| help() | ||
| return | ||
| } | ||
| if (argv.indexOf('--version') !== -1) { | ||
| console.log(pkg.version); | ||
| return; | ||
| console.log(pkg.version) | ||
| return | ||
| } | ||
| var opts = { | ||
| amount: argv[0], | ||
| from: argv[1], | ||
| to: argv[2] | ||
| }; | ||
| let opts = { | ||
| amount: argv[0] || 1, | ||
| from: (argv[1] || 'USD').toUpperCase(), | ||
| to: (argv[2] || 'BTC').toUpperCase() | ||
| } | ||
| currency(opts).then(console.log).catch(err => { | ||
| console.log(err); | ||
| currency(opts) | ||
| .then(result => { | ||
| console.log(`${opts.amount} ${opts.from} = ${result} ${opts.to}`) | ||
| }) | ||
| .catch(err => { | ||
| console.log(err) | ||
| process.exit(1); | ||
| }); | ||
| process.exit(1) | ||
| }) |
+83
-21
@@ -1,32 +0,94 @@ | ||
| 'use strict'; | ||
| const got = require('got') | ||
| const money = require('money') | ||
| const got = require('got'); | ||
| const money = require('money'); | ||
| const FIXER_URL = 'https://api.fixer.io/latest' | ||
| const BLOCKCHAIN_URL = 'https://blockchain.info/ticker' | ||
| const ETHERCHAIN_URL = 'https://etherchain.org/api/statistics/price' | ||
| const path = 'https://api.fixer.io/latest'; | ||
| const CURRENCY_BITCOIN = 'BTC' | ||
| const CURRENCY_ETHEREUM = 'ETH' | ||
| let isAnyBTC = (from, to) => [from, to].includes(CURRENCY_BITCOIN) | ||
| let isAnyETH = (from, to) => [from, to].includes(CURRENCY_ETHEREUM) | ||
| const httpOpts = { | ||
| json: true | ||
| } | ||
| module.exports = (opts) => { | ||
| if (opts.amount === void 0) { | ||
| opts.amount = 1; | ||
| } | ||
| let { | ||
| amount = 1, | ||
| from = 'USD', | ||
| to = CURRENCY_BITCOIN | ||
| } = opts | ||
| if (opts.from === void 0) { | ||
| opts.from = 'usd'; | ||
| let base = from | ||
| let promises = [] | ||
| const anyBTC = isAnyBTC(from, to) | ||
| const anyETH = isAnyETH(from, to) | ||
| if (anyBTC) { | ||
| base = (from === CURRENCY_BITCOIN) ? to : from | ||
| promises.push(got(BLOCKCHAIN_URL, httpOpts)) | ||
| } | ||
| if (opts.to === void 0) { | ||
| opts.to = 'dkk'; | ||
| if (anyETH) { | ||
| // always default base to USD when dealing with Etherum | ||
| base = 'USD' | ||
| promises.push(got(ETHERCHAIN_URL, httpOpts)) | ||
| } | ||
| return got(path, {json:true}).then(response => { | ||
| money.base = response.body.base; | ||
| money.rates = response.body.rates; | ||
| promises.unshift(got(`${FIXER_URL}?base=${base}`, httpOpts)) | ||
| const converted = money.convert(opts.amount, { | ||
| from: opts.from.toUpperCase(), | ||
| to: opts.to.toUpperCase() | ||
| }); | ||
| return Promise.all(promises).then(result => { | ||
| let [fixer] = result | ||
| return Number(converted.toFixed(3)); | ||
| }); | ||
| }; | ||
| money.base = fixer.body.base | ||
| money.rates = fixer.body.rates | ||
| let conversionOpts = { | ||
| from, | ||
| to | ||
| } | ||
| if (anyBTC) { | ||
| let blockchain = result.find(r => r.body.hasOwnProperty(base)) | ||
| Object.assign(money.rates, { | ||
| BTC: blockchain.body[base].last | ||
| }) | ||
| } | ||
| if (anyETH) { | ||
| let etherchain = result.find(r => r.body.hasOwnProperty('data') && r.body.status === 1) | ||
| let {usd} = etherchain.body.data[etherchain.body.data.length - 1] | ||
| let ethTo = to === CURRENCY_ETHEREUM ? from : to | ||
| let etherumConversionOpts = { | ||
| from: 'USD', // always convert from USD | ||
| to: ethTo | ||
| } | ||
| let eth = money.convert(usd, etherumConversionOpts) | ||
| // set proper base | ||
| money.base = ethTo | ||
| Object.assign(money.rates, { | ||
| ETH: eth | ||
| }) | ||
| } | ||
| if (anyBTC || anyETH) { | ||
| // swap the conversion opts | ||
| Object.assign(conversionOpts, { | ||
| from: to, | ||
| to: from | ||
| }) | ||
| } | ||
| return money.convert(amount, conversionOpts) | ||
| }) | ||
| } |
+9
-7
| { | ||
| "name": "currency", | ||
| "version": "3.0.0", | ||
| "description": "simple currency conversion cli using openexchangerates.org", | ||
| "version": "4.0.0", | ||
| "description": "simple currency conversion cli", | ||
| "main": "index.js", | ||
@@ -10,3 +10,5 @@ "keywords": [ | ||
| "rates", | ||
| "convert" | ||
| "convert", | ||
| "bitcoin", | ||
| "etherum" | ||
| ], | ||
@@ -21,5 +23,5 @@ "license": "MIT", | ||
| "dependencies": { | ||
| "got": "6.1.1", | ||
| "got": "7.1.0", | ||
| "money": "0.2.0", | ||
| "update-notifier": "0.6.0" | ||
| "update-notifier": "2.2.0" | ||
| }, | ||
@@ -40,5 +42,5 @@ "author": { | ||
| "devDependencies": { | ||
| "ava": "0.12.0", | ||
| "nock": "7.2.2" | ||
| "ava": "0.22.0", | ||
| "nock": "9.0.19" | ||
| } | ||
| } |
+24
-3
| # currency [](https://travis-ci.org/srn/currency) | ||
| > simple currency conversion cli using [fixer.io](http://fixer.io/) | ||
| > simple currency conversion cli using [fixer.io](http://fixer.io), [blockchain.info](https://blockchain.info) and [etherchain.org](https://etherchain.org) | ||
@@ -11,2 +11,8 @@ ## Install | ||
| ## Currencies | ||
| - All currencies listed in the [European Central Bank](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html) API | ||
| - Bitcoin using [blockchain.info](https://blockchain.info) | ||
| - Ethereum using [etherchain.org](https://etherchain.org) | ||
| ## CLI | ||
@@ -20,9 +26,24 @@ | ||
| Example | ||
| currency 10 usd dkk | ||
| $ currency 10 usd dkk | ||
| => 10 USD = 62.208 DKK | ||
| => 57.75516 | ||
| $ currency 1 btc usd | ||
| => 1 BTC = 3746.18 USD | ||
| $ currency 500 usd btc | ||
| => 500 USD = 0.13358982579886716 BTC | ||
| $ currency 1 eth usd | ||
| => 1 ETH = 282.81 USD | ||
| $ currency 500 usd eth | ||
| => 500 USD = 1.767971429581698 ETH | ||
| ``` | ||
| ## API | ||
| ## License | ||
| MIT © [Søren Brokær](http://srn.io) |
+115
-22
@@ -1,30 +0,123 @@ | ||
| import test from 'ava'; | ||
| import nock from 'nock'; | ||
| import test from 'ava' | ||
| import nock from 'nock' | ||
| import currency from './'; | ||
| import currency from './' | ||
| test.beforeEach(t => { | ||
| const exchangeRates = { | ||
| base: 'USD', | ||
| rates: { | ||
| DKK: 5.775516, | ||
| MYR: 3.230421 | ||
| } | ||
| }; | ||
| nock('https://api.fixer.io') | ||
| .get('/latest?base=USD') | ||
| .reply(200, { | ||
| base: 'USD', | ||
| rates: { | ||
| DKK: 6.2208 | ||
| } | ||
| }) | ||
| nock('https://api.fixer.io') | ||
| .get('/latest') | ||
| .reply(200, exchangeRates); | ||
| }); | ||
| .get('/latest?base=DKK') | ||
| .reply(200, { | ||
| base: 'DKK', | ||
| rates: { | ||
| USD: 0.16075 | ||
| } | ||
| }) | ||
| test('convert 10 usd to dkk', async t => { | ||
| var opts = { | ||
| amount: 10, | ||
| from: 'usd', | ||
| to: 'dkk' | ||
| }; | ||
| nock('https://blockchain.info') | ||
| .get('/ticker') | ||
| .reply(200, { | ||
| "USD" : {"15m" : 3755.12, "last" : 3755.12, "buy" : 3755.29, "sell" : 3754.95, "symbol" : "$"}, | ||
| "DKK" : {"15m" : 23383.98, "last" : 23383.98, "buy" : 23385.04, "sell" : 23382.92, "symbol" : "kr"} | ||
| }) | ||
| const converted = currency(opts); | ||
| nock('https://etherchain.org') | ||
| .get('/api/statistics/price') | ||
| .reply(200, { | ||
| "status": 1, | ||
| "data": [ | ||
| { | ||
| "time": "2017-09-23T16:10:56.000Z", | ||
| "usd": 278.91 | ||
| } | ||
| ] | ||
| }) | ||
| }) | ||
| t.is(await converted, 57.755); | ||
| }); | ||
| test('convert 1 USD to DKK', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'USD', | ||
| to: 'DKK' | ||
| }) | ||
| t.is(await converted, 6.2208) | ||
| }) | ||
| test('convert 1 DKK to USD', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'DKK', | ||
| to: 'USD' | ||
| }) | ||
| t.is(await converted, 0.16075) | ||
| }) | ||
| test('convert 1 BTC to USD', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'BTC', | ||
| to: 'USD' | ||
| }) | ||
| t.is(await converted, 3755.12) | ||
| }) | ||
| test('convert 1 BTC to DKK', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'BTC', | ||
| to: 'DKK' | ||
| }) | ||
| t.is(await converted, 23383.98) | ||
| }) | ||
| test('convert 1 DKK to BTC', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'DKK', | ||
| to: 'BTC' | ||
| }) | ||
| t.is(await converted, 0.00004276431984632214) | ||
| }) | ||
| test('convert 1 ETH to USD', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'ETH', | ||
| to: 'USD' | ||
| }) | ||
| t.is(await converted, 278.91) | ||
| }) | ||
| test('convert 1 ETH to DKK', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'ETH', | ||
| to: 'DKK' | ||
| }) | ||
| t.is(await converted, 1735.043328) | ||
| }) | ||
| test('convert 1 USD to ETH', async t => { | ||
| const converted = currency({ | ||
| amount: 1, | ||
| from: 'USD', | ||
| to: 'ETH' | ||
| }) | ||
| t.is(await converted, 0.0035853859667993255) | ||
| }) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
7420
122.76%212
155.42%48
77.78%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated