ip-utilities 1.0.0

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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -0
  3. package/dist/cidr.d.ts +2 -0
  4. package/dist/cidr.d.ts.map +1 -0
  5. package/dist/cidr.js +1 -0
  6. package/dist/index.d.ts +54 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +89 -0
  9. package/dist/internal/cidr.d.ts +112 -0
  10. package/dist/internal/cidr.d.ts.map +1 -0
  11. package/dist/internal/cidr.js +297 -0
  12. package/dist/internal/ipv4-ranges.d.ts +26 -0
  13. package/dist/internal/ipv4-ranges.d.ts.map +1 -0
  14. package/dist/internal/ipv4-ranges.js +73 -0
  15. package/dist/internal/ipv4.d.ts +44 -0
  16. package/dist/internal/ipv4.d.ts.map +1 -0
  17. package/dist/internal/ipv4.js +183 -0
  18. package/dist/internal/ipv6-ranges.d.ts +47 -0
  19. package/dist/internal/ipv6-ranges.d.ts.map +1 -0
  20. package/dist/internal/ipv6-ranges.js +159 -0
  21. package/dist/internal/ipv6.d.ts +67 -0
  22. package/dist/internal/ipv6.d.ts.map +1 -0
  23. package/dist/internal/ipv6.js +385 -0
  24. package/dist/internal/regex.d.ts +37 -0
  25. package/dist/internal/regex.d.ts.map +1 -0
  26. package/dist/internal/regex.js +118 -0
  27. package/dist/internal/sort.d.ts +22 -0
  28. package/dist/internal/sort.d.ts.map +1 -0
  29. package/dist/internal/sort.js +207 -0
  30. package/dist/ipv4.d.ts +2 -0
  31. package/dist/ipv4.d.ts.map +1 -0
  32. package/dist/ipv4.js +1 -0
  33. package/dist/ipv6.d.ts +2 -0
  34. package/dist/ipv6.d.ts.map +1 -0
  35. package/dist/ipv6.js +1 -0
  36. package/dist/ranges.d.ts +3 -0
  37. package/dist/ranges.d.ts.map +1 -0
  38. package/dist/ranges.js +2 -0
  39. package/dist/regex.d.ts +3 -0
  40. package/dist/regex.d.ts.map +1 -0
  41. package/dist/regex.js +1 -0
  42. package/dist/sort.d.ts +2 -0
  43. package/dist/sort.d.ts.map +1 -0
  44. package/dist/sort.js +1 -0
  45. package/dist/types.d.ts +26 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +1 -0
  48. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dr. Skill Issue
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # ip-utilities
2
+
3
+ IP address parsing, validation, and CIDR operations for TypeScript.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bun add ip-utilities
9
+ # or
10
+ npm install ip-utilities
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```ts
16
+ import {
17
+ parseIP, isIP, isIPOrCIDR,
18
+ isPrivateIP, isPublicIPOrCIDR,
19
+ parseCIDR, isIPInCIDR,
20
+ sortIPs,
21
+ } from 'ip-utilities'
22
+
23
+ isIP('192.168.1.1') // true
24
+ isIP('::1') // true
25
+ isIPOrCIDR('10.0.0.0/8') // true
26
+ isPrivateIP('192.168.1.1') // true
27
+ isPublicIPOrCIDR('8.8.8.8') // true
28
+ isIPInCIDR('10.0.0.5', '10.0.0.0/8') // true
29
+
30
+ const addr = parseIP('192.168.1.1')
31
+ // { ip: 3232235777, kind: 4 }
32
+
33
+ const cidr = parseCIDR('::1/128')
34
+ // { addr: { w0: 0, w1: 0, w2: 0, w3: 1, kind: 6 }, prefix: 128, kind: 6 }
35
+
36
+ sortIPs(['::1', '192.168.1.1', '10.0.0.1', '2001:db8::1'])
37
+ // ['10.0.0.1', '192.168.1.1', '::1', '2001:db8::1']
38
+ ```
39
+
40
+ ## Sub-path Imports
41
+
42
+ Each module is available as a separate entry point for tree-shaking:
43
+
44
+ ```ts
45
+ import { parseIPv4, isIPv4 } from 'ip-utilities/ipv4'
46
+ import { parseIPv6, ipv6ToString } from 'ip-utilities/ipv6'
47
+ import { parseCIDR, ipInCIDR } from 'ip-utilities/cidr'
48
+ import { ipv4Range, isPrivateIPv6 } from 'ip-utilities/ranges'
49
+ import { sortIPs, compareIPs } from 'ip-utilities/sort'
50
+ import ipRegex, { testV4 } from 'ip-utilities/regex'
51
+ ```
52
+
53
+ ## API
54
+
55
+ ### Validation
56
+
57
+ | Function | Description |
58
+ |---|---|
59
+ | `isIP(s)` | Checks if a string is a valid IPv4 or IPv6 address |
60
+ | `isIPv4(s)` | Checks if a string is a valid IPv4 address |
61
+ | `isIPv6(s)` | Checks if a string is a valid IPv6 address |
62
+ | `isCIDR(s)` | Checks if a string is valid CIDR notation |
63
+ | `isIPOrCIDR(s)` | Checks if a string is a valid IP address or CIDR |
64
+ | `isPrivateIP(s)` | Checks if a string is a valid IP in a private range |
65
+ | `isPrivateIPOrCIDR(s)` | Checks if a valid IP/CIDR is in a private range |
66
+ | `isPublicIPOrCIDR(s)` | Checks if a valid IP/CIDR is globally routable |
67
+ | `detectIPType(s)` | Returns `4`, `6`, or `null` |
68
+
69
+ ### Parsing
70
+
71
+ | Function | Returns | Description |
72
+ |---|---|---|
73
+ | `parseIP(s)` | `IPAddr \| null` | Auto-detects and parses IPv4 or IPv6 |
74
+ | `parseIPv4(s)` | `IPv4Addr \| null` | Parses strict dotted-decimal IPv4 |
75
+ | `parseIPv4Loose(s)` | `IPv4Addr \| null` | Parses IPv4 with hex, octal, and classful shorthand |
76
+ | `parseIPv6(s)` | `IPv6Addr \| null` | Parses IPv6 with `::`, embedded IPv4, and zone IDs |
77
+ | `parseCIDR(s)` | `CIDR \| null` | Auto-detects and parses IPv4 or IPv6 CIDR |
78
+ | `parseCIDRv4(s)` | `CIDRv4 \| null` | Parses IPv4 CIDR notation |
79
+ | `parseCIDRv6(s)` | `CIDRv6 \| null` | Parses IPv6 CIDR notation |
80
+
81
+ ### String Conversion
82
+
83
+ | Function | Returns | Description |
84
+ |---|---|---|
85
+ | `ipv4ToString(ip)` | `string` | Packed uint32 to dotted-decimal (e.g. `"192.168.1.1"`) |
86
+ | `ipv4ToOctets(ip)` | `[n, n, n, n]` | Packed uint32 to four octets |
87
+ | `ipv6ToString(addr)` | `string` | Compressed RFC 5952 notation (e.g. `"::1"`) |
88
+ | `ipv6ToNormalizedString(addr)` | `string` | Uncompressed without padding (e.g. `"0:0:0:0:0:0:0:1"`) |
89
+ | `ipv6ToFixedString(addr)` | `string` | Zero-padded groups (e.g. `"0000:0000:...:0001"`) |
90
+
91
+ ### Range Classification
92
+
93
+ | Function | Returns | Description |
94
+ |---|---|---|
95
+ | `ipv4Range(ip)` | `IPv4RangeName` | Classifies into IANA range (e.g. `"private"`, `"unicast"`) |
96
+ | `ipv6Range(addr)` | `IPv6RangeName` | Classifies into IANA range (e.g. `"uniqueLocal"`, `"unicast"`) |
97
+ | `isPrivateIPv4(ip)` | `boolean` | Checks RFC 1918 ranges (10/8, 172.16/12, 192.168/16) |
98
+ | `isPrivateIPv6(addr)` | `boolean` | Checks unique-local, multicast, link-local, loopback |
99
+ | `isLoopbackIPv4(ip)` | `boolean` | Checks 127.0.0.0/8 |
100
+ | `isLoopbackIPv6(addr)` | `boolean` | Checks ::1 |
101
+ | `isLinkLocalIPv4(ip)` | `boolean` | Checks 169.254.0.0/16 |
102
+ | `isLinkLocalIPv6(addr)` | `boolean` | Checks fe80::/10 |
103
+
104
+ ### CIDR Operations
105
+
106
+ | Function | Returns | Description |
107
+ |---|---|---|
108
+ | `ipInCIDR(ip, cidr)` | `boolean` | Checks if a parsed IP is within a parsed CIDR range |
109
+ | `ipInCIDRv4(ip, cidr)` | `boolean` | IPv4-specific CIDR containment check |
110
+ | `ipInCIDRv6(ip, cidr)` | `boolean` | IPv6-specific CIDR containment check |
111
+ | `isIPInCIDR(ipStr, cidrStr)` | `boolean` | Parses both strings and checks containment |
112
+ | `networkAddressV4(cidr)` | `IPv4Addr` | First address in an IPv4 CIDR range |
113
+ | `broadcastAddressV4(cidr)` | `IPv4Addr` | Last address in an IPv4 CIDR range |
114
+ | `networkAddressV6(cidr)` | `IPv6Addr` | First address in an IPv6 CIDR range |
115
+ | `broadcastAddressV6(cidr)` | `IPv6Addr` | Last address in an IPv6 CIDR range |
116
+ | `subnetMaskV4(prefix)` | `number` | Subnet mask for a prefix length (0-32) |
117
+ | `prefixFromSubnetMask(mask)` | `number \| null` | Prefix length from a contiguous subnet mask |
118
+
119
+ ### IPv6 Utilities
120
+
121
+ | Function | Returns | Description |
122
+ |---|---|---|
123
+ | `isIPv4Mapped(addr)` | `boolean` | Checks if address is IPv4-mapped (::ffff:0:0/96) |
124
+ | `ipv6ToIPv4(addr)` | `number` | Extracts the embedded IPv4 uint32 from lower 32 bits |
125
+ | `ipv6ToWords(addr)` | `[x8 number]` | Expands to eight 16-bit groups |
126
+ | `ipv6GetZoneId(addr)` | `string` | Retrieves the zone ID (e.g. `"eth0"`) or empty string |
127
+
128
+ ### Sorting
129
+
130
+ | Function | Returns | Description |
131
+ |---|---|---|
132
+ | `sortIPs(ips)` | `string[]` | Sorts IP/CIDR strings in network order (new array) |
133
+ | `compareIPs(a, b)` | `number` | Comparator for two IP/CIDR strings (cached) |
134
+ | `clearSortCache()` | `void` | Clears the internal comparison cache |
135
+
136
+ Sort order: IPv4 before IPv6, numeric within each version, invalid strings last (lexicographic among themselves), CIDR entries with the same network sort by prefix length.
137
+
138
+ ### Regex
139
+
140
+ ```ts
141
+ import ipRegex, { testV4, testV6, testV46 } from 'ip-utilities/regex'
142
+ ```
143
+
144
+ | Export | Description |
145
+ |---|---|
146
+ | `testV4(s)` | Fast exact IPv4 string test |
147
+ | `testV6(s)` | Fast exact IPv6 string test |
148
+ | `testV46(s)` | Fast exact IPv4-or-IPv6 string test |
149
+ | `ipRegex(options?)` | Returns a RegExp matching IPv4 and IPv6 |
150
+ | `ipRegex.v4(options?)` | Returns a RegExp matching IPv4 only |
151
+ | `ipRegex.v6(options?)` | Returns a RegExp matching IPv6 only |
152
+ | `ipRegex.scanAll(input, options?)` | Extracts all IP addresses from a string |
153
+ | `ipRegex.scanAllV4(input, options?)` | Extracts all IPv4 addresses from a string |
154
+ | `ipRegex.scanAllV6(input, options?)` | Extracts all IPv6 addresses from a string |
155
+
156
+ **Options:**
157
+
158
+ - `exact` -- Match the entire string only (anchored)
159
+ - `includeBoundaries` -- Require whitespace or string boundaries around matches
160
+
161
+ **ScanResult:**
162
+
163
+ ```ts
164
+ { value: string, index: number }
165
+ ```
166
+
167
+ ## Types
168
+
169
+ ```ts
170
+ interface IPv4Addr {
171
+ readonly ip: number // Packed uint32
172
+ readonly kind: 4
173
+ }
174
+
175
+ interface IPv6Addr {
176
+ readonly w0: number // Bits 0-31
177
+ readonly w1: number // Bits 32-63
178
+ readonly w2: number // Bits 64-95
179
+ readonly w3: number // Bits 96-127
180
+ readonly kind: 6
181
+ }
182
+
183
+ type IPAddr = IPv4Addr | IPv6Addr
184
+
185
+ interface CIDRv4 {
186
+ readonly addr: IPv4Addr
187
+ readonly prefix: number
188
+ readonly kind: 4
189
+ }
190
+
191
+ interface CIDRv6 {
192
+ readonly addr: IPv6Addr
193
+ readonly prefix: number
194
+ readonly kind: 6
195
+ }
196
+
197
+ type CIDR = CIDRv4 | CIDRv6
198
+ ```
199
+
200
+ All types use a `kind` discriminant for narrowing:
201
+
202
+ ```ts
203
+ const addr = parseIP(input)
204
+ if (addr?.kind === 4) {
205
+ // addr is IPv4Addr
206
+ console.log(ipv4ToString(addr.ip))
207
+ } else if (addr?.kind === 6) {
208
+ // addr is IPv6Addr
209
+ console.log(ipv6ToString(addr))
210
+ }
211
+ ```
212
+
213
+ ## Benchmarks
214
+
215
+ Compared to ipaddr.js (v2.3.0) on AMD Ryzen 9 7950X, Bun 1.3:
216
+
217
+ | Operation | ip-utilities | ipaddr.js | Speedup |
218
+ |---|---|---|---|
219
+ | IPv4 parse (10 addrs) | 180 ns | 1,910 ns | **10.6x** |
220
+ | IPv6 parse (10 addrs) | 310 ns | 5,140 ns | **16.6x** |
221
+ | isValid (20 mixed) | 533 ns | 8,310 ns | **15.6x** |
222
+ | parse (20 mixed) | 593 ns | 15,960 ns | **26.9x** |
223
+ | CIDR match (strings) | 53 ns | 2,140 ns | **40.8x** |
224
+ | parseCIDR IPv4 | 26 ns | 1,930 ns | **74.4x** |
225
+ | parseCIDR IPv6 | 33 ns | 896 ns | **27.2x** |
226
+ | invalid IPv4 | 33 ns | 4,950 ns | **151.7x** |
227
+ | invalid IPv6 | 52 ns | 5,280 ns | **101.8x** |
228
+
229
+ Run benchmarks locally:
230
+
231
+ ```bash
232
+ bun run test/bench/ip.bench.ts
233
+ bun run test/bench/memory.bench.ts
234
+ ```
235
+
236
+ ## License
237
+
238
+ MIT
package/dist/cidr.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { parseCIDR, parseCIDRv4, parseCIDRv6, isCIDR, isIPInCIDR, ipInCIDR, ipInCIDRv4, ipInCIDRv6, networkAddressV4, broadcastAddressV4, networkAddressV6, broadcastAddressV6, subnetMaskV4, prefixFromSubnetMask } from './internal/cidr.ts';
2
+ //# sourceMappingURL=cidr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cidr.d.ts","sourceRoot":"","sources":["../src/cidr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/cidr.js ADDED
@@ -0,0 +1 @@
1
+ export { parseCIDR, parseCIDRv4, parseCIDRv6, isCIDR, isIPInCIDR, ipInCIDR, ipInCIDRv4, ipInCIDRv6, networkAddressV4, broadcastAddressV4, networkAddressV6, broadcastAddressV6, subnetMaskV4, prefixFromSubnetMask } from "./internal/cidr.js";
@@ -0,0 +1,54 @@
1
+ import type { IPAddr } from './types.ts';
2
+ export { parseIPv4, isIPv4, parseIPv4Loose, ipv4ToOctets, ipv4ToString } from './ipv4.ts';
3
+ export { parseIPv6, isIPv6, isIPv4Mapped, ipv6ToWords, ipv6ToString, ipv6ToNormalizedString, ipv6ToFixedString, ipv6ToIPv4, ipv6GetZoneId } from './ipv6.ts';
4
+ export { ipv4Range, isPrivateIPv4, isLoopbackIPv4, isLinkLocalIPv4, ipv6Range, isPrivateIPv6, isLoopbackIPv6, isLinkLocalIPv6 } from './ranges.ts';
5
+ export { parseCIDR, parseCIDRv4, parseCIDRv6, isCIDR, isIPInCIDR, ipInCIDR, ipInCIDRv4, ipInCIDRv6, networkAddressV4, broadcastAddressV4, networkAddressV6, broadcastAddressV6, subnetMaskV4, prefixFromSubnetMask } from './cidr.ts';
6
+ export { compareIPs, sortIPs, clearSortCache } from './sort.ts';
7
+ export { default as ipRegex, testV4, testV6, testV46 } from './regex.ts';
8
+ export type { Options as RegexOptions, ScanResult, IpRegex } from './regex.ts';
9
+ export type { IPv4Addr, IPv6Addr, IPAddr, CIDRv4, CIDRv6, CIDR, IPv4RangeName, IPv6RangeName } from './types.ts';
10
+ /**
11
+ * Parses an IP address string, auto-detecting IPv4 or IPv6.
12
+ * @param s - The IP address string
13
+ * @returns The parsed address, or null if invalid
14
+ */
15
+ export declare function parseIP(s: string): IPAddr | null;
16
+ /**
17
+ * Checks whether a string is a valid IPv4 or IPv6 address.
18
+ * @param s - The string to validate
19
+ * @returns True if the string is a valid IP address
20
+ */
21
+ export declare function isIP(s: string): boolean;
22
+ /**
23
+ * Detects the IP version of a string.
24
+ * @param s - The string to check
25
+ * @returns 4 for IPv4, 6 for IPv6, or null if invalid
26
+ */
27
+ export declare function detectIPType(s: string): 4 | 6 | null;
28
+ /**
29
+ * Checks whether a string is a valid IP address or CIDR notation.
30
+ * @param s - The string to validate
31
+ * @returns True if the string is a valid IP or CIDR
32
+ */
33
+ export declare function isIPOrCIDR(s: string): boolean;
34
+ /**
35
+ * Checks whether a string is a valid IP address in a private range.
36
+ * @param s - The IP address string
37
+ * @returns True if the address is valid and private
38
+ */
39
+ export declare function isPrivateIP(s: string): boolean;
40
+ /**
41
+ * Checks whether a string is a valid IP or CIDR in a private range.
42
+ * For CIDR input, the address portion is checked.
43
+ * @param s - The IP or CIDR string
44
+ * @returns True if valid and private
45
+ */
46
+ export declare function isPrivateIPOrCIDR(s: string): boolean;
47
+ /**
48
+ * Checks whether a string is a valid IP or CIDR in a globally routable (unicast) range.
49
+ * For CIDR input, the address portion is checked.
50
+ * @param s - The IP or CIDR string
51
+ * @returns True if valid and publicly routable
52
+ */
53
+ export declare function isPublicIPOrCIDR(s: string): boolean;
54
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC5J,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClJ,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACrO,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACxE,YAAY,EAAE,OAAO,IAAI,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAC9E,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAEhH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAIpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAO9C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAKpD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAKnD"}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ import { parseIPv4Raw, isIPv4 } from "./internal/ipv4.js";
2
+ import { parseIPv6, isIPv6 } from "./internal/ipv6.js";
3
+ import { parseIPOrCIDR, parseIPOrCIDRv4, v6AddrFromBuf } from "./internal/cidr.js";
4
+ import { ipv4Range, isPrivateIPv4 } from "./internal/ipv4-ranges.js";
5
+ import { ipv6Range, isPrivateIPv6 } from "./internal/ipv6-ranges.js";
6
+ export { parseIPv4, isIPv4, parseIPv4Loose, ipv4ToOctets, ipv4ToString } from "./ipv4.js";
7
+ export { parseIPv6, isIPv6, isIPv4Mapped, ipv6ToWords, ipv6ToString, ipv6ToNormalizedString, ipv6ToFixedString, ipv6ToIPv4, ipv6GetZoneId } from "./ipv6.js";
8
+ export { ipv4Range, isPrivateIPv4, isLoopbackIPv4, isLinkLocalIPv4, ipv6Range, isPrivateIPv6, isLoopbackIPv6, isLinkLocalIPv6 } from "./ranges.js";
9
+ export { parseCIDR, parseCIDRv4, parseCIDRv6, isCIDR, isIPInCIDR, ipInCIDR, ipInCIDRv4, ipInCIDRv6, networkAddressV4, broadcastAddressV4, networkAddressV6, broadcastAddressV6, subnetMaskV4, prefixFromSubnetMask } from "./cidr.js";
10
+ export { compareIPs, sortIPs, clearSortCache } from "./sort.js";
11
+ export { default as ipRegex, testV4, testV6, testV46 } from "./regex.js";
12
+ /**
13
+ * Parses an IP address string, auto-detecting IPv4 or IPv6.
14
+ * @param s - The IP address string
15
+ * @returns The parsed address, or null if invalid
16
+ */
17
+ export function parseIP(s) {
18
+ if (s.indexOf(':') !== -1)
19
+ return parseIPv6(s);
20
+ const ip = parseIPv4Raw(s, 0, s.length);
21
+ return ip !== -1 ? { ip, kind: 4 } : null;
22
+ }
23
+ /**
24
+ * Checks whether a string is a valid IPv4 or IPv6 address.
25
+ * @param s - The string to validate
26
+ * @returns True if the string is a valid IP address
27
+ */
28
+ export function isIP(s) {
29
+ return s.indexOf(':') === -1 ? isIPv4(s) : isIPv6(s);
30
+ }
31
+ /**
32
+ * Detects the IP version of a string.
33
+ * @param s - The string to check
34
+ * @returns 4 for IPv4, 6 for IPv6, or null if invalid
35
+ */
36
+ export function detectIPType(s) {
37
+ return s.indexOf(':') === -1
38
+ ? (isIPv4(s) ? 4 : null)
39
+ : (isIPv6(s) ? 6 : null);
40
+ }
41
+ /**
42
+ * Checks whether a string is a valid IP address or CIDR notation.
43
+ * @param s - The string to validate
44
+ * @returns True if the string is a valid IP or CIDR
45
+ */
46
+ export function isIPOrCIDR(s) {
47
+ return parseIPOrCIDR(s) !== 0;
48
+ }
49
+ /**
50
+ * Checks whether a string is a valid IP address in a private range.
51
+ * @param s - The IP address string
52
+ * @returns True if the address is valid and private
53
+ */
54
+ export function isPrivateIP(s) {
55
+ if (s.indexOf(':') === -1) {
56
+ const ip = parseIPv4Raw(s, 0, s.length);
57
+ return ip !== -1 && isPrivateIPv4(ip);
58
+ }
59
+ const v6 = parseIPv6(s);
60
+ return v6 !== null && isPrivateIPv6(v6);
61
+ }
62
+ /**
63
+ * Checks whether a string is a valid IP or CIDR in a private range.
64
+ * For CIDR input, the address portion is checked.
65
+ * @param s - The IP or CIDR string
66
+ * @returns True if valid and private
67
+ */
68
+ export function isPrivateIPOrCIDR(s) {
69
+ const kind = parseIPOrCIDR(s);
70
+ if (kind === 4)
71
+ return isPrivateIPv4(parseIPOrCIDRv4);
72
+ if (kind === 6)
73
+ return isPrivateIPv6(v6AddrFromBuf());
74
+ return false;
75
+ }
76
+ /**
77
+ * Checks whether a string is a valid IP or CIDR in a globally routable (unicast) range.
78
+ * For CIDR input, the address portion is checked.
79
+ * @param s - The IP or CIDR string
80
+ * @returns True if valid and publicly routable
81
+ */
82
+ export function isPublicIPOrCIDR(s) {
83
+ const kind = parseIPOrCIDR(s);
84
+ if (kind === 4)
85
+ return ipv4Range(parseIPOrCIDRv4) === 'unicast';
86
+ if (kind === 6)
87
+ return ipv6Range(v6AddrFromBuf()) === 'unicast';
88
+ return false;
89
+ }
@@ -0,0 +1,112 @@
1
+ import type { IPv4Addr, IPv6Addr, IPAddr, CIDRv4, CIDRv6, CIDR } from '../types.ts';
2
+ export declare let parseIPOrCIDRv4: number;
3
+ /**
4
+ * Parses a decimal prefix length from a substring.
5
+ * @param s - Source string
6
+ * @param start - Start index of the prefix digits
7
+ * @param end - End index (exclusive)
8
+ * @param max - Maximum allowed prefix value
9
+ * @returns The prefix length, or -1 if invalid
10
+ */
11
+ export declare function parsePrefixInline(s: string, start: number, end: number, max: number): number;
12
+ /**
13
+ * Parses a CIDR string in IPv4 notation (e.g. "192.168.1.0/24").
14
+ * @param s - The CIDR string
15
+ * @returns The parsed CIDRv4, or null if invalid
16
+ */
17
+ export declare function parseCIDRv4(s: string): CIDRv4 | null;
18
+ /**
19
+ * Parses a CIDR string in IPv6 notation (e.g. "::1/128").
20
+ * @param s - The CIDR string
21
+ * @returns The parsed CIDRv6, or null if invalid
22
+ */
23
+ export declare function parseCIDRv6(s: string): CIDRv6 | null;
24
+ /**
25
+ * Parses a CIDR string, auto-detecting IPv4 or IPv6.
26
+ * @param s - The CIDR string
27
+ * @returns The parsed CIDR, or null if invalid
28
+ */
29
+ export declare function parseCIDR(s: string): CIDR | null;
30
+ /**
31
+ * Checks whether a string is valid CIDR notation (IPv4 or IPv6).
32
+ * @param s - The string to validate
33
+ * @returns True if the string is valid CIDR
34
+ */
35
+ export declare function isCIDR(s: string): boolean;
36
+ /**
37
+ * Checks whether an IPv4 address is within a CIDRv4 range.
38
+ * @param ip - The IPv4 address
39
+ * @param cidr - The CIDRv4 range
40
+ * @returns True if the address is within the range
41
+ */
42
+ export declare function ipInCIDRv4(ip: IPv4Addr, cidr: CIDRv4): boolean;
43
+ /**
44
+ * Checks whether an IPv6 address is within a CIDRv6 range.
45
+ * @param ip - The IPv6 address
46
+ * @param cidr - The CIDRv6 range
47
+ * @returns True if the address is within the range
48
+ */
49
+ export declare function ipInCIDRv6(ip: IPv6Addr, cidr: CIDRv6): boolean;
50
+ /**
51
+ * Checks whether an IP address is within a CIDR range. Both must be the same version.
52
+ * @param ip - The IP address (IPv4 or IPv6)
53
+ * @param cidr - The CIDR range (IPv4 or IPv6)
54
+ * @returns True if the address is within the range, false if mismatched versions
55
+ */
56
+ export declare function ipInCIDR(ip: IPAddr, cidr: CIDR): boolean;
57
+ /**
58
+ * Parses an IP string and CIDR string, then checks containment.
59
+ * @param ipStr - The IP address string
60
+ * @param cidrStr - The CIDR range string
61
+ * @returns True if the IP is within the CIDR range
62
+ */
63
+ export declare function isIPInCIDR(ipStr: string, cidrStr: string): boolean;
64
+ /**
65
+ * Computes the network address (first address) of an IPv4 CIDR range.
66
+ * @param cidr - The CIDRv4 range
67
+ * @returns The network address
68
+ */
69
+ export declare function networkAddressV4(cidr: CIDRv4): IPv4Addr;
70
+ /**
71
+ * Computes the broadcast address (last address) of an IPv4 CIDR range.
72
+ * @param cidr - The CIDRv4 range
73
+ * @returns The broadcast address
74
+ */
75
+ export declare function broadcastAddressV4(cidr: CIDRv4): IPv4Addr;
76
+ /**
77
+ * Computes the network address (first address) of an IPv6 CIDR range.
78
+ * @param cidr - The CIDRv6 range
79
+ * @returns The network address
80
+ */
81
+ export declare function networkAddressV6(cidr: CIDRv6): IPv6Addr;
82
+ /**
83
+ * Computes the broadcast address (last address) of an IPv6 CIDR range.
84
+ * @param cidr - The CIDRv6 range
85
+ * @returns The broadcast address
86
+ */
87
+ export declare function broadcastAddressV6(cidr: CIDRv6): IPv6Addr;
88
+ /**
89
+ * Returns the subnet mask for an IPv4 prefix length.
90
+ * @param prefix - Prefix length (0-32)
91
+ * @returns The uint32 subnet mask
92
+ */
93
+ export declare function subnetMaskV4(prefix: number): number;
94
+ /**
95
+ * Converts a subnet mask to its prefix length.
96
+ * @param mask - The uint32 subnet mask (must be contiguous)
97
+ * @returns The prefix length, or null if the mask is not contiguous
98
+ */
99
+ export declare function prefixFromSubnetMask(mask: number): number | null;
100
+ /**
101
+ * Parses an IP or CIDR string, routing v4/v6 in a single forward scan.
102
+ * On success, the v4 result is in {@link parseIPOrCIDRv4} and v6 result in ipv6RawBuf.
103
+ * @param s - The IP or CIDR string
104
+ * @returns 4 for valid IPv4, 6 for valid IPv6, 0 for invalid
105
+ */
106
+ export declare function parseIPOrCIDR(s: string): number;
107
+ /**
108
+ * Constructs an IPv6Addr from the shared ipv6RawBuf after a successful parseIPv6Raw call.
109
+ * @returns The IPv6Addr built from the raw buffer
110
+ */
111
+ export declare function v6AddrFromBuf(): IPv6Addr;
112
+ //# sourceMappingURL=cidr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cidr.d.ts","sourceRoot":"","sources":["../../src/internal/cidr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAiBnF,eAAO,IAAI,eAAe,QAAI,CAAA;AAI9B;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAW5F;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQpD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAYhD;AAID;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAczC;AAID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAIxD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAWlE;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAUvD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAUzD;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhE;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB/C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,QAAQ,CAExC"}