node-ip-ts 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.
- package/README.md +435 -0
- package/jest.config.js +22 -0
- package/package.json +46 -0
- package/src/index.ts +454 -0
- package/tests/ip.test.ts +454 -0
- package/tsconfig.cjs.json +17 -0
- package/tsconfig.esm.json +18 -0
- package/tsconfig.types.json +18 -0
package/tests/ip.test.ts
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { networkInterfaces } from "os";
|
|
2
|
+
import { isIPv4, isIPv6 } from "net";
|
|
3
|
+
import * as ip from "../src/index";
|
|
4
|
+
|
|
5
|
+
describe("IP library for node.js", () => {
|
|
6
|
+
// ─── toBuffer / toString ───────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
describe("toBuffer()/toString() methods", () => {
|
|
9
|
+
it("should convert to buffer IPv4 address", () => {
|
|
10
|
+
const buf = ip.toBuffer("127.0.0.1");
|
|
11
|
+
expect(buf.toString("hex")).toBe("7f000001");
|
|
12
|
+
expect(ip.toString(buf)).toBe("127.0.0.1");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should convert to buffer IPv4 address in-place", () => {
|
|
16
|
+
const buf = Buffer.alloc(128);
|
|
17
|
+
const offset = 64;
|
|
18
|
+
ip.toBuffer("127.0.0.1", buf, offset);
|
|
19
|
+
expect(buf.toString("hex", offset, offset + 4)).toBe("7f000001");
|
|
20
|
+
expect(ip.toString(buf, offset, 4)).toBe("127.0.0.1");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should convert to buffer IPv6 address", () => {
|
|
24
|
+
const buf = ip.toBuffer("::1");
|
|
25
|
+
expect(/(00){15,15}01/.test(buf.toString("hex"))).toBe(true);
|
|
26
|
+
expect(ip.toString(buf)).toBe("::1");
|
|
27
|
+
expect(ip.toString(ip.toBuffer("1::"))).toBe("1::");
|
|
28
|
+
expect(ip.toString(ip.toBuffer("abcd::dcba"))).toBe("abcd::dcba");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should convert to buffer IPv6 address in-place", () => {
|
|
32
|
+
const buf = Buffer.alloc(128);
|
|
33
|
+
const offset = 64;
|
|
34
|
+
ip.toBuffer("::1", buf, offset);
|
|
35
|
+
expect(
|
|
36
|
+
/(00){15,15}01/.test(buf.toString("hex", offset, offset + 16)),
|
|
37
|
+
).toBe(true);
|
|
38
|
+
expect(ip.toString(buf, offset, 16)).toBe("::1");
|
|
39
|
+
expect(ip.toString(ip.toBuffer("1::", buf, offset), offset, 16)).toBe(
|
|
40
|
+
"1::",
|
|
41
|
+
);
|
|
42
|
+
expect(
|
|
43
|
+
ip.toString(ip.toBuffer("abcd::dcba", buf, offset), offset, 16),
|
|
44
|
+
).toBe("abcd::dcba");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should convert to buffer IPv6 mapped IPv4 address", () => {
|
|
48
|
+
let buf = ip.toBuffer("::ffff:127.0.0.1");
|
|
49
|
+
expect(buf.toString("hex")).toBe("00000000000000000000ffff7f000001");
|
|
50
|
+
expect(ip.toString(buf)).toBe("::ffff:7f00:1");
|
|
51
|
+
|
|
52
|
+
buf = ip.toBuffer("ffff::127.0.0.1");
|
|
53
|
+
expect(buf.toString("hex")).toBe("ffff000000000000000000007f000001");
|
|
54
|
+
expect(ip.toString(buf)).toBe("ffff::7f00:1");
|
|
55
|
+
|
|
56
|
+
buf = ip.toBuffer("0:0:0:0:0:ffff:127.0.0.1");
|
|
57
|
+
expect(buf.toString("hex")).toBe("00000000000000000000ffff7f000001");
|
|
58
|
+
expect(ip.toString(buf)).toBe("::ffff:7f00:1");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// ─── fromPrefixLen ─────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
describe("fromPrefixLen() method", () => {
|
|
65
|
+
it("should create IPv4 mask", () => {
|
|
66
|
+
expect(ip.fromPrefixLen(24)).toBe("255.255.255.0");
|
|
67
|
+
});
|
|
68
|
+
it("should create IPv6 mask", () => {
|
|
69
|
+
expect(ip.fromPrefixLen(64)).toBe("ffff:ffff:ffff:ffff::");
|
|
70
|
+
});
|
|
71
|
+
it("should create IPv6 mask explicitly", () => {
|
|
72
|
+
expect(ip.fromPrefixLen(24, "IPV6")).toBe("ffff:ff00::");
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// ─── not ───────────────────────────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
describe("not() method", () => {
|
|
79
|
+
it("should reverse bits in address", () => {
|
|
80
|
+
expect(ip.not("255.255.255.0")).toBe("0.0.0.255");
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// ─── or ────────────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
describe("or() method", () => {
|
|
87
|
+
it("should or bits in ipv4 addresses", () => {
|
|
88
|
+
expect(ip.or("0.0.0.255", "192.168.1.10")).toBe("192.168.1.255");
|
|
89
|
+
});
|
|
90
|
+
it("should or bits in ipv6 addresses", () => {
|
|
91
|
+
expect(ip.or("::ff", "::abcd:dcba:abcd:dcba")).toBe(
|
|
92
|
+
"::abcd:dcba:abcd:dcff",
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
it("should or bits in mixed addresses", () => {
|
|
96
|
+
expect(ip.or("0.0.0.255", "::abcd:dcba:abcd:dcba")).toBe(
|
|
97
|
+
"::abcd:dcba:abcd:dcff",
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// ─── mask ──────────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
describe("mask() method", () => {
|
|
105
|
+
it("should mask bits in address", () => {
|
|
106
|
+
expect(ip.mask("192.168.1.134", "255.255.255.0")).toBe("192.168.1.0");
|
|
107
|
+
expect(ip.mask("192.168.1.134", "::ffff:ff00")).toBe("::ffff:c0a8:100");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should not leak data", () => {
|
|
111
|
+
for (let i = 0; i < 10; i++) {
|
|
112
|
+
expect(ip.mask("::1", "0.0.0.0")).toBe("::");
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// ─── subnet ────────────────────────────────────────────────────────────────
|
|
118
|
+
|
|
119
|
+
describe("subnet() method", () => {
|
|
120
|
+
const ipv4Subnet = ip.subnet("192.168.1.134", "255.255.255.192");
|
|
121
|
+
|
|
122
|
+
it("should compute ipv4 network address", () => {
|
|
123
|
+
expect(ipv4Subnet.networkAddress).toBe("192.168.1.128");
|
|
124
|
+
});
|
|
125
|
+
it("should compute ipv4 network's first address", () => {
|
|
126
|
+
expect(ipv4Subnet.firstAddress).toBe("192.168.1.129");
|
|
127
|
+
});
|
|
128
|
+
it("should compute ipv4 network's last address", () => {
|
|
129
|
+
expect(ipv4Subnet.lastAddress).toBe("192.168.1.190");
|
|
130
|
+
});
|
|
131
|
+
it("should compute ipv4 broadcast address", () => {
|
|
132
|
+
expect(ipv4Subnet.broadcastAddress).toBe("192.168.1.191");
|
|
133
|
+
});
|
|
134
|
+
it("should compute ipv4 subnet number of addresses", () => {
|
|
135
|
+
expect(ipv4Subnet.length).toBe(64);
|
|
136
|
+
});
|
|
137
|
+
it("should compute ipv4 subnet number of addressable hosts", () => {
|
|
138
|
+
expect(ipv4Subnet.numHosts).toBe(62);
|
|
139
|
+
});
|
|
140
|
+
it("should compute ipv4 subnet mask", () => {
|
|
141
|
+
expect(ipv4Subnet.subnetMask).toBe("255.255.255.192");
|
|
142
|
+
});
|
|
143
|
+
it("should compute ipv4 subnet mask's length", () => {
|
|
144
|
+
expect(ipv4Subnet.subnetMaskLength).toBe(26);
|
|
145
|
+
});
|
|
146
|
+
it("should know whether a subnet contains an address", () => {
|
|
147
|
+
expect(ipv4Subnet.contains("192.168.1.180")).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
it("should know whether a subnet does not contain an address", () => {
|
|
150
|
+
expect(ipv4Subnet.contains("192.168.1.195")).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe("subnet() method with mask length 32", () => {
|
|
155
|
+
const ipv4Subnet = ip.subnet("192.168.1.134", "255.255.255.255");
|
|
156
|
+
|
|
157
|
+
it("should compute ipv4 network's first address", () => {
|
|
158
|
+
expect(ipv4Subnet.firstAddress).toBe("192.168.1.134");
|
|
159
|
+
});
|
|
160
|
+
it("should compute ipv4 network's last address", () => {
|
|
161
|
+
expect(ipv4Subnet.lastAddress).toBe("192.168.1.134");
|
|
162
|
+
});
|
|
163
|
+
it("should compute ipv4 subnet number of addressable hosts", () => {
|
|
164
|
+
expect(ipv4Subnet.numHosts).toBe(1);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("subnet() method with mask length 31", () => {
|
|
169
|
+
const ipv4Subnet = ip.subnet("192.168.1.134", "255.255.255.254");
|
|
170
|
+
|
|
171
|
+
it("should compute ipv4 network's first address", () => {
|
|
172
|
+
expect(ipv4Subnet.firstAddress).toBe("192.168.1.134");
|
|
173
|
+
});
|
|
174
|
+
it("should compute ipv4 network's last address", () => {
|
|
175
|
+
expect(ipv4Subnet.lastAddress).toBe("192.168.1.135");
|
|
176
|
+
});
|
|
177
|
+
it("should compute ipv4 subnet number of addressable hosts", () => {
|
|
178
|
+
expect(ipv4Subnet.numHosts).toBe(2);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// ─── cidrSubnet ────────────────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
describe("cidrSubnet() method", () => {
|
|
185
|
+
const ipv4Subnet = ip.cidrSubnet("192.168.1.134/26");
|
|
186
|
+
|
|
187
|
+
it("should compute an ipv4 network address", () => {
|
|
188
|
+
expect(ipv4Subnet.networkAddress).toBe("192.168.1.128");
|
|
189
|
+
});
|
|
190
|
+
it("should compute an ipv4 network's first address", () => {
|
|
191
|
+
expect(ipv4Subnet.firstAddress).toBe("192.168.1.129");
|
|
192
|
+
});
|
|
193
|
+
it("should compute an ipv4 network's last address", () => {
|
|
194
|
+
expect(ipv4Subnet.lastAddress).toBe("192.168.1.190");
|
|
195
|
+
});
|
|
196
|
+
it("should compute an ipv4 broadcast address", () => {
|
|
197
|
+
expect(ipv4Subnet.broadcastAddress).toBe("192.168.1.191");
|
|
198
|
+
});
|
|
199
|
+
it("should compute an ipv4 subnet number of addresses", () => {
|
|
200
|
+
expect(ipv4Subnet.length).toBe(64);
|
|
201
|
+
});
|
|
202
|
+
it("should compute an ipv4 subnet number of addressable hosts", () => {
|
|
203
|
+
expect(ipv4Subnet.numHosts).toBe(62);
|
|
204
|
+
});
|
|
205
|
+
it("should compute an ipv4 subnet mask", () => {
|
|
206
|
+
expect(ipv4Subnet.subnetMask).toBe("255.255.255.192");
|
|
207
|
+
});
|
|
208
|
+
it("should compute an ipv4 subnet mask's length", () => {
|
|
209
|
+
expect(ipv4Subnet.subnetMaskLength).toBe(26);
|
|
210
|
+
});
|
|
211
|
+
it("should know whether a subnet contains an address", () => {
|
|
212
|
+
expect(ipv4Subnet.contains("192.168.1.180")).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
it("should know whether a subnet does not contain an address", () => {
|
|
215
|
+
expect(ipv4Subnet.contains("192.168.1.195")).toBe(false);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// ─── cidr ──────────────────────────────────────────────────────────────────
|
|
220
|
+
|
|
221
|
+
describe("cidr() method", () => {
|
|
222
|
+
it("should mask address in CIDR notation", () => {
|
|
223
|
+
expect(ip.cidr("192.168.1.134/26")).toBe("192.168.1.128");
|
|
224
|
+
expect(ip.cidr("2607:f0d0:1002:51::4/56")).toBe("2607:f0d0:1002::");
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// ─── isEqual ───────────────────────────────────────────────────────────────
|
|
229
|
+
|
|
230
|
+
describe("isEqual() method", () => {
|
|
231
|
+
it("should check if addresses are equal", () => {
|
|
232
|
+
expect(ip.isEqual("127.0.0.1", "::7f00:1")).toBe(true);
|
|
233
|
+
expect(ip.isEqual("127.0.0.1", "::7f00:2")).toBe(false);
|
|
234
|
+
expect(ip.isEqual("127.0.0.1", "::ffff:7f00:1")).toBe(true);
|
|
235
|
+
expect(ip.isEqual("127.0.0.1", "::ffaf:7f00:1")).toBe(false);
|
|
236
|
+
expect(ip.isEqual("::ffff:127.0.0.1", "::ffff:127.0.0.1")).toBe(true);
|
|
237
|
+
expect(ip.isEqual("::ffff:127.0.0.1", "127.0.0.1")).toBe(true);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// ─── normalizeToLong ───────────────────────────────────────────────────────
|
|
242
|
+
|
|
243
|
+
describe("normalizeIpv4() method", () => {
|
|
244
|
+
it('should correctly normalize "127.0.0.1"', () => {
|
|
245
|
+
expect(ip.normalizeToLong("127.0.0.1")).toBe(2130706433);
|
|
246
|
+
});
|
|
247
|
+
it('should correctly handle "127.1" as two parts', () => {
|
|
248
|
+
expect(ip.normalizeToLong("127.1")).toBe(2130706433);
|
|
249
|
+
});
|
|
250
|
+
it('should correctly handle "127.0.1" as three parts', () => {
|
|
251
|
+
expect(ip.normalizeToLong("127.0.1")).toBe(2130706433);
|
|
252
|
+
});
|
|
253
|
+
it('should correctly handle hexadecimal notation "0x7f.0x0.0x0.0x1"', () => {
|
|
254
|
+
expect(ip.normalizeToLong("0x7f.0x0.0x0.0x1")).toBe(2130706433);
|
|
255
|
+
});
|
|
256
|
+
it('should correctly handle "0x7f000001" as a single part', () => {
|
|
257
|
+
expect(ip.normalizeToLong("0x7f000001")).toBe(2130706433);
|
|
258
|
+
});
|
|
259
|
+
it('should correctly handle octal notation "010.0.0.01"', () => {
|
|
260
|
+
expect(ip.normalizeToLong("010.0.0.01")).toBe(134217729);
|
|
261
|
+
});
|
|
262
|
+
it('should return -1 for an invalid address "256.100.50.25"', () => {
|
|
263
|
+
expect(ip.normalizeToLong("256.100.50.25")).toBe(-1);
|
|
264
|
+
});
|
|
265
|
+
it('should return -1 for an address with invalid octal "019.0.0.1"', () => {
|
|
266
|
+
expect(ip.normalizeToLong("019.0.0.1")).toBe(-1);
|
|
267
|
+
});
|
|
268
|
+
it('should return -1 for an address with invalid hex "0xGG.0.0.1"', () => {
|
|
269
|
+
expect(ip.normalizeToLong("0xGG.0.0.1")).toBe(-1);
|
|
270
|
+
});
|
|
271
|
+
it("should return -1 for an empty string", () => {
|
|
272
|
+
expect(ip.normalizeToLong("")).toBe(-1);
|
|
273
|
+
});
|
|
274
|
+
it('should return -1 for a string with too many parts "192.168.0.1.100"', () => {
|
|
275
|
+
expect(ip.normalizeToLong("192.168.0.1.100")).toBe(-1);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// ─── isPrivate ─────────────────────────────────────────────────────────────
|
|
280
|
+
|
|
281
|
+
describe("isPrivate() method", () => {
|
|
282
|
+
it("should check if an address is localhost", () => {
|
|
283
|
+
expect(ip.isPrivate("127.0.0.1")).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
it("should check if an address is from a 192.168.x.x network", () => {
|
|
286
|
+
expect(ip.isPrivate("192.168.0.123")).toBe(true);
|
|
287
|
+
expect(ip.isPrivate("192.168.122.123")).toBe(true);
|
|
288
|
+
expect(ip.isPrivate("192.162.1.2")).toBe(false);
|
|
289
|
+
});
|
|
290
|
+
it("should check if an address is from a 172.16.x.x network", () => {
|
|
291
|
+
expect(ip.isPrivate("172.16.0.5")).toBe(true);
|
|
292
|
+
expect(ip.isPrivate("172.16.123.254")).toBe(true);
|
|
293
|
+
expect(ip.isPrivate("171.16.0.5")).toBe(false);
|
|
294
|
+
expect(ip.isPrivate("172.25.232.15")).toBe(true);
|
|
295
|
+
expect(ip.isPrivate("172.15.0.5")).toBe(false);
|
|
296
|
+
expect(ip.isPrivate("172.32.0.5")).toBe(false);
|
|
297
|
+
});
|
|
298
|
+
it("should check if an address is from a 169.254.x.x network", () => {
|
|
299
|
+
expect(ip.isPrivate("169.254.2.3")).toBe(true);
|
|
300
|
+
expect(ip.isPrivate("169.254.221.9")).toBe(true);
|
|
301
|
+
expect(ip.isPrivate("168.254.2.3")).toBe(false);
|
|
302
|
+
});
|
|
303
|
+
it("should check if an address is from a 10.x.x.x network", () => {
|
|
304
|
+
expect(ip.isPrivate("10.0.2.3")).toBe(true);
|
|
305
|
+
expect(ip.isPrivate("10.1.23.45")).toBe(true);
|
|
306
|
+
expect(ip.isPrivate("12.1.2.3")).toBe(false);
|
|
307
|
+
});
|
|
308
|
+
it("should check if an address is from a private IPv6 network", () => {
|
|
309
|
+
expect(ip.isPrivate("fd12:3456:789a:1::1")).toBe(true);
|
|
310
|
+
expect(ip.isPrivate("fe80::f2de:f1ff:fe3f:307e")).toBe(true);
|
|
311
|
+
expect(ip.isPrivate("::ffff:10.100.1.42")).toBe(true);
|
|
312
|
+
expect(ip.isPrivate("::FFFF:172.16.200.1")).toBe(true);
|
|
313
|
+
expect(ip.isPrivate("::ffff:192.168.0.1")).toBe(true);
|
|
314
|
+
});
|
|
315
|
+
it("should check if an address is from the internet", () => {
|
|
316
|
+
expect(ip.isPrivate("165.225.132.33")).toBe(false);
|
|
317
|
+
});
|
|
318
|
+
it("should check if an address is a loopback IPv6 address", () => {
|
|
319
|
+
expect(ip.isPrivate("::")).toBe(true);
|
|
320
|
+
expect(ip.isPrivate("::1")).toBe(true);
|
|
321
|
+
expect(ip.isPrivate("fe80::1")).toBe(true);
|
|
322
|
+
});
|
|
323
|
+
it("should correctly identify hexadecimal IP addresses like '0x7f.1' as private", () => {
|
|
324
|
+
expect(ip.isPrivate("0x7f.1")).toBe(true);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// ─── loopback ──────────────────────────────────────────────────────────────
|
|
329
|
+
|
|
330
|
+
describe("loopback() method", () => {
|
|
331
|
+
describe("undefined", () => {
|
|
332
|
+
it("should respond with 127.0.0.1", () => {
|
|
333
|
+
expect(ip.loopback()).toBe("127.0.0.1");
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
describe("ipv4", () => {
|
|
337
|
+
it("should respond with 127.0.0.1", () => {
|
|
338
|
+
expect(ip.loopback("ipv4")).toBe("127.0.0.1");
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
describe("ipv6", () => {
|
|
342
|
+
it("should respond with fe80::1", () => {
|
|
343
|
+
expect(ip.loopback("ipv6")).toBe("fe80::1");
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// ─── isLoopback ────────────────────────────────────────────────────────────
|
|
349
|
+
|
|
350
|
+
describe("isLoopback() method", () => {
|
|
351
|
+
it("127.0.0.1 should respond with true", () => {
|
|
352
|
+
expect(ip.isLoopback("127.0.0.1")).toBe(true);
|
|
353
|
+
});
|
|
354
|
+
it("127.8.8.8 should respond with true", () => {
|
|
355
|
+
expect(ip.isLoopback("127.8.8.8")).toBe(true);
|
|
356
|
+
});
|
|
357
|
+
it("8.8.8.8 should respond with false", () => {
|
|
358
|
+
expect(ip.isLoopback("8.8.8.8")).toBe(false);
|
|
359
|
+
});
|
|
360
|
+
it("fe80::1 should respond with true", () => {
|
|
361
|
+
expect(ip.isLoopback("fe80::1")).toBe(true);
|
|
362
|
+
});
|
|
363
|
+
it("::1 should respond with true", () => {
|
|
364
|
+
expect(ip.isLoopback("::1")).toBe(true);
|
|
365
|
+
});
|
|
366
|
+
it(":: should respond with true", () => {
|
|
367
|
+
expect(ip.isLoopback("::")).toBe(true);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// ─── address ───────────────────────────────────────────────────────────────
|
|
372
|
+
|
|
373
|
+
describe("address() method", () => {
|
|
374
|
+
describe("undefined", () => {
|
|
375
|
+
it("should respond with a private ip", () => {
|
|
376
|
+
expect(ip.isPrivate(ip.address())).toBe(true);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
describe("private", () => {
|
|
381
|
+
([undefined, "ipv4", "ipv6"] as const).forEach((family) => {
|
|
382
|
+
describe(family ?? "undefined", () => {
|
|
383
|
+
it("should respond with a private ip", () => {
|
|
384
|
+
expect(ip.isPrivate(ip.address("private", family))).toBe(true);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const ifaces = networkInterfaces();
|
|
391
|
+
Object.keys(ifaces).forEach((nic) => {
|
|
392
|
+
describe(nic, () => {
|
|
393
|
+
([undefined, "ipv4"] as const).forEach((family) => {
|
|
394
|
+
describe(family ?? "undefined", () => {
|
|
395
|
+
it("should respond with an ipv4 address", () => {
|
|
396
|
+
const addr = ip.address(nic, family);
|
|
397
|
+
expect(!addr || isIPv4(addr)).toBe(true);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
describe("ipv6", () => {
|
|
403
|
+
it("should respond with an ipv6 address", () => {
|
|
404
|
+
const addr = ip.address(nic, "ipv6");
|
|
405
|
+
expect(!addr || isIPv6(addr)).toBe(true);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// ─── toLong / fromLong ─────────────────────────────────────────────────────
|
|
413
|
+
|
|
414
|
+
describe("toLong() method", () => {
|
|
415
|
+
it("should respond with a int", () => {
|
|
416
|
+
expect(ip.toLong("127.0.0.1")).toBe(2130706433);
|
|
417
|
+
expect(ip.toLong("255.255.255.255")).toBe(4294967295);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
describe("fromLong() method", () => {
|
|
422
|
+
it("should respond with ipv4 address", () => {
|
|
423
|
+
expect(ip.fromLong(2130706433)).toBe("127.0.0.1");
|
|
424
|
+
expect(ip.fromLong(4294967295)).toBe("255.255.255.255");
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// ─── Alternate notations ───────────────────────────────────────────────────
|
|
429
|
+
|
|
430
|
+
it('should return true for octal representation "0177.0.0.1"', () => {
|
|
431
|
+
expect(ip.isLoopback("0177.0.0.1")).toBe(true);
|
|
432
|
+
});
|
|
433
|
+
it('should return true for octal representation "0177.0.1"', () => {
|
|
434
|
+
expect(ip.isLoopback("0177.0.1")).toBe(true);
|
|
435
|
+
});
|
|
436
|
+
it('should return true for octal representation "0177.1"', () => {
|
|
437
|
+
expect(ip.isLoopback("0177.1")).toBe(true);
|
|
438
|
+
});
|
|
439
|
+
it('should return true for hexadecimal representation "0x7f.0.0.1"', () => {
|
|
440
|
+
expect(ip.isLoopback("0x7f.0.0.1")).toBe(true);
|
|
441
|
+
});
|
|
442
|
+
it('should return true for hexadecimal representation "0x7f.0.1"', () => {
|
|
443
|
+
expect(ip.isLoopback("0x7f.0.1")).toBe(true);
|
|
444
|
+
});
|
|
445
|
+
it('should return true for hexadecimal representation "0x7f.1"', () => {
|
|
446
|
+
expect(ip.isLoopback("0x7f.1")).toBe(true);
|
|
447
|
+
});
|
|
448
|
+
it('should return true for single long integer representation "2130706433"', () => {
|
|
449
|
+
expect(ip.isLoopback("2130706433")).toBe(true);
|
|
450
|
+
});
|
|
451
|
+
it('should return false for "192.168.1.1"', () => {
|
|
452
|
+
expect(ip.isLoopback("192.168.1.1")).toBe(false);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "./dist/cjs",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"declaration": false,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"],
|
|
16
|
+
"exclude": ["node_modules", "dist"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ES2020",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"outDir": "./dist/esm",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"declaration": false,
|
|
10
|
+
"declarationMap": false,
|
|
11
|
+
"sourceMap": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ES2020",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"outDir": "./dist/types",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"declarationMap": true,
|
|
11
|
+
"emitDeclarationOnly": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|