ipterate
Advanced tools
Comparing version 1.0.3 to 1.1.0
@@ -16,3 +16,3 @@ 'use strict'; | ||
while (lastIp = this.subnet.nextIp(lastIp)) { | ||
callback(lastIp); | ||
callback(lastIp, this.subnet.buildProgressData(lastIp)); | ||
} | ||
@@ -24,5 +24,5 @@ } | ||
while (lastIp = this.subnet.nextIp(lastIp)) { | ||
await callback(lastIp); | ||
await callback(lastIp, this.subnet.buildProgressData(lastIp)); | ||
} | ||
} | ||
}; |
@@ -85,2 +85,10 @@ 'use strict'; | ||
const ipStringToArray = ipStr => ipStr.split('.').map(part => part * 1); | ||
const calculateIteration = (mask, ip) => { | ||
const binaryIp = toBinaryArray(ip); | ||
const binaryIteration = binaryIp.slice(mask, binaryIp.length); | ||
return parseInt(binaryIteration.join(''), 2) + 1; | ||
}; | ||
class SubnetIpV4 { | ||
@@ -97,3 +105,3 @@ constructor(subnet) { | ||
} | ||
const incrementedIp = incrementIp(lastIp.split('.').map(part => part * 1)); | ||
const incrementedIp = incrementIp(ipStringToArray(lastIp)); | ||
if (!incrementedIp || !firstNBitsMatch(incrementedIp, this.ip, this.mask)) { | ||
@@ -104,2 +112,13 @@ return null; | ||
} | ||
buildProgressData(iteratedIp) { | ||
const ipArray = ipStringToArray(iteratedIp); | ||
if (!firstNBitsMatch(ipArray, this.ip, this.mask)) { | ||
throw new Error('The provided IP address does not match the subnet'); | ||
} | ||
const allIps = Math.pow(2, 32 - this.mask); | ||
const iteration = calculateIteration(this.mask, ipArray); | ||
const completionPercentage = Math.round(iteration / (allIps / 100)); | ||
return {allIps, iteration, completionPercentage}; | ||
} | ||
} | ||
@@ -106,0 +125,0 @@ |
{ | ||
"name": "ipterate", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": " A small utility library to allow you to iterate through all IPs within a given subnet. Remains efficient no matter how many IPs there are in the range.", | ||
"main": "index.js", | ||
"directories": { | ||
"test": "test", | ||
"lib": "lib" | ||
}, | ||
"scripts": { | ||
"test": "node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --recursive && cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js" | ||
"test": "node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --recursive", | ||
"send-coverage": "cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js" | ||
}, | ||
"repository": "https://github.com/kamiljano/ipterate", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/kamiljano/ipterate.git" | ||
}, | ||
"homepage": "https://github.com/kamiljano/ipterate", | ||
"keywords": [ | ||
@@ -16,3 +25,3 @@ "ip", | ||
], | ||
"author": "kgjanowski@gmail.com", | ||
"author": "Kamil Janowski <kgjanowski@gmail.com>", | ||
"license": "ISC", | ||
@@ -19,0 +28,0 @@ "devDependencies": { |
@@ -11,2 +11,4 @@ [![Build Status](https://travis-ci.org/kamiljano/ipterate.svg?branch=master)](https://travis-ci.org/kamiljano/ipterate) | ||
## Basic usage | ||
For instance the following code | ||
@@ -39,3 +41,3 @@ | ||
If you want to perform an asynchronous action, make sure that your function returns a promise and call `iterateAsync` | ||
If you want to perform an asynchronous action, make sure that your delegate returns a promise and call `iterateAsync` | ||
instead. `iterateAsync` itself returns a promise and will wait for the resolution of the promise returned by | ||
@@ -51,4 +53,16 @@ your delegate, before it provides you with another IP. | ||
## Iteration information | ||
Iterating through large sets of IPs might take a while. For this reason you might want to track the progress of your iteration. | ||
In the second parameter the `iterate` and `iterateAsync` provide itaration information to your delegate function. | ||
ipterate.range('0.0.0.0/0').iterate((ip, data) => { | ||
console.log(`All IPs available in this subnet: ${data.allIps}`); | ||
console.log(`Current iteration: ${data.iteration}`); //starts from 1 | ||
console.log(`Completion percentage: ${data.completionPercentage}`); // an integer number between 0 and 100 | ||
// calculated based on allIps and iteration | ||
}); | ||
# Installation | ||
npm install --save ipterate |
@@ -21,13 +21,29 @@ 'use strict'; | ||
expect(callback).to.have.been.called.exactly(256); | ||
expect(callback).to.have.been.called.with('255.255.255.0'); | ||
expect(callback).to.have.been.called.with('255.255.255.255'); | ||
expect(callback).to.have.been.called.with('255.255.255.0', { | ||
allIps: 256, | ||
iteration: 1, | ||
completionPercentage: 0 | ||
}); | ||
expect(callback).to.have.been.called.with('255.255.255.255', { | ||
allIps: 256, | ||
iteration: 256, | ||
completionPercentage: 100 | ||
}); | ||
}); | ||
it('WHEN triggering the iterateAsync(), THEN all IPs within the subnet are properly processed', async () => { | ||
await new IpRange('255.255.255.0/24').iterateAsync(async ip => { | ||
callback(ip); | ||
await new IpRange('255.255.255.0/24').iterateAsync(async (ip, data) => { | ||
callback(ip, data); | ||
}); | ||
expect(callback).to.have.been.called.exactly(256); | ||
expect(callback).to.have.been.called.with('255.255.255.0'); | ||
expect(callback).to.have.been.called.with('255.255.255.255'); | ||
expect(callback).to.have.been.called.with('255.255.255.0', { | ||
allIps: 256, | ||
iteration: 1, | ||
completionPercentage: 0 | ||
}); | ||
expect(callback).to.have.been.called.with('255.255.255.255', { | ||
allIps: 256, | ||
iteration: 256, | ||
completionPercentage: 100 | ||
}); | ||
}); | ||
@@ -34,0 +50,0 @@ |
@@ -76,2 +76,32 @@ 'use strict'; | ||
}); | ||
describe('WHEN the string is a valid subnet identifier AND the buildProgressData() is called', () => { | ||
it('with a valid IP, but one that does not match the subnet, THEN an error is thrown', () => { | ||
const subnet = new SubnetIpV4('255.255.255.0/24'); | ||
expectError(() => subnet.buildProgressData('0.0.0.0')); | ||
}); | ||
it('with a valid IP that matches the subnet, THEN a valid number of all IPs is returned', () => { | ||
const subnet = new SubnetIpV4('255.255.255.0/24'); | ||
expect(subnet.buildProgressData('255.255.255.0').allIps).to.equal(256); | ||
}); | ||
it('with a valid max IP that matches the subnet, THEN a valid number of all IPs is returned', () => { | ||
const subnet = new SubnetIpV4('0.0.0.0/0'); | ||
expect(subnet.buildProgressData('255.255.255.255').allIps).to.equal(Math.pow(2, 32)); | ||
expect(subnet.buildProgressData('255.255.255.255').iteration).to.equal(Math.pow(2, 32)); | ||
}); | ||
it('with a valid IP that matches the subnet, THEN a valid index is returned', () => { | ||
const subnet = new SubnetIpV4('255.255.0.0/16'); | ||
expect(subnet.buildProgressData('255.255.1.0').iteration).to.equal(257); | ||
}); | ||
it('with a valid IP that matches the subnet, THEN a valid completion percentage is returned', () => { | ||
const subnet = new SubnetIpV4('255.255.255.0/24'); | ||
expect(subnet.buildProgressData('255.255.255.128').completionPercentage).to.equal(50); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
14342
284
0
65
0