external-ip
Advanced tools
Comparing version 0.0.5 to 0.0.6
76
index.js
'use strict'; | ||
var services = require('./lib/services').services; | ||
var extIP = require('./lib/extIP'); | ||
var utils = require('./lib/utils'); | ||
module.exports.getIP = function (cb) { | ||
var errors = []; | ||
utils.asyncLoop({ | ||
iterations: services.length, | ||
exec: function (i, stop, next) { | ||
services[i].getIP(function (err, ip) { | ||
if (err) { | ||
err = services[i].url + ' : ' + err; | ||
errors.push(err); | ||
next(); | ||
} else { | ||
stop(ip); | ||
} | ||
}); | ||
}, | ||
done: function (ip) { | ||
cb.apply(null, ip ? [null, ip] : [errors, null]); | ||
} | ||
}); | ||
module.exports = function (extConf) { | ||
extConf = extConf || {}; | ||
var extValid = utils.validateConfig(extConf); | ||
if (extValid.errors.length) { | ||
throw new Error(extConf.errors); | ||
} | ||
// Check: https://github.com/mjhasbach/MOIRA | ||
var defConf = { | ||
replace: false, | ||
services: [ | ||
'http://ifconfig.co/x-real-ip', | ||
'http://ifconfig.me/ip', | ||
'http://icanhazip.com/', | ||
'http://ip.appspot.com/', | ||
'http://curlmyip.com/', | ||
'http://ident.me/', | ||
'http://whatismyip.akamai.com/', | ||
'http://tnx.nl/ip', | ||
'http://myip.dnsomatic.com/', | ||
'http://ipecho.net/plain' | ||
], | ||
timeout: 500 | ||
}; | ||
var config = utils.mergeConfig(extConf, defConf); | ||
var services = extIP.setup(config).services; | ||
var getIP = function (cb) { | ||
var errors = []; | ||
utils.asyncLoop({ | ||
iterations: services.length, | ||
exec: function (i, stop, next) { | ||
services[i].getIP(function (err, ip) { | ||
if (err) { | ||
err = services[i].url + ' : ' + err; | ||
errors.push(err); | ||
next(); | ||
} else { | ||
stop(ip); | ||
} | ||
}); | ||
}, | ||
done: function (ip) { | ||
cb.apply(null, ip ? [null, ip] : [errors, null]); | ||
} | ||
}); | ||
}; | ||
return getIP; | ||
}; |
'use strict'; | ||
var revalidator = require('revalidator'); | ||
/** | ||
@@ -11,5 +13,5 @@ * Taken from: https://github.com/parris/iz/blob/master/src/validators.js | ||
var isIP = function (str) { | ||
// How is this even possible??? | ||
var re = (/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/); | ||
return re.test(str); | ||
// How is this even possible??? | ||
var re = (/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/); | ||
return re.test(str); | ||
}; | ||
@@ -74,6 +76,43 @@ | ||
var validateConfig = function (config) { | ||
return revalidator.validate(config, { | ||
properties: { | ||
replace: { | ||
description: 'true: replaces the default services, false: extends them', | ||
type: 'boolean', | ||
allowEmpty: false, | ||
dependencies: 'services' | ||
}, | ||
services: { | ||
description: 'array of urls that return the ip in the document body', | ||
type: 'array', | ||
minItems: 1, | ||
allowEmpty: false, | ||
format: 'url' | ||
}, | ||
timeout: { | ||
description: 'timeout per request', | ||
type: 'integer', | ||
allowEmpty: false | ||
} | ||
} | ||
}); | ||
}; | ||
var mergeConfig = function (extCfg, defCfg) { | ||
return { | ||
// Kill it with fire! | ||
services: extCfg.replace ? extCfg.services : extCfg.services && defCfg.services.concat(extCfg.services) || defCfg.services, | ||
timeout: extCfg.timeout || defCfg.timeout | ||
}; | ||
}; | ||
module.exports = { | ||
isIP: isIP, | ||
asyncLoop: asyncLoop | ||
isIP: isIP, | ||
asyncLoop: asyncLoop, | ||
validateConfig: validateConfig, | ||
mergeConfig: mergeConfig | ||
}; |
{ | ||
"name": "external-ip", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"description": "Get your external IP, with fallbacks", | ||
@@ -27,3 +27,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"request": "^2.40.0" | ||
"request": "^2.40.0", | ||
"revalidator": "^0.2.0" | ||
}, | ||
@@ -30,0 +31,0 @@ "devDependencies": { |
@@ -17,15 +17,20 @@ #external-ip | ||
##Test | ||
Change your working directory to the project's root, `npm install` to get the development dependencies and then run `npm test` | ||
##Usage | ||
basic | ||
```javascript | ||
var getIP = require('external-ip').getIP; | ||
'use strict'; | ||
var getIP = require('../index')(); | ||
getIP(function (err, ip) { | ||
if (err) { | ||
//Every service in the list failed to return an ip | ||
} else { | ||
//Do stuff | ||
// every service in the list has failed | ||
throw err; | ||
} | ||
console.log(ip); | ||
}); | ||
@@ -35,2 +40,24 @@ | ||
with configuration | ||
```javascript | ||
'use strict'; | ||
var extIP = require('../index'); | ||
var getIP = extIP({ | ||
replace: true, // true: replace the default services list, false: extend it, default: false | ||
services: ['http://ifconfig.co/x-real-ip', 'http://ifconfig.me/ip'], | ||
timeout: 600 // set timeout per request, default: 500ms | ||
}); | ||
getIP(function (err, ip) { | ||
if (err) { | ||
throw err; | ||
} | ||
console.log(ip); | ||
}); | ||
``` | ||
##Why? | ||
@@ -40,6 +67,3 @@ No idea, really. Just another lib that gives you your external ip address | ||
##Todo: | ||
* Complete tests | ||
* Document | ||
* Clean up some mess | ||
* Use custom urls | ||
* ...?? | ||
* clean up some mess | ||
* sequential / parallel (spam) requests ? |
@@ -6,3 +6,3 @@ 'use strict'; | ||
// Integration test | ||
var getIP = require('../index').getIP; | ||
var extIP = require('../index'); | ||
var utils = require('../lib/utils'); | ||
@@ -12,4 +12,5 @@ var should = require('should'); | ||
describe('index.js test', function () { | ||
it('Should return an IP', function (done) { | ||
it('Should return an IP with default configuration', function (done) { | ||
this.timeout(3000); | ||
var getIP = extIP(); | ||
getIP(function (err, ip) { | ||
@@ -21,2 +22,18 @@ (err === null).should.be.true; | ||
}); | ||
it('Should return an IP with custom configuration', function (done) { | ||
this.timeout(3000); | ||
var getIP = extIP({ | ||
replace: true, // true: replace the default services list, false: extend it, default: false | ||
services: ['http://ifconfig.co/x-real-ip', 'http://ifconfig.me/ip'], | ||
timeout: 600 // set timeout per request, default: 500ms | ||
}); | ||
getIP(function (err, ip) { | ||
(err === null).should.be.true; | ||
utils.isIP(ip).should.be.true; | ||
done(); | ||
}); | ||
}); | ||
}); |
@@ -26,3 +26,3 @@ 'use strict'; | ||
it('should loop i times and pass the arguments to done callback', function(cb) { | ||
it('should loop i times and pass the arguments to done callback', function (cb) { | ||
var i = 10; | ||
@@ -35,3 +35,3 @@ utils.asyncLoop({ | ||
done: function (result, bat) { | ||
result.should.equal(i-1); | ||
result.should.equal(i - 1); | ||
bat.should.equal('man'); | ||
@@ -45,3 +45,3 @@ cb(); | ||
it('should loop i times and stop at n and pass the arguments to done callback', function(cb) { | ||
it('should loop i times and stop at n and pass the arguments to done callback', function (cb) { | ||
var i = 10; | ||
@@ -52,3 +52,3 @@ var n = 4; | ||
exec: function (i, stop, next) { | ||
if(i === n) { | ||
if (i === n) { | ||
stop(i, 'tab'); | ||
@@ -67,2 +67,82 @@ } | ||
it('should validate the config object', function () { | ||
var validCfg1 = { | ||
replace: false, | ||
services: ['http://ifconfig.co/x-real-ip','http://ifconfig.me/ip'], | ||
timeout: 500 | ||
}; | ||
utils.validateConfig(validCfg1).valid.should.be.true; | ||
var validCfg2 = { | ||
services: ['http://ifconfig.co/x-real-ip','http://ifconfig.me/ip'], | ||
timeout: 500 | ||
}; | ||
utils.validateConfig(validCfg2).valid.should.be.true; | ||
var validCfg3 = { | ||
timeout: 500 | ||
}; | ||
utils.validateConfig(validCfg3).valid.should.be.true; | ||
var validCfg4 = {}; | ||
utils.validateConfig(validCfg4).valid.should.be.true; | ||
var invalidCfg1 = { | ||
replace: 'batman', | ||
services: [], | ||
timeout: 'robin' | ||
}; | ||
utils.validateConfig(invalidCfg1).errors.length.should.equal(3); | ||
var invalidCfg2 = { | ||
replace: true | ||
}; | ||
utils.validateConfig(invalidCfg2).errors.length.should.equal(1); | ||
var invalidCfg3 = { | ||
services: ['I am THE Batman'] | ||
}; | ||
utils.validateConfig(invalidCfg3).errors.length.should.equal(1); | ||
}); | ||
it('should merge a valid configuration with default configuration', function () { | ||
var defConf = { | ||
replace: false, | ||
services: ['http://ifconfig.co/x-real-ip','http://ifconfig.me/ip'], | ||
timeout: 500 | ||
}; | ||
var ext1 = {}; | ||
var ext2 = { | ||
services: ['http://ifconfig.co/x-real-ip','http://ifconfig.me/ip'], | ||
timeout: 1000 | ||
}; | ||
var ext3 = { | ||
replace: true, | ||
services: ['http://ifconfig.co/x-real-ip'] | ||
}; | ||
var merged = utils.mergeConfig(ext1, defConf); | ||
merged.should.have.property('timeout', 500); | ||
merged.should.have.property('services').with.lengthOf(2); | ||
merged = utils.mergeConfig(ext2, defConf); | ||
merged.should.have.property('timeout', 1000); | ||
merged.should.have.property('services').with.lengthOf(4); | ||
merged = utils.mergeConfig(ext3, defConf); | ||
merged.should.have.property('timeout', 500); | ||
merged.should.have.property('services').with.lengthOf(1); | ||
}); | ||
}); |
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
17381
12
412
66
2
1
+ Addedrevalidator@^0.2.0
+ Addedrevalidator@0.2.0(transitive)