cidr-tools 7.0.4 → 7.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -5
- package/index.d.ts +0 -2
- package/index.js +59 -55
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -71,15 +71,14 @@ Returns a string or array (depending on input) with a normalized representation.
|
|
|
71
71
|
|
|
72
72
|
- `network` *String*: A CIDR or IP address.
|
|
73
73
|
|
|
74
|
-
Returns a `parsed` Object which is used internally by this module. It can be used to test whether the passed network is IPv4 or IPv6 or work with the BigInts directly.
|
|
74
|
+
Returns a `parsed` Object which is used internally by this module. It can be used to test whether the passed network is IPv4 or IPv6 or to work with the BigInts directly.
|
|
75
75
|
|
|
76
76
|
`parsed`: `Object`
|
|
77
77
|
- `cidr` String: The CIDR of the network.
|
|
78
|
-
- `version` Number: Either `4` or `6`.
|
|
78
|
+
- `version` Number: IP protocol version. Either `4` or `6`.
|
|
79
79
|
- `prefix` String: The network prefix, e.g. `/64`.
|
|
80
|
-
- `start` BigInt: Start of the network.
|
|
81
|
-
- `end` BigInt:
|
|
82
|
-
- `single` Boolean: `true` when is a single IP.
|
|
80
|
+
- `start` BigInt: Start number of the network.
|
|
81
|
+
- `end` BigInt: End number of the network.
|
|
83
82
|
|
|
84
83
|
## Related
|
|
85
84
|
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ type IPv4Address = string;
|
|
|
2
2
|
type IPv4CIDR = string;
|
|
3
3
|
type IPv6Address = string;
|
|
4
4
|
type IPv6CIDR = string;
|
|
5
|
-
|
|
6
5
|
type Network = IPv4Address | IPv4CIDR | IPv6Address | IPv6CIDR;
|
|
7
6
|
type Networks = Network | Network[];
|
|
8
7
|
|
|
@@ -12,7 +11,6 @@ type Parsed = {
|
|
|
12
11
|
prefix: string;
|
|
13
12
|
start: bigint;
|
|
14
13
|
end: bigint;
|
|
15
|
-
single: boolean;
|
|
16
14
|
};
|
|
17
15
|
|
|
18
16
|
type NormalizeOpts = {
|
package/index.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import {parseIp, stringifyIp, normalizeIp, ipVersion} from "ip-bigint";
|
|
2
2
|
|
|
3
|
-
const bits = {
|
|
4
|
-
4: 32,
|
|
5
|
-
6: 128,
|
|
6
|
-
};
|
|
7
|
-
|
|
3
|
+
const bits = {4: 32, 6: 128};
|
|
8
4
|
const uniq = arr => Array.from(new Set(arr));
|
|
9
5
|
const cidrVersion = cidr => cidr.includes("/") ? ipVersion(cidr) : 0;
|
|
10
6
|
|
|
@@ -20,8 +16,8 @@ function compare(a, b) {
|
|
|
20
16
|
}
|
|
21
17
|
|
|
22
18
|
function doNormalize(cidr, {compress = true, hexify = false} = {}) {
|
|
23
|
-
const {start,
|
|
24
|
-
if (
|
|
19
|
+
const {start, end, prefix, version} = parse(cidr);
|
|
20
|
+
if (start !== end) { // cidr
|
|
25
21
|
// set network address to first address
|
|
26
22
|
const ip = normalizeIp(stringifyIp({number: start, version}), {compress, hexify});
|
|
27
23
|
return `${ip}/${prefix}`;
|
|
@@ -41,7 +37,6 @@ export function normalize(cidr, {compress = true, hexify = false} = {}) {
|
|
|
41
37
|
export function parse(str) {
|
|
42
38
|
const cidrVer = cidrVersion(str);
|
|
43
39
|
const parsed = Object.create(null);
|
|
44
|
-
parsed.single = false;
|
|
45
40
|
|
|
46
41
|
if (cidrVer) {
|
|
47
42
|
parsed.cidr = str;
|
|
@@ -51,13 +46,17 @@ export function parse(str) {
|
|
|
51
46
|
if (version) {
|
|
52
47
|
parsed.cidr = `${str}/${bits[version]}`;
|
|
53
48
|
parsed.version = version;
|
|
54
|
-
parsed.single = true;
|
|
55
49
|
} else {
|
|
56
50
|
throw new Error(`Network is not a CIDR or IP: ${str}`);
|
|
57
51
|
}
|
|
58
52
|
}
|
|
59
53
|
|
|
60
54
|
const [ip, prefix] = parsed.cidr.split("/");
|
|
55
|
+
|
|
56
|
+
if (!/^[0-9]+$/.test(prefix)) {
|
|
57
|
+
throw new Error(`Network is not a CIDR or IP: ${str}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
61
60
|
parsed.prefix = prefix;
|
|
62
61
|
const {number, version} = parseIp(ip);
|
|
63
62
|
const numBits = bits[version];
|
|
@@ -223,75 +222,80 @@ function diff(a, b) {
|
|
|
223
222
|
return a - b;
|
|
224
223
|
}
|
|
225
224
|
|
|
226
|
-
function formatPart(part,
|
|
227
|
-
const ip = normalize(stringifyIp({
|
|
228
|
-
number: BigInt(part.start.toString()),
|
|
229
|
-
version: v,
|
|
230
|
-
}));
|
|
225
|
+
function formatPart(part, version) {
|
|
226
|
+
const ip = normalize(stringifyIp({number: BigInt(part.start.toString()), version}));
|
|
231
227
|
const zeroes = diff(part.end, part.start).toString(2);
|
|
232
|
-
const prefix = bits[
|
|
228
|
+
const prefix = bits[version] - (zeroes.match(/0/g) || []).length;
|
|
233
229
|
return `${ip}/${prefix}`;
|
|
234
230
|
}
|
|
235
231
|
|
|
236
232
|
function mapNets(nets) {
|
|
237
|
-
const maps = {4: {}, 6: {}};
|
|
238
|
-
for (const {start, end, version
|
|
239
|
-
if (!maps[
|
|
240
|
-
if (!maps[
|
|
233
|
+
const maps = {4: {}, 6: {}}; // TODO: use Map with BigInt key
|
|
234
|
+
for (const {start, end, version} of nets) {
|
|
235
|
+
if (!maps[version][start]) maps[version][start] = {};
|
|
236
|
+
if (!maps[version][end]) maps[version][end] = {};
|
|
241
237
|
|
|
242
|
-
if (maps[
|
|
243
|
-
maps[
|
|
238
|
+
if (maps[version][start].start) {
|
|
239
|
+
maps[version][start].start += 1;
|
|
244
240
|
} else {
|
|
245
|
-
maps[
|
|
241
|
+
maps[version][start].start = 1;
|
|
246
242
|
}
|
|
247
243
|
|
|
248
|
-
if (maps[
|
|
249
|
-
maps[
|
|
244
|
+
if (maps[version][end].end) {
|
|
245
|
+
maps[version][end].end += 1;
|
|
250
246
|
} else {
|
|
251
|
-
maps[
|
|
247
|
+
maps[version][end].end = 1;
|
|
252
248
|
}
|
|
253
249
|
}
|
|
254
250
|
return maps;
|
|
255
251
|
}
|
|
256
252
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const
|
|
253
|
+
function doMerge(maps, v) {
|
|
254
|
+
let start = null;
|
|
255
|
+
let end = null;
|
|
256
|
+
const numbers = Object.keys(maps);
|
|
257
|
+
let depth = 0;
|
|
258
|
+
const merged = [];
|
|
261
259
|
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
const end = {4: null, 6: null};
|
|
260
|
+
for (const [index, number] of numbers.entries()) {
|
|
261
|
+
const marker = maps[number];
|
|
265
262
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
263
|
+
if (start === null && marker.start) {
|
|
264
|
+
start = BigInt(number);
|
|
265
|
+
}
|
|
266
|
+
if (marker.end) {
|
|
267
|
+
end = BigInt(number);
|
|
268
|
+
}
|
|
269
269
|
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
if (marker.start) depth += marker.start;
|
|
271
|
+
if (marker.end) depth -= marker.end;
|
|
272
272
|
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
const next = numbers[index + 1];
|
|
274
|
+
if (marker.end && depth === 0 && next && ((BigInt(next) - BigInt(number)) > 1)) {
|
|
275
|
+
// when there is a end and the next part is more than one number away, we cut a part
|
|
276
|
+
for (const sub of subparts({start, end})) {
|
|
277
|
+
merged.push(formatPart(sub, v));
|
|
275
278
|
}
|
|
276
|
-
|
|
277
|
-
|
|
279
|
+
start = null;
|
|
280
|
+
end = null;
|
|
281
|
+
} else if (index === (numbers.length - 1)) {
|
|
282
|
+
// cut the final part
|
|
283
|
+
for (const sub of subparts({start, end})) {
|
|
284
|
+
merged.push(formatPart(sub, v));
|
|
278
285
|
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return merged;
|
|
289
|
+
}
|
|
279
290
|
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
export function merge(nets) {
|
|
292
|
+
// sort to workaround https://github.com/silverwind/cidr-tools/issues/17
|
|
293
|
+
nets = uniq((Array.isArray(nets) ? nets : [nets]).sort(compare).map(parse));
|
|
294
|
+
const maps = mapNets(nets);
|
|
282
295
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
start[v] = null;
|
|
288
|
-
end[v] = null;
|
|
289
|
-
} else if (index === (numbers.length - 1)) {
|
|
290
|
-
for (const sub of subparts({start: start[v], end: end[v]})) {
|
|
291
|
-
merged[v].push(formatPart(sub, v));
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
296
|
+
const merged = {4: [], 6: []};
|
|
297
|
+
for (const v of [4, 6]) {
|
|
298
|
+
merged[v] = doMerge(maps[v], v);
|
|
295
299
|
}
|
|
296
300
|
|
|
297
301
|
return [...merged[4].sort(compare), ...merged[6].sort(compare)];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cidr-tools",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.6",
|
|
4
4
|
"author": "silverwind <me@silverwind.io>",
|
|
5
5
|
"description": "Tools to work with IPv4 and IPv6 CIDR",
|
|
6
6
|
"repository": "silverwind/cidr-tools",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"./index.d.ts"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"ip-bigint": "^8.0.
|
|
21
|
+
"ip-bigint": "^8.0.2"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"eslint": "8.
|
|
25
|
-
"eslint-config-silverwind": "
|
|
26
|
-
"tsd": "0.
|
|
27
|
-
"updates": "15.
|
|
28
|
-
"versions": "12.0.
|
|
29
|
-
"vitest": "
|
|
30
|
-
"vitest-config-silverwind": "
|
|
24
|
+
"eslint": "8.56.0",
|
|
25
|
+
"eslint-config-silverwind": "80.0.3",
|
|
26
|
+
"tsd": "0.30.5",
|
|
27
|
+
"updates": "15.1.2",
|
|
28
|
+
"versions": "12.0.1",
|
|
29
|
+
"vitest": "1.3.1",
|
|
30
|
+
"vitest-config-silverwind": "5.1.1"
|
|
31
31
|
}
|
|
32
32
|
}
|