cidr-tools 11.0.9 → 11.0.10

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.
Files changed (2) hide show
  1. package/dist/index.js +63 -49
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,10 +1,8 @@
1
- import { ipVersion, parseIp, stringifyIp, normalizeIp } from "ip-bigint";
1
+ import { parseIp, stringifyIp, normalizeIp } from "ip-bigint";
2
2
  const bits = { 4: 32, 6: 128 };
3
3
  function uniq(arr) {
4
- return Array.from(new Set(arr));
5
- }
6
- function cidrVersion(cidr) {
7
- return cidr.includes("/") ? ipVersion(cidr) : 0;
4
+ const set = new Set(arr);
5
+ return set.size === arr.length ? arr : Array.from(set);
8
6
  }
9
7
  function doNormalize(cidr, { compress = true, hexify = false } = {}) {
10
8
  const { start, end, prefix, version, prefixPresent } = parseCidr(cidr);
@@ -23,61 +21,65 @@ function normalizeCidr(cidr, opts) {
23
21
  }
24
22
  }
25
23
  function parseCidr(str) {
26
- const cidrVer = cidrVersion(str);
27
24
  const parsed = /* @__PURE__ */ Object.create(null);
28
- let cidr;
29
- if (cidrVer) {
30
- cidr = str;
31
- parsed.version = cidrVer;
32
- } else {
33
- const version2 = ipVersion(str);
34
- if (version2) {
35
- cidr = `${str}/${bits[version2]}`;
36
- parsed.version = version2;
37
- } else {
25
+ const slashIndex = str.indexOf("/");
26
+ let ipPart;
27
+ let prefix;
28
+ if (slashIndex !== -1) {
29
+ ipPart = str.substring(0, slashIndex);
30
+ prefix = str.substring(slashIndex + 1);
31
+ if (!/^[0-9]+$/.test(prefix)) {
38
32
  throw new Error(`Network is not a CIDR or IP: "${str}"`);
39
33
  }
34
+ parsed.prefixPresent = true;
35
+ } else {
36
+ ipPart = str;
37
+ parsed.prefixPresent = false;
38
+ prefix = "";
40
39
  }
41
- const [ipAndMisc, prefix] = cidr.split("/");
42
- if (!/^[0-9]+$/.test(prefix)) {
40
+ const { number, version, ipv4mapped, scopeid } = parseIp(ipPart);
41
+ if (!version) {
43
42
  throw new Error(`Network is not a CIDR or IP: "${str}"`);
44
43
  }
45
- const { number, version, ipv4mapped, scopeid } = parseIp(ipAndMisc);
44
+ if (!parsed.prefixPresent) {
45
+ prefix = String(bits[version]);
46
+ }
47
+ parsed.version = version;
46
48
  parsed.ip = stringifyIp({ number, version, ipv4mapped, scopeid });
47
49
  parsed.cidr = `${parsed.ip}/${prefix}`;
48
50
  parsed.prefix = prefix;
49
- parsed.prefixPresent = Boolean(cidrVer);
50
51
  const numBits = bits[version];
51
- const hostBits = BigInt(numBits - Number(prefix));
52
- const mask = hostBits > 0n ? (1n << hostBits) - 1n : 0n;
52
+ const hostBits = numBits - Number(prefix);
53
+ const mask = hostBits > 0 ? (1n << BigInt(hostBits)) - 1n : 0n;
53
54
  parsed.start = number & ~mask;
54
55
  parsed.end = number | mask;
55
56
  return parsed;
56
57
  }
57
58
  function parseCidrLean(str) {
58
- const cidrVer = cidrVersion(str);
59
- let version;
60
- let cidr;
61
- if (cidrVer) {
62
- cidr = str;
63
- version = cidrVer;
64
- } else {
65
- const v = ipVersion(str);
66
- if (v) {
67
- version = v;
68
- cidr = `${str}/${bits[version]}`;
69
- } else {
59
+ const slashIndex = str.indexOf("/");
60
+ let ipPart;
61
+ let prefixNum;
62
+ if (slashIndex !== -1) {
63
+ ipPart = str.substring(0, slashIndex);
64
+ const prefixStr = str.substring(slashIndex + 1);
65
+ if (!/^[0-9]+$/.test(prefixStr)) {
70
66
  throw new Error(`Network is not a CIDR or IP: "${str}"`);
71
67
  }
68
+ prefixNum = Number(prefixStr);
69
+ } else {
70
+ ipPart = str;
71
+ prefixNum = -1;
72
72
  }
73
- const [ipAndMisc, prefix] = cidr.split("/");
74
- if (!/^[0-9]+$/.test(prefix)) {
73
+ const { number, version } = parseIp(ipPart);
74
+ if (!version) {
75
75
  throw new Error(`Network is not a CIDR or IP: "${str}"`);
76
76
  }
77
- const { number, version: parsedVersion } = parseIp(ipAndMisc);
78
- const numBits = bits[parsedVersion];
79
- const hostBits = BigInt(numBits - Number(prefix));
80
- const mask = hostBits > 0n ? (1n << hostBits) - 1n : 0n;
77
+ if (prefixNum === -1) {
78
+ prefixNum = bits[version];
79
+ }
80
+ const numBits = bits[version];
81
+ const hostBits = numBits - prefixNum;
82
+ const mask = hostBits > 0 ? (1n << BigInt(hostBits)) - 1n : 0n;
81
83
  return {
82
84
  start: number & ~mask,
83
85
  end: number | mask,
@@ -144,7 +146,7 @@ function subparts(part, output) {
144
146
  let biggest = biggestPowerOfTwo(size);
145
147
  let start;
146
148
  let end;
147
- if (size === biggest && part.start + size === part.end) {
149
+ if (size === biggest && part.start % biggest === 0n) {
148
150
  output.push(part);
149
151
  return output;
150
152
  } else if (part.start % biggest === 0n) {
@@ -233,11 +235,13 @@ function doMerge(maps) {
233
235
  function mergeCidr(nets) {
234
236
  const arr = uniq(Array.isArray(nets) ? nets : [nets]).map(parseCidrLean);
235
237
  const maps = mapNets(arr);
236
- const merged = { 4: [], 6: [] };
238
+ const merged = [];
237
239
  for (const v of [4, 6]) {
238
- merged[v] = doMerge(maps[v]).map((part) => formatPart(part, v));
240
+ for (const part of doMerge(maps[v])) {
241
+ merged.push(formatPart(part, v));
242
+ }
239
243
  }
240
- return [...merged[4], ...merged[6]];
244
+ return merged;
241
245
  }
242
246
  function excludeCidr(base, excl) {
243
247
  const baseArr = uniq(Array.isArray(base) ? base : [base]).map(parseCidrLean);
@@ -254,7 +258,9 @@ function excludeCidr(base, excl) {
254
258
  for (const exclPart of excls[v]) {
255
259
  const newBases = [];
256
260
  for (const basePart of bases[v]) {
257
- newBases.push(...excludeNetsParts(basePart, exclPart));
261
+ for (const part of excludeNetsParts(basePart, exclPart)) {
262
+ newBases.push(part);
263
+ }
258
264
  }
259
265
  bases[v] = newBases;
260
266
  }
@@ -279,9 +285,13 @@ function* expandCidr(nets) {
279
285
  function overlapCidr(a, b) {
280
286
  const aNets = uniq(Array.isArray(a) ? a : [a]).map(parseCidrLean);
281
287
  const bNets = uniq(Array.isArray(b) ? b : [b]).map(parseCidrLean);
288
+ const aByVersion = { 4: [], 6: [] };
289
+ const bByVersion = { 4: [], 6: [] };
290
+ for (const n of aNets) aByVersion[n.version].push(n);
291
+ for (const n of bNets) bByVersion[n.version].push(n);
282
292
  for (const v of [4, 6]) {
283
- const aVer = aNets.filter((n) => n.version === v).sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
284
- const bVer = bNets.filter((n) => n.version === v).sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
293
+ const aVer = aByVersion[v].sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
294
+ const bVer = bByVersion[v].sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
285
295
  let i = 0, j = 0;
286
296
  while (i < aVer.length && j < bVer.length) {
287
297
  const aNet = aVer[i];
@@ -296,9 +306,13 @@ function overlapCidr(a, b) {
296
306
  function containsCidr(a, b) {
297
307
  const aNets = uniq(Array.isArray(a) ? a : [a]).map(parseCidrLean);
298
308
  const bNets = uniq(Array.isArray(b) ? b : [b]).map(parseCidrLean);
309
+ const aByVersion = { 4: [], 6: [] };
310
+ const bByVersion = { 4: [], 6: [] };
311
+ for (const n of aNets) aByVersion[n.version].push(n);
312
+ for (const n of bNets) bByVersion[n.version].push(n);
299
313
  for (const v of [4, 6]) {
300
- const containers = aNets.filter((n) => n.version === v).sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
301
- const targets = bNets.filter((n) => n.version === v);
314
+ const containers = aByVersion[v].sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
315
+ const targets = bByVersion[v];
302
316
  if (targets.length === 0) continue;
303
317
  if (containers.length === 0) return false;
304
318
  const maxEnd = new Array(containers.length);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cidr-tools",
3
- "version": "11.0.9",
3
+ "version": "11.0.10",
4
4
  "author": "silverwind <me@silverwind.io>",
5
5
  "description": "Tools to work with IPv4 and IPv6 CIDR",
6
6
  "repository": "silverwind/cidr-tools",