node-ip-ts 1.0.0 → 1.2.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/README.md CHANGED
@@ -1,12 +1,31 @@
1
1
  <div align="center">
2
2
 
3
+ <br />
4
+
5
+ ```
6
+ ___ ____ _____ ____
7
+ |_ _| _ \ |_ _/ ___|
8
+ | || |_) |_____| | \___ \
9
+ | || __/_____| | ___) |
10
+ |___|_| |_| |____/
11
+ ```
12
+
3
13
  ### A modern, type-safe IP address utility library for Node.js
4
14
 
15
+ [![npm version](https://img.shields.io/npm/v/node-ip-ts?color=0ea5e9&style=flat-square)](https://www.npmjs.com/package/node-ip-ts)
16
+ [![license](https://img.shields.io/npm/l/node-ip-ts?color=0ea5e9&style=flat-square)](./LICENSE)
17
+ [![types](https://img.shields.io/npm/types/node-ip-ts?style=flat-square)](https://www.npmjs.com/package/node-ip-ts)
18
+ [![zero deps](https://img.shields.io/badge/dependencies-0-brightgreen?style=flat-square)](./package.json)
19
+
20
+ <br />
21
+
5
22
  **node-ip-ts** is a full TypeScript rewrite of the popular [`ip`](https://www.npmjs.com/package/ip) package —
6
23
  rebuilt from the ground up with strict types, ES Modules, and zero external dependencies.
7
24
 
8
25
  [Installation](#installation) · [Quick Start](#quick-start) · [API Reference](#api-reference) · [Contributing](#contributing)
9
26
 
27
+ <br />
28
+
10
29
  </div>
11
30
 
12
31
  ---
@@ -15,15 +34,29 @@ rebuilt from the ground up with strict types, ES Modules, and zero external depe
15
34
 
16
35
  The original `ip` package has millions of weekly downloads but ships no TypeScript types and only supports CommonJS. **node-ip-ts** solves that:
17
36
 
18
- | | `ip` | `node-ip-ts` |
19
- | --------------------- | :--: | :----------: |
20
- | TypeScript support | | |
21
- | ES Module support | | |
22
- | CommonJS support | | |
23
- | Type declarations | | |
24
- | Strict null checks | | |
25
- | External dependencies | 0 | 0 |
26
- | API compatibility | | ✅ drop-in |
37
+ | | `ip` | `node-ip-ts` |
38
+ |---|:---:|:---:|
39
+ | TypeScript support | | |
40
+ | ES Module support | | |
41
+ | CommonJS support | | |
42
+ | Type declarations | | |
43
+ | Strict null checks | | |
44
+ | External dependencies | 0 | 0 |
45
+ | API compatibility | | ✅ drop-in |
46
+
47
+ ---
48
+
49
+ ## Browser Compatibility
50
+
51
+ All functions **except `address()`** work in both Node.js and browser/bundler environments (Vite, webpack, esbuild, etc.).
52
+
53
+ | Function | Node.js | Browser |
54
+ |---|:---:|:---:|
55
+ | All IP/subnet/bitwise functions | ✅ | ✅ |
56
+ | `loopback()` | ✅ | ✅ |
57
+ | `address()` | ✅ | ❌ (uses `os` module) |
58
+
59
+ If you need an IP in a browser context, obtain it server-side and pass it to the client, or use `loopback()` as a fallback.
27
60
 
28
61
  ---
29
62
 
@@ -31,13 +64,13 @@ The original `ip` package has millions of weekly downloads but ships no TypeScri
31
64
 
32
65
  ```bash
33
66
  # npm
34
- npm install node-node-ip-ts
67
+ npm install node-ip-ts
35
68
 
36
69
  # pnpm
37
- pnpm add node-node-ip-ts
70
+ pnpm add node-ip-ts
38
71
 
39
72
  # yarn
40
- yarn add node-node-ip-ts
73
+ yarn add node-ip-ts
41
74
  ```
42
75
 
43
76
  > **Requirements:** Node.js ≥ 16
@@ -49,41 +82,34 @@ yarn add node-node-ip-ts
49
82
  ### ESM / TypeScript
50
83
 
51
84
  ```ts
52
- import * as ip from "node-node-ip-ts";
53
-
54
- // Address classification
55
- ip.address(); // first private IPv4 address, e.g. '192.168.1.42'
56
- ip.address("public"); // first public IPv4 address
57
- ip.address("private"); // first private IPv4 address
58
- ip.address("eth0"); // first IPv4 address on eth0
59
- ip.address("eth0", 6); // first IPv6 address on eth0
85
+ import * as ip from 'node-ip-ts';
60
86
 
61
87
  // Address classification
62
- ip.isPrivate("192.168.1.1"); // true
63
- ip.isPublic("8.8.8.8"); // true
64
- ip.isLoopback("127.0.0.1"); // true
88
+ ip.isPrivate('192.168.1.1'); // true
89
+ ip.isPublic('8.8.8.8'); // true
90
+ ip.isLoopback('127.0.0.1'); // true
65
91
 
66
92
  // Subnet operations
67
- ip.cidr("192.168.1.134/26"); // '192.168.1.128'
68
- const subnet = ip.cidrSubnet("192.168.1.134/26");
69
- subnet.contains("192.168.1.180"); // true
93
+ ip.cidr('192.168.1.134/26'); // '192.168.1.128'
94
+ const subnet = ip.cidrSubnet('192.168.1.134/26');
95
+ subnet.contains('192.168.1.180'); // true
70
96
 
71
97
  // Conversion
72
- ip.toLong("255.255.255.255"); // 4294967295
73
- ip.fromLong(4294967295); // '255.255.255.255'
98
+ ip.toLong('255.255.255.255'); // 4294967295
99
+ ip.fromLong(4294967295); // '255.255.255.255'
74
100
  ```
75
101
 
76
102
  ### Named imports (tree-shakeable)
77
103
 
78
104
  ```ts
79
- import { isPrivate, cidrSubnet, toLong } from "node-ip-ts";
105
+ import { isPrivate, cidrSubnet, toLong } from 'node-ip-ts';
80
106
  ```
81
107
 
82
108
  ### CommonJS
83
109
 
84
110
  ```js
85
- const ip = require("node-ip-ts");
86
- ip.isPrivate("10.0.0.1"); // true
111
+ const ip = require('node-ip-ts');
112
+ ip.isPrivate('10.0.0.1'); // true
87
113
  ```
88
114
 
89
115
  ---
@@ -95,7 +121,6 @@ ip.isPrivate("10.0.0.1"); // true
95
121
  #### `isPrivate(addr: string): boolean`
96
122
 
97
123
  Returns `true` if the address falls within any private/reserved range:
98
-
99
124
  - `10.0.0.0/8` — RFC 1918
100
125
  - `172.16.0.0/12` — RFC 1918
101
126
  - `192.168.0.0/16` — RFC 1918
@@ -105,11 +130,11 @@ Returns `true` if the address falls within any private/reserved range:
105
130
  - `::1`, `::` — loopback
106
131
 
107
132
  ```ts
108
- ip.isPrivate("192.168.0.1"); // true
109
- ip.isPrivate("10.0.0.1"); // true
110
- ip.isPrivate("fd12:3456:789a:1::1"); // true (IPv6 ULA)
111
- ip.isPrivate("::ffff:192.168.0.1"); // true (IPv4-mapped IPv6)
112
- ip.isPrivate("8.8.8.8"); // false
133
+ ip.isPrivate('192.168.0.1'); // true
134
+ ip.isPrivate('10.0.0.1'); // true
135
+ ip.isPrivate('fd12:3456:789a:1::1'); // true (IPv6 ULA)
136
+ ip.isPrivate('::ffff:192.168.0.1'); // true (IPv4-mapped IPv6)
137
+ ip.isPrivate('8.8.8.8'); // false
113
138
  ```
114
139
 
115
140
  #### `isPublic(addr: string): boolean`
@@ -117,8 +142,8 @@ ip.isPrivate("8.8.8.8"); // false
117
142
  Inverse of `isPrivate`. Returns `true` for publicly routable addresses.
118
143
 
119
144
  ```ts
120
- ip.isPublic("1.1.1.1"); // true
121
- ip.isPublic("10.0.0.1"); // false
145
+ ip.isPublic('1.1.1.1'); // true
146
+ ip.isPublic('10.0.0.1'); // false
122
147
  ```
123
148
 
124
149
  #### `isLoopback(addr: string): boolean`
@@ -126,27 +151,27 @@ ip.isPublic("10.0.0.1"); // false
126
151
  Returns `true` for loopback addresses. Supports dotted-decimal, octal, hexadecimal, and long-integer notation.
127
152
 
128
153
  ```ts
129
- ip.isLoopback("127.0.0.1"); // true
130
- ip.isLoopback("::1"); // true
131
- ip.isLoopback("0x7f.0.0.1"); // true (hex notation)
132
- ip.isLoopback("0177.0.0.1"); // true (octal notation)
133
- ip.isLoopback("2130706433"); // true (integer notation)
134
- ip.isLoopback("8.8.8.8"); // false
154
+ ip.isLoopback('127.0.0.1'); // true
155
+ ip.isLoopback('::1'); // true
156
+ ip.isLoopback('0x7f.0.0.1'); // true (hex notation)
157
+ ip.isLoopback('0177.0.0.1'); // true (octal notation)
158
+ ip.isLoopback('2130706433'); // true (integer notation)
159
+ ip.isLoopback('8.8.8.8'); // false
135
160
  ```
136
161
 
137
162
  #### `isV4Format(ip: string): boolean`
138
163
 
139
164
  ```ts
140
- ip.isV4Format("192.168.0.1"); // true
141
- ip.isV4Format("::1"); // false
165
+ ip.isV4Format('192.168.0.1'); // true
166
+ ip.isV4Format('::1'); // false
142
167
  ```
143
168
 
144
169
  #### `isV6Format(ip: string): boolean`
145
170
 
146
171
  ```ts
147
- ip.isV6Format("::1"); // true
148
- ip.isV6Format("::ffff:192.168.0.1"); // true
149
- ip.isV6Format("192.168.0.1"); // false
172
+ ip.isV6Format('::1'); // true
173
+ ip.isV6Format('::ffff:192.168.0.1'); // true
174
+ ip.isV6Format('192.168.0.1'); // false
150
175
  ```
151
176
 
152
177
  ---
@@ -158,8 +183,8 @@ ip.isV6Format("192.168.0.1"); // false
158
183
  Returns the network address for a given CIDR string.
159
184
 
160
185
  ```ts
161
- ip.cidr("192.168.1.134/26"); // '192.168.1.128'
162
- ip.cidr("2607:f0d0:1002:51::4/56"); // '2607:f0d0:1002::'
186
+ ip.cidr('192.168.1.134/26'); // '192.168.1.128'
187
+ ip.cidr('2607:f0d0:1002:51::4/56'); // '2607:f0d0:1002::'
163
188
  ```
164
189
 
165
190
  #### `cidrSubnet(cidrString: string): SubnetInfo`
@@ -167,18 +192,18 @@ ip.cidr("2607:f0d0:1002:51::4/56"); // '2607:f0d0:1002::'
167
192
  Returns a full `SubnetInfo` object for a given CIDR string.
168
193
 
169
194
  ```ts
170
- const s = ip.cidrSubnet("192.168.1.134/26");
171
-
172
- s.networkAddress; // '192.168.1.128'
173
- s.firstAddress; // '192.168.1.129'
174
- s.lastAddress; // '192.168.1.190'
175
- s.broadcastAddress; // '192.168.1.191'
176
- s.subnetMask; // '255.255.255.192'
177
- s.subnetMaskLength; // 26
178
- s.numHosts; // 62
179
- s.length; // 64
180
- s.contains("192.168.1.150"); // true
181
- s.contains("192.168.1.200"); // false
195
+ const s = ip.cidrSubnet('192.168.1.134/26');
196
+
197
+ s.networkAddress; // '192.168.1.128'
198
+ s.firstAddress; // '192.168.1.129'
199
+ s.lastAddress; // '192.168.1.190'
200
+ s.broadcastAddress; // '192.168.1.191'
201
+ s.subnetMask; // '255.255.255.192'
202
+ s.subnetMaskLength; // 26
203
+ s.numHosts; // 62
204
+ s.length; // 64
205
+ s.contains('192.168.1.150'); // true
206
+ s.contains('192.168.1.200'); // false
182
207
  ```
183
208
 
184
209
  #### `subnet(addr: string, mask: string): SubnetInfo`
@@ -186,7 +211,7 @@ s.contains("192.168.1.200"); // false
186
211
  Same as `cidrSubnet` but takes address and mask separately.
187
212
 
188
213
  ```ts
189
- const s = ip.subnet("192.168.1.134", "255.255.255.192");
214
+ const s = ip.subnet('192.168.1.134', '255.255.255.192');
190
215
  ```
191
216
 
192
217
  #### `mask(addr: string, mask: string): string`
@@ -194,8 +219,8 @@ const s = ip.subnet("192.168.1.134", "255.255.255.192");
194
219
  Applies a subnet mask to an address via bitwise AND.
195
220
 
196
221
  ```ts
197
- ip.mask("192.168.1.134", "255.255.255.0"); // '192.168.1.0'
198
- ip.mask("192.168.1.134", "::ffff:ff00"); // '::ffff:c0a8:100'
222
+ ip.mask('192.168.1.134', '255.255.255.0'); // '192.168.1.0'
223
+ ip.mask('192.168.1.134', '::ffff:ff00'); // '::ffff:c0a8:100'
199
224
  ```
200
225
 
201
226
  #### `fromPrefixLen(prefixlen: number, family?: string | number): string`
@@ -203,9 +228,9 @@ ip.mask("192.168.1.134", "::ffff:ff00"); // '::ffff:c0a8:100'
203
228
  Converts a prefix length to a subnet mask string.
204
229
 
205
230
  ```ts
206
- ip.fromPrefixLen(24); // '255.255.255.0'
207
- ip.fromPrefixLen(64); // 'ffff:ffff:ffff:ffff::' (auto-detects IPv6)
208
- ip.fromPrefixLen(24, "ipv6"); // 'ffff:ff00::'
231
+ ip.fromPrefixLen(24); // '255.255.255.0'
232
+ ip.fromPrefixLen(64); // 'ffff:ffff:ffff:ffff::' (auto-detects IPv6)
233
+ ip.fromPrefixLen(24, 'ipv6'); // 'ffff:ff00::'
209
234
  ```
210
235
 
211
236
  ---
@@ -217,7 +242,7 @@ ip.fromPrefixLen(24, "ipv6"); // 'ffff:ff00::'
217
242
  Bitwise NOT — useful for computing wildcard masks.
218
243
 
219
244
  ```ts
220
- ip.not("255.255.255.0"); // '0.0.0.255'
245
+ ip.not('255.255.255.0'); // '0.0.0.255'
221
246
  ```
222
247
 
223
248
  #### `or(a: string, b: string): string`
@@ -225,9 +250,9 @@ ip.not("255.255.255.0"); // '0.0.0.255'
225
250
  Bitwise OR. Supports same-protocol and mixed IPv4/IPv6 inputs.
226
251
 
227
252
  ```ts
228
- ip.or("0.0.0.255", "192.168.1.10"); // '192.168.1.255'
229
- ip.or("::ff", "::abcd:dcba:abcd:dcba"); // '::abcd:dcba:abcd:dcff'
230
- ip.or("0.0.0.255", "::abcd:dcba:abcd:dcba"); // '::abcd:dcba:abcd:dcff'
253
+ ip.or('0.0.0.255', '192.168.1.10'); // '192.168.1.255'
254
+ ip.or('::ff', '::abcd:dcba:abcd:dcba'); // '::abcd:dcba:abcd:dcff'
255
+ ip.or('0.0.0.255', '::abcd:dcba:abcd:dcba'); // '::abcd:dcba:abcd:dcff'
231
256
  ```
232
257
 
233
258
  #### `isEqual(a: string, b: string): boolean`
@@ -235,9 +260,9 @@ ip.or("0.0.0.255", "::abcd:dcba:abcd:dcba"); // '::abcd:dcba:abcd:dcff'
235
260
  Deep equality check, IPv4/IPv6 aware (e.g. `127.0.0.1` equals `::ffff:7f00:1`).
236
261
 
237
262
  ```ts
238
- ip.isEqual("127.0.0.1", "::ffff:127.0.0.1"); // true
239
- ip.isEqual("127.0.0.1", "::7f00:1"); // true
240
- ip.isEqual("127.0.0.1", "::7f00:2"); // false
263
+ ip.isEqual('127.0.0.1', '::ffff:127.0.0.1'); // true
264
+ ip.isEqual('127.0.0.1', '::7f00:1'); // true
265
+ ip.isEqual('127.0.0.1', '::7f00:2'); // false
241
266
  ```
242
267
 
243
268
  ---
@@ -249,11 +274,11 @@ ip.isEqual("127.0.0.1", "::7f00:2"); // false
249
274
  Converts an IP string to a raw `Buffer` (4 bytes for IPv4, 16 for IPv6). Optionally writes into an existing buffer at a given offset.
250
275
 
251
276
  ```ts
252
- ip.toBuffer("127.0.0.1");
277
+ ip.toBuffer('127.0.0.1');
253
278
  // <Buffer 7f 00 00 01>
254
279
 
255
280
  const buf = Buffer.alloc(128);
256
- ip.toBuffer("127.0.0.1", buf, 64);
281
+ ip.toBuffer('127.0.0.1', buf, 64);
257
282
  // writes 4 bytes into buf at offset 64
258
283
  ```
259
284
 
@@ -262,8 +287,8 @@ ip.toBuffer("127.0.0.1", buf, 64);
262
287
  Converts a `Buffer` back to an IP address string.
263
288
 
264
289
  ```ts
265
- ip.toString(Buffer.from("7f000001", "hex")); // '127.0.0.1'
266
- ip.toString(buf, 64, 4); // '127.0.0.1'
290
+ ip.toString(Buffer.from('7f000001', 'hex')); // '127.0.0.1'
291
+ ip.toString(buf, 64, 4); // '127.0.0.1'
267
292
  ```
268
293
 
269
294
  ---
@@ -275,8 +300,8 @@ ip.toString(buf, 64, 4); // '127.0.0.1'
275
300
  Converts a dotted-decimal IPv4 address to an unsigned 32-bit integer.
276
301
 
277
302
  ```ts
278
- ip.toLong("127.0.0.1"); // 2130706433
279
- ip.toLong("255.255.255.255"); // 4294967295
303
+ ip.toLong('127.0.0.1'); // 2130706433
304
+ ip.toLong('255.255.255.255'); // 4294967295
280
305
  ```
281
306
 
282
307
  #### `fromLong(ipl: number): string`
@@ -284,8 +309,8 @@ ip.toLong("255.255.255.255"); // 4294967295
284
309
  Converts an unsigned 32-bit integer back to dotted-decimal.
285
310
 
286
311
  ```ts
287
- ip.fromLong(2130706433); // '127.0.0.1'
288
- ip.fromLong(4294967295); // '255.255.255.255'
312
+ ip.fromLong(2130706433); // '127.0.0.1'
313
+ ip.fromLong(4294967295); // '255.255.255.255'
289
314
  ```
290
315
 
291
316
  #### `normalizeToLong(addr: string): number`
@@ -293,12 +318,12 @@ ip.fromLong(4294967295); // '255.255.255.255'
293
318
  Normalizes an IPv4 address in any notation (decimal, octal, hex, compact) to an unsigned long. Returns `-1` on invalid input.
294
319
 
295
320
  ```ts
296
- ip.normalizeToLong("127.0.0.1"); // 2130706433 (standard)
297
- ip.normalizeToLong("0x7f.0x0.0x0.1"); // 2130706433 (hex)
298
- ip.normalizeToLong("0177.0.0.01"); // 2130706433 (octal)
299
- ip.normalizeToLong("0x7f000001"); // 2130706433 (single hex)
300
- ip.normalizeToLong("127.1"); // 2130706433 (compact)
301
- ip.normalizeToLong("256.0.0.1"); // -1 (invalid)
321
+ ip.normalizeToLong('127.0.0.1'); // 2130706433 (standard)
322
+ ip.normalizeToLong('0x7f.0x0.0x0.1'); // 2130706433 (hex)
323
+ ip.normalizeToLong('0177.0.0.01'); // 2130706433 (octal)
324
+ ip.normalizeToLong('0x7f000001'); // 2130706433 (single hex)
325
+ ip.normalizeToLong('127.1'); // 2130706433 (compact)
326
+ ip.normalizeToLong('256.0.0.1'); // -1 (invalid)
302
327
  ```
303
328
 
304
329
  ---
@@ -307,14 +332,17 @@ ip.normalizeToLong("256.0.0.1"); // -1 (invalid)
307
332
 
308
333
  #### `address(name?: string, family?: string | number): string`
309
334
 
335
+ > ⚠️ **Node.js only.** This function uses the `os` module which is not available in browsers.
336
+ > Calling it in a browser environment will throw a descriptive error. All other functions work in both environments.
337
+
310
338
  Returns an IP address from the current machine's network interfaces.
311
339
 
312
340
  ```ts
313
- ip.address(); // first private IPv4 address, e.g. '192.168.1.42'
314
- ip.address("public"); // first public IPv4 address
315
- ip.address("private"); // first private IPv4 address
316
- ip.address("eth0"); // first IPv4 address on eth0
317
- ip.address("eth0", 6); // first IPv6 address on eth0
341
+ ip.address(); // first private IPv4 address, e.g. '192.168.1.42'
342
+ ip.address('public'); // first public IPv4 address
343
+ ip.address('private'); // first private IPv4 address
344
+ ip.address('eth0'); // first IPv4 address on eth0
345
+ ip.address('eth0', 6); // first IPv6 address on eth0
318
346
  ```
319
347
 
320
348
  Falls back to `loopback()` if no matching interface is found.
@@ -324,9 +352,9 @@ Falls back to `loopback()` if no matching interface is found.
324
352
  Returns the loopback address for the given IP family.
325
353
 
326
354
  ```ts
327
- ip.loopback(); // '127.0.0.1'
328
- ip.loopback("ipv4"); // '127.0.0.1'
329
- ip.loopback("ipv6"); // 'fe80::1'
355
+ ip.loopback(); // '127.0.0.1'
356
+ ip.loopback('ipv4'); // '127.0.0.1'
357
+ ip.loopback('ipv6'); // 'fe80::1'
330
358
  ```
331
359
 
332
360
  ---
@@ -334,9 +362,9 @@ ip.loopback("ipv6"); // 'fe80::1'
334
362
  ### Types
335
363
 
336
364
  ```ts
337
- import type { IPFamily, SubnetInfo } from "node-ip-ts";
365
+ import type { IPFamily, SubnetInfo } from 'node-ip-ts';
338
366
 
339
- type IPFamily = "ipv4" | "ipv6";
367
+ type IPFamily = 'ipv4' | 'ipv6';
340
368
 
341
369
  interface SubnetInfo {
342
370
  networkAddress: string;
@@ -417,7 +445,7 @@ Please [open an issue](https://github.com/your-org/node-ip-ts/issues/new) with a
417
445
  Or for TypeScript / ESM:
418
446
 
419
447
  ```ts
420
- import * as ip from "node-ip-ts";
448
+ import * as ip from 'node-ip-ts';
421
449
  ```
422
450
 
423
451
  All function names and behaviours are identical to the original library.
@@ -426,10 +454,10 @@ All function names and behaviours are identical to the original library.
426
454
 
427
455
  ## License
428
456
 
429
- MIT © Deni Irawan Nugraha
457
+ [MIT](./LICENSE) © your-org
430
458
 
431
459
  ---
432
460
 
433
461
  <div align="center">
434
462
  <sub>If this library saved you time, consider giving it a ⭐ on GitHub.</sub>
435
- </div>
463
+ </div>