cidr-tools 12.0.0 → 12.0.2

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
@@ -23,6 +23,7 @@ declare function parseCidr(str: Network): ParsedCidr;
23
23
  declare function mergeCidr(nets: Networks): Array<Network>;
24
24
  /** Returns an array of merged remaining networks of the subtraction of `excludeNetworks` from `baseNetworks`. */
25
25
  declare function excludeCidr(base: Networks, excl: Networks): Array<Network>;
26
+ /** Returns a generator for individual IPs contained in the networks. */
26
27
  declare function expandCidr(nets: Networks): Generator<Network>;
27
28
  /** Returns a boolean that indicates if `networksA` overlap (intersect) with `networksB`. */
28
29
  declare function overlapCidr(a: Networks, b: Networks): boolean;
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ const bits = {
8
8
  const octetStrings = Array.from({ length: 256 }, (_, i) => String(i));
9
9
  const octetDotStrings = Array.from({ length: 256 }, (_, i) => `${i}.`);
10
10
  const prefixStrings = Array.from({ length: 129 }, (_, i) => `/${i}`);
11
+ const prefixNumStrings = Array.from({ length: 129 }, (_, i) => String(i));
11
12
  const cmpV4StartEnd = (a, b) => a.start - b.start || a.end - b.end;
12
13
  const cmpV4Start = (a, b) => a.start - b.start;
13
14
  const cmpV6StartEnd = (a, b) => a.start > b.start ? 1 : a.start < b.start ? -1 : a.end > b.end ? 1 : a.end < b.end ? -1 : 0;
@@ -92,8 +93,7 @@ function doNormalize(cidr, opts) {
92
93
  }
93
94
  /** 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. */
94
95
  function normalizeCidr(cidr, opts) {
95
- if (Array.isArray(cidr)) return cidr.map((entry) => normalizeCidr(entry, opts));
96
- else return doNormalize(cidr, opts);
96
+ return Array.isArray(cidr) ? cidr.map((entry) => doNormalize(entry, opts)) : doNormalize(cidr, opts);
97
97
  }
98
98
  /** 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. */
99
99
  function parseCidr(str) {
@@ -104,7 +104,7 @@ function parseCidr(str) {
104
104
  if (v4num !== -1) {
105
105
  const prefixNum = prefixPresent ? parsePrefixNum(str, slashIndex) : 32;
106
106
  const ip = formatIPv4Fast(v4num);
107
- const prefix = String(prefixNum);
107
+ const prefix = prefixNumStrings[prefixNum] ?? String(prefixNum);
108
108
  const hostBits = 32 - prefixNum;
109
109
  let startNum, endNum;
110
110
  if (hostBits >= 32) {
@@ -130,7 +130,7 @@ function parseCidr(str) {
130
130
  const { number, version, ipv4mapped, scopeid } = parseIp(ipPart);
131
131
  if (!version) throw new Error(`Network is not a CIDR or IP: "${str}"`);
132
132
  if (prefixNum === -1) prefixNum = bits[version];
133
- const prefix = String(prefixNum);
133
+ const prefix = prefixNumStrings[prefixNum] ?? String(prefixNum);
134
134
  const ip = stringifyIp({
135
135
  number,
136
136
  version,
@@ -206,120 +206,37 @@ function biggestPowerOfTwo4(num) {
206
206
  return 1 << 31 - Math.clz32(num) >>> 0;
207
207
  }
208
208
  function subparts4(pStart, pEnd, output) {
209
- if (pEnd < pStart) return;
210
- if (pEnd === pStart) {
209
+ let start = pStart;
210
+ while (start <= pEnd) {
211
+ const size = pEnd - start + 1;
212
+ const lowBit = (start & -start) >>> 0;
213
+ const blockSize = lowBit !== 0 && lowBit <= size ? lowBit : biggestPowerOfTwo4(size);
211
214
  output.push({
212
- start: pStart,
213
- end: pEnd
214
- });
215
- return;
216
- }
217
- if (pEnd - pStart === 1) {
218
- if (pEnd % 2 === 0) output.push({
219
- start: pStart,
220
- end: pStart
221
- }, {
222
- start: pEnd,
223
- end: pEnd
224
- });
225
- else output.push({
226
- start: pStart,
227
- end: pEnd
215
+ start,
216
+ end: start + blockSize - 1
228
217
  });
229
- return;
218
+ start += blockSize;
230
219
  }
231
- const size = pEnd - pStart + 1;
232
- if ((size & size - 1) === 0 && pStart % size === 0) {
233
- output.push({
234
- start: pStart,
235
- end: pEnd
236
- });
237
- return;
238
- }
239
- let biggest = biggestPowerOfTwo4(size);
240
- let start;
241
- let end;
242
- if (pStart % biggest === 0) {
243
- start = pStart;
244
- end = start + biggest - 1;
245
- } else {
246
- start = Math.floor(pEnd / biggest) * biggest;
247
- if (start + biggest - 1 > pEnd) {
248
- start = (Math.floor(pEnd / biggest) - 1) * biggest;
249
- while (start < pStart) {
250
- biggest /= 2;
251
- start = (Math.floor(pEnd / biggest) - 1) * biggest;
252
- }
253
- end = start + biggest - 1;
254
- } else {
255
- start = Math.floor(pEnd / biggest) * biggest;
256
- end = start + biggest - 1;
257
- }
258
- }
259
- if (start !== pStart) subparts4(pStart, start - 1, output);
260
- output.push({
261
- start,
262
- end
263
- });
264
- if (end !== pEnd) subparts4(end + 1, pEnd, output);
265
220
  }
266
221
  function subparts6(pStart, pEnd, output) {
267
- if (pEnd < pStart) return;
268
- if (pEnd === pStart) {
269
- output.push({
270
- start: pStart,
271
- end: pEnd
272
- });
273
- return;
274
- }
275
- if (pEnd - pStart === 1n) {
276
- if (pEnd % 2n === 0n) output.push({
277
- start: pStart,
278
- end: pStart
279
- }, {
280
- start: pEnd,
281
- end: pEnd
282
- });
283
- else output.push({
284
- start: pStart,
285
- end: pEnd
286
- });
287
- return;
288
- }
289
- const size = pEnd - pStart + 1n;
290
- if ((size & size - 1n) === 0n && (pStart & size - 1n) === 0n) {
222
+ let start = pStart;
223
+ while (start <= pEnd) {
224
+ const size = pEnd - start + 1n;
225
+ const lowBit = start & -start;
226
+ if ((size & size - 1n) === 0n && (lowBit === 0n || lowBit >= size)) {
227
+ output.push({
228
+ start,
229
+ end: pEnd
230
+ });
231
+ return;
232
+ }
233
+ const blockSize = lowBit !== 0n && lowBit <= size ? lowBit : biggestPowerOfTwo(size);
291
234
  output.push({
292
- start: pStart,
293
- end: pEnd
235
+ start,
236
+ end: start + blockSize - 1n
294
237
  });
295
- return;
296
- }
297
- let biggest = biggestPowerOfTwo(size);
298
- let start;
299
- let end;
300
- if ((pStart & biggest - 1n) === 0n) {
301
- start = pStart;
302
- end = start + biggest - 1n;
303
- } else {
304
- start = pEnd & -biggest;
305
- if (start + biggest - 1n > pEnd) {
306
- start = (pEnd & -biggest) - biggest;
307
- while (start < pStart) {
308
- biggest >>= 1n;
309
- start = (pEnd & -biggest) - biggest;
310
- }
311
- end = start + biggest - 1n;
312
- } else {
313
- start = pEnd & -biggest;
314
- end = start + biggest - 1n;
315
- }
238
+ start += blockSize;
316
239
  }
317
- if (start !== pStart) subparts6(pStart, start - 1n, output);
318
- output.push({
319
- start,
320
- end
321
- });
322
- if (end !== pEnd) subparts6(end + 1n, pEnd, output);
323
240
  }
324
241
  function formatPart4(part) {
325
242
  return formatIPv4Fast(part.start) + prefixStrings[Math.clz32(part.end - part.start)];
@@ -486,6 +403,7 @@ function excludeCidr(base, excl) {
486
403
  }
487
404
  return result;
488
405
  }
406
+ /** Returns a generator for individual IPs contained in the networks. */
489
407
  function* expandCidr(nets) {
490
408
  const arr = Array.isArray(nets) ? nets : [nets];
491
409
  const v4 = [];
@@ -498,13 +416,13 @@ function* expandCidr(nets) {
498
416
  if (v4.length > 0) for (const part of mergeIntervalsRaw4(v4)) {
499
417
  let prevHigh = -1;
500
418
  let prefix = "";
501
- for (let n = part.start; n <= part.end; n++) {
502
- const high = n >>> 8;
419
+ for (let num = part.start; num <= part.end; num++) {
420
+ const high = num >>> 8;
503
421
  if (high !== prevHigh) {
504
- prefix = octetDotStrings[n >>> 24 & 255] + octetDotStrings[n >>> 16 & 255] + octetDotStrings[n >>> 8 & 255];
422
+ prefix = octetDotStrings[num >>> 24 & 255] + octetDotStrings[num >>> 16 & 255] + octetDotStrings[num >>> 8 & 255];
505
423
  prevHigh = high;
506
424
  }
507
- yield prefix + octetStrings[n & 255];
425
+ yield prefix + octetStrings[num & 255];
508
426
  }
509
427
  }
510
428
  if (v6.length > 0) {
@@ -524,6 +442,9 @@ function overlapCidr(a, b) {
524
442
  if (parseIPv4Range(a)) {
525
443
  const startA = rangeV4Start, endA = rangeV4End;
526
444
  if (parseIPv4Range(b)) return startA <= rangeV4End && rangeV4Start <= endA;
445
+ const pb = parseCidrLean(b);
446
+ if (pb.version !== 4) return false;
447
+ return startA <= pb.end && pb.start <= endA;
527
448
  }
528
449
  const pa = parseCidrLean(a);
529
450
  const pb = parseCidrLean(b);
@@ -584,6 +505,9 @@ function containsCidr(a, b) {
584
505
  if (parseIPv4Range(a)) {
585
506
  const startA = rangeV4Start, endA = rangeV4End;
586
507
  if (parseIPv4Range(b)) return startA <= rangeV4Start && endA >= rangeV4End;
508
+ const pb = parseCidrLean(b);
509
+ if (pb.version !== 4) return false;
510
+ return startA <= pb.start && endA >= pb.end;
587
511
  }
588
512
  const pa = parseCidrLean(a);
589
513
  const pb = parseCidrLean(b);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cidr-tools",
3
- "version": "12.0.0",
3
+ "version": "12.0.2",
4
4
  "author": "silverwind <me@silverwind.io>",
5
5
  "description": "Tools to work with IPv4 and IPv6 CIDR",
6
6
  "keywords": [
@@ -26,23 +26,23 @@
26
26
  "bun": "*"
27
27
  },
28
28
  "dependencies": {
29
- "ip-bigint": "^9.0.0"
29
+ "ip-bigint": "^9.0.5"
30
30
  },
31
31
  "devDependencies": {
32
- "@types/node": "25.6.0",
33
- "@typescript/native-preview": "7.0.0-dev.20260505.1",
34
- "@vitest/coverage-v8": "4.1.5",
35
- "eslint": "10.3.0",
36
- "eslint-config-silverwind": "133.0.0",
32
+ "@types/node": "25.9.1",
33
+ "@typescript/native-preview": "7.0.0-dev.20260527.2",
34
+ "@vitest/coverage-v8": "4.1.7",
35
+ "eslint": "10.4.0",
36
+ "eslint-config-silverwind": "133.0.5",
37
37
  "jest-extended": "7.0.0",
38
- "tsdown": "0.21.10",
39
- "tsdown-config-silverwind": "3.0.0",
38
+ "tsdown": "0.22.1",
39
+ "tsdown-config-silverwind": "3.0.2",
40
40
  "typescript": "6.0.3",
41
41
  "typescript-config-silverwind": "18.0.0",
42
- "updates": "17.16.9",
43
- "updates-config-silverwind": "3.0.0",
44
- "versions": "15.0.3",
45
- "vitest": "4.1.5",
46
- "vitest-config-silverwind": "11.3.3"
42
+ "updates": "17.17.3",
43
+ "updates-config-silverwind": "3.0.2",
44
+ "versions": "15.1.0",
45
+ "vitest": "4.1.7",
46
+ "vitest-config-silverwind": "11.3.5"
47
47
  }
48
48
  }