cidr-tools 12.0.3 → 12.1.1

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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region index.d.ts
2
2
  type Network = string;
3
- type Networks = Network | Array<Network>;
3
+ type Networks = Network | ReadonlyArray<Network>;
4
4
  type ValidIpVersion = 4 | 6;
5
5
  type ParsedCidr = {
6
6
  cidr: string;
@@ -16,7 +16,7 @@ type NormalizeOpts = {
16
16
  hexify?: boolean;
17
17
  };
18
18
  /** Returns a string or array (depending on input) with a normalized representation. Will not include a prefix on single IPs. Will set network address to the start of the network. */
19
- declare function normalizeCidr<T extends Network | Array<Network>>(cidr: T, opts?: NormalizeOpts): T;
19
+ declare function normalizeCidr<T extends Networks>(cidr: T, opts?: NormalizeOpts): T;
20
20
  /** 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. */
21
21
  declare function parseCidr(str: Network): ParsedCidr;
22
22
  /** Returns an array of merged networks */
package/dist/index.js CHANGED
@@ -107,7 +107,7 @@ function doNormalize(cidr, opts) {
107
107
  }
108
108
  /** Returns a string or array (depending on input) with a normalized representation. Will not include a prefix on single IPs. Will set network address to the start of the network. */
109
109
  function normalizeCidr(cidr, opts) {
110
- return Array.isArray(cidr) ? cidr.map((entry) => doNormalize(entry, opts)) : doNormalize(cidr, opts);
110
+ return typeof cidr === "string" ? doNormalize(cidr, opts) : cidr.map((entry) => doNormalize(entry, opts));
111
111
  }
112
112
  /** 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. */
113
113
  function parseCidr(str) {
@@ -241,17 +241,19 @@ function subparts4(pStart, pEnd, output) {
241
241
  }
242
242
  }
243
243
  function subparts6(pStart, pEnd, output) {
244
+ const fullSize = pEnd - pStart + 1n;
245
+ const startLowBit = pStart & -pStart;
246
+ if ((fullSize & fullSize - 1n) === 0n && (startLowBit === 0n || startLowBit >= fullSize)) {
247
+ output.push(stringifyIp({
248
+ number: pStart,
249
+ version: 6
250
+ }) + prefixStrings[129 - bigintBitLength(fullSize)]);
251
+ return;
252
+ }
244
253
  let start = pStart;
245
254
  while (start <= pEnd) {
246
255
  const size = pEnd - start + 1n;
247
256
  const lowBit = start & -start;
248
- if ((size & size - 1n) === 0n && (lowBit === 0n || lowBit >= size)) {
249
- output.push(stringifyIp({
250
- number: start,
251
- version: 6
252
- }) + prefixStrings[129 - bigintBitLength(size)]);
253
- return;
254
- }
255
257
  const blockSize = lowBit !== 0n && lowBit <= size ? lowBit : biggestPowerOfTwo(size);
256
258
  output.push(stringifyIp({
257
259
  number: start,
@@ -362,7 +364,7 @@ function subtractSorted6(bases, excls) {
362
364
  }
363
365
  /** Returns an array of merged networks */
364
366
  function mergeCidr(nets) {
365
- const arr = Array.isArray(nets) ? nets : [nets];
367
+ const arr = typeof nets === "string" ? [nets] : nets;
366
368
  const v4 = [];
367
369
  const v6 = [];
368
370
  for (const s of arr) {
@@ -377,8 +379,8 @@ function mergeCidr(nets) {
377
379
  }
378
380
  /** Returns an array of merged remaining networks of the subtraction of `excludeNetworks` from `baseNetworks`. */
379
381
  function excludeCidr(base, excl) {
380
- const baseArr = Array.isArray(base) ? base : [base];
381
- const exclArr = Array.isArray(excl) ? excl : [excl];
382
+ const baseArr = typeof base === "string" ? [base] : base;
383
+ const exclArr = typeof excl === "string" ? [excl] : excl;
382
384
  const v4base = [], v6base = [];
383
385
  const v4excl = [], v6excl = [];
384
386
  for (const s of baseArr) {
@@ -406,7 +408,7 @@ function excludeCidr(base, excl) {
406
408
  }
407
409
  /** Returns a generator for individual IPs contained in the networks. */
408
410
  function* expandCidr(nets) {
409
- const arr = Array.isArray(nets) ? nets : [nets];
411
+ const arr = typeof nets === "string" ? [nets] : nets;
410
412
  const v4 = [];
411
413
  const v6 = [];
412
414
  for (const s of arr) {
@@ -455,7 +457,7 @@ function* expandCidr(nets) {
455
457
  }
456
458
  /** Returns a boolean that indicates if `networksA` overlap (intersect) with `networksB`. */
457
459
  function overlapCidr(a, b) {
458
- if (!Array.isArray(a) && !Array.isArray(b)) {
460
+ if (typeof a === "string" && typeof b === "string") {
459
461
  if (parseIPv4Range(a)) {
460
462
  const startA = rangeV4Start, endA = rangeV4End;
461
463
  if (parseIPv4Range(b)) return startA <= rangeV4End && rangeV4Start <= endA;
@@ -468,8 +470,8 @@ function overlapCidr(a, b) {
468
470
  if (pa.version !== pb.version) return false;
469
471
  return pa.start <= pb.end && pb.start <= pa.end;
470
472
  }
471
- const aArr = Array.isArray(a) ? a : [a];
472
- const bArr = Array.isArray(b) ? b : [b];
473
+ const aArr = typeof a === "string" ? [a] : a;
474
+ const bArr = typeof b === "string" ? [b] : b;
473
475
  const v4a = [], v6a = [];
474
476
  const v4b = [], v6b = [];
475
477
  for (const s of aArr) {
@@ -518,7 +520,7 @@ function overlapCidr(a, b) {
518
520
  }
519
521
  /** Returns a boolean that indicates whether `networksA` fully contain all `networksB`. */
520
522
  function containsCidr(a, b) {
521
- if (!Array.isArray(a) && !Array.isArray(b)) {
523
+ if (typeof a === "string" && typeof b === "string") {
522
524
  if (parseIPv4Range(a)) {
523
525
  const startA = rangeV4Start, endA = rangeV4End;
524
526
  if (parseIPv4Range(b)) return startA <= rangeV4Start && endA >= rangeV4End;
@@ -531,8 +533,8 @@ function containsCidr(a, b) {
531
533
  if (pa.version !== pb.version) return false;
532
534
  return pa.start <= pb.start && pa.end >= pb.end;
533
535
  }
534
- const aArr = Array.isArray(a) ? a : [a];
535
- const bArr = Array.isArray(b) ? b : [b];
536
+ const aArr = typeof a === "string" ? [a] : a;
537
+ const bArr = typeof b === "string" ? [b] : b;
536
538
  const v4a = [], v6a = [];
537
539
  const v4b = [], v6b = [];
538
540
  for (const s of aArr) {
@@ -547,60 +549,60 @@ function containsCidr(a, b) {
547
549
  }
548
550
  if (v4b.length > 0) {
549
551
  if (v4a.length === 0) return false;
550
- if (v4b.length === 1) {
551
- const ts = v4b[0].start, te = v4b[0].end;
552
- let found = false;
553
- for (const a of v4a) if (a.start <= ts && a.end >= te) {
554
- found = true;
552
+ let sorted = false;
553
+ for (const target of v4b) {
554
+ const ts = target.start, te = target.end;
555
+ let covered = false;
556
+ for (const iv of v4a) if (iv.start <= ts && iv.end >= te) {
557
+ covered = true;
555
558
  break;
556
559
  }
557
- if (!found) return false;
558
- } else {
559
- v4a.sort(cmpV4Start);
560
- const maxEnd = new Array(v4a.length);
561
- maxEnd[0] = v4a[0].end;
562
- for (let i = 1; i < v4a.length; i++) maxEnd[i] = Math.max(v4a[i].end, maxEnd[i - 1]);
563
- for (const target of v4b) {
564
- let lo = 0, hi = v4a.length - 1;
565
- let idx = -1;
566
- while (lo <= hi) {
567
- const mid = lo + hi >> 1;
568
- if (v4a[mid].start <= target.start) {
569
- idx = mid;
570
- lo = mid + 1;
571
- } else hi = mid - 1;
560
+ if (covered) continue;
561
+ if (!sorted) {
562
+ v4a.sort(cmpV4Start);
563
+ sorted = true;
564
+ }
565
+ let cur = ts;
566
+ for (const iv of v4a) {
567
+ if (iv.start > cur) break;
568
+ if (iv.end >= cur) {
569
+ if (iv.end >= te) {
570
+ covered = true;
571
+ break;
572
+ }
573
+ cur = iv.end + 1;
572
574
  }
573
- if (idx < 0 || maxEnd[idx] < target.end) return false;
574
575
  }
576
+ if (!covered) return false;
575
577
  }
576
578
  }
577
579
  if (v6b.length > 0) {
578
580
  if (v6a.length === 0) return false;
579
- if (v6b.length === 1) {
580
- const ts = v6b[0].start, te = v6b[0].end;
581
- let found = false;
582
- for (const a of v6a) if (a.start <= ts && a.end >= te) {
583
- found = true;
581
+ let sorted = false;
582
+ for (const target of v6b) {
583
+ const ts = target.start, te = target.end;
584
+ let covered = false;
585
+ for (const iv of v6a) if (iv.start <= ts && iv.end >= te) {
586
+ covered = true;
584
587
  break;
585
588
  }
586
- if (!found) return false;
587
- } else {
588
- v6a.sort(cmpV6Start);
589
- const maxEnd = new Array(v6a.length);
590
- maxEnd[0] = v6a[0].end;
591
- for (let i = 1; i < v6a.length; i++) maxEnd[i] = v6a[i].end > maxEnd[i - 1] ? v6a[i].end : maxEnd[i - 1];
592
- for (const target of v6b) {
593
- let lo = 0, hi = v6a.length - 1;
594
- let idx = -1;
595
- while (lo <= hi) {
596
- const mid = lo + hi >> 1;
597
- if (v6a[mid].start <= target.start) {
598
- idx = mid;
599
- lo = mid + 1;
600
- } else hi = mid - 1;
589
+ if (covered) continue;
590
+ if (!sorted) {
591
+ v6a.sort(cmpV6Start);
592
+ sorted = true;
593
+ }
594
+ let cur = ts;
595
+ for (const iv of v6a) {
596
+ if (iv.start > cur) break;
597
+ if (iv.end >= cur) {
598
+ if (iv.end >= te) {
599
+ covered = true;
600
+ break;
601
+ }
602
+ cur = iv.end + 1n;
601
603
  }
602
- if (idx < 0 || maxEnd[idx] < target.end) return false;
603
604
  }
605
+ if (!covered) return false;
604
606
  }
605
607
  }
606
608
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cidr-tools",
3
- "version": "12.0.3",
3
+ "version": "12.1.1",
4
4
  "author": "silverwind <me@silverwind.io>",
5
5
  "description": "Tools to work with IPv4 and IPv6 CIDR",
6
6
  "keywords": [
@@ -32,20 +32,20 @@
32
32
  "ip-bigint": "^9.0.6"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/node": "25.9.2",
36
- "@typescript/native-preview": "7.0.0-dev.20260609.1",
37
- "@vitest/coverage-v8": "4.1.8",
38
- "eslint": "10.4.1",
39
- "eslint-config-silverwind": "135.0.1",
35
+ "@types/node": "25.9.3",
36
+ "@typescript/native-preview": "7.0.0-dev.20260616.1",
37
+ "@vitest/coverage-v8": "4.1.9",
38
+ "eslint": "10.5.0",
39
+ "eslint-config-silverwind": "136.0.10",
40
40
  "jest-extended": "7.0.0",
41
- "tsdown": "0.22.2",
41
+ "tsdown": "0.22.3",
42
42
  "tsdown-config-silverwind": "3.0.3",
43
43
  "typescript": "6.0.3",
44
44
  "typescript-config-silverwind": "20.0.0",
45
45
  "updates": "17.18.0",
46
46
  "updates-config-silverwind": "4.0.0",
47
47
  "versions": "15.1.1",
48
- "vitest": "4.1.8",
48
+ "vitest": "4.1.9",
49
49
  "vitest-config-silverwind": "11.3.6"
50
50
  }
51
51
  }