@pfeiferio/ipv4 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 ADDED
@@ -0,0 +1,154 @@
1
+ # @pfeiferio/ipv4
2
+
3
+ ![npm](https://img.shields.io/npm/v/@pfeiferio/ipv4)
4
+ ![types](https://img.shields.io/npm/types/@pfeiferio/ipv4)
5
+ ![license](https://img.shields.io/npm/l/@pfeiferio/ipv4)
6
+ ![downloads](https://img.shields.io/npm/dm/@pfeiferio/ipv4)
7
+ ![node](https://img.shields.io/node/v/@pfeiferio/ipv4)
8
+
9
+ Strict and well-tested IPv4 address and network utilities for Node.js.
10
+
11
+ * ESM only
12
+ * Node.js ≥ 18
13
+ * TypeScript-first
14
+ * No dependencies
15
+ * Full test coverage
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @pfeiferio/ipv4
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Basic Usage
28
+
29
+ ```js
30
+ import { ipV4 } from '@pfeiferio/ipv4'
31
+
32
+ const ip = ipV4('192.168.1.10/24')
33
+
34
+ ip.address // "192.168.1.10"
35
+ ip.prefix // 24
36
+ ip.addressWithCidr // "192.168.1.10/24"
37
+ ip.toInteger() // 3232235786
38
+ ```
39
+
40
+ Default prefix is `/32`.
41
+
42
+ ---
43
+
44
+ ## IPv4Address examples
45
+
46
+ ### Create addresses
47
+
48
+ ```js
49
+ ipV4('1.1.1.1')
50
+ ipV4('1.1.1.1/32')
51
+ ipV4(3232235777)
52
+ ```
53
+
54
+ ### Prefix handling (immutable)
55
+
56
+ ```js
57
+ const ip = ipV4('10.0.0.1')
58
+ const withPrefix = ip.withPrefix(16)
59
+
60
+ ip.addressWithCidr // "10.0.0.1/32"
61
+ withPrefix.addressWithCidr // "10.0.0.1/16"
62
+ ```
63
+
64
+ ### Address comparison
65
+
66
+ ```js
67
+ ip.equals(ipV4('10.0.0.1/32')) // true
68
+ ip.isSameAddress(ipV4('10.0.0.1/8')) // true
69
+ ```
70
+
71
+ ### Navigation
72
+
73
+ ```js
74
+ ipV4('1.1.1.1').next().address // "1.1.1.2"
75
+ ipV4('1.1.1.1').prev().address // "1.1.1.0"
76
+ ```
77
+
78
+ ---
79
+
80
+ ## IPv4Network examples
81
+
82
+ ### Create networks
83
+
84
+ ```js
85
+ const net = ipV4('192.168.1.10/24').network()
86
+
87
+ net.addressWithCidr // "192.168.1.0/24"
88
+ net.size // 256
89
+ net.hostCount // 254
90
+ ```
91
+
92
+ ### Network helpers
93
+
94
+ ```js
95
+ net.firstHost.address // "192.168.1.1"
96
+ net.lastHost.address // "192.168.1.254"
97
+ net.broadcast.address // "192.168.1.255"
98
+ ```
99
+
100
+ ### Containment & relations
101
+
102
+ ```js
103
+ net.contains('192.168.1.42') // true
104
+ net.overlaps('192.168.1.128/25') // true
105
+ net.containsNetwork('192.168.1.128/25') // true
106
+ net.isSubnetOf('192.168.0.0/16') // true
107
+ net.isSupernetOf('192.168.1.128/25') // true
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Iteration
113
+
114
+ ### Usable hosts
115
+
116
+ ```js
117
+ for (const host of net.hosts()) {
118
+ console.log(host.address)
119
+ }
120
+ ```
121
+
122
+ ### All addresses
123
+
124
+ ```js
125
+ for (const addr of net.addresses()) {
126
+ console.log(addr.address)
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Utilities
133
+
134
+ ```js
135
+ import { ipToInt, intToIp } from '@pfeiferio/ipv4'
136
+
137
+ ipToInt('192.168.1.1') // 3232235777
138
+ intToIp(3232235777) // "192.168.1.1"
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Design notes
144
+
145
+ * Prefix defaults to `/32`
146
+ * Network addresses are always normalized
147
+ * No implicit magic
148
+ * `/0`, `/31`, `/32` handled correctly
149
+
150
+ ---
151
+
152
+ ## License
153
+
154
+ MIT
@@ -0,0 +1,38 @@
1
+ import { IPv4Network } from "./IPv4Network.js";
2
+ import type { IPv4Input, IPv4AddressAsString, IPv4AddressInAddrArpa, IPv4AddressWithCidrAsString } from "./types.js";
3
+ type IpV4Options = {
4
+ allowZeroOctet?: boolean;
5
+ };
6
+ export declare class IPv4Address {
7
+ #private;
8
+ static fromInteger: (value: number, prefix?: number) => IPv4Address;
9
+ static fromString: (value: string) => IPv4Address;
10
+ static isValid: (value: IPv4Input) => boolean;
11
+ static private: () => IPv4Address[];
12
+ static rfc1918: () => IPv4Address[];
13
+ constructor(ipv4Address: IPv4Input, prefixOverride?: number | null, { allowZeroOctet }?: IpV4Options);
14
+ get prefix(): number;
15
+ get address(): IPv4AddressAsString;
16
+ get addressWithCidr(): IPv4AddressWithCidrAsString;
17
+ network(): IPv4Network;
18
+ isInSubnet(subnet: IPv4Input): boolean;
19
+ toString(): IPv4AddressAsString;
20
+ toInteger(): number;
21
+ equals(other: IPv4Input): boolean;
22
+ isSameAddress(other: IPv4Input): boolean;
23
+ next(): IPv4Address | null;
24
+ prev(): IPv4Address | null;
25
+ withPrefix(prefix: number): IPv4Address;
26
+ isPrivate(): boolean;
27
+ isPublic(): boolean;
28
+ isLoopback(): boolean;
29
+ isLinkLocal(): boolean;
30
+ isMulticast(): boolean;
31
+ isReserved(): boolean;
32
+ reversePointer(): IPv4AddressInAddrArpa;
33
+ toBinary(): string;
34
+ toBinaryAddress(): string;
35
+ toHex(): string;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=IPv4Address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPv4Address.d.ts","sourceRoot":"","sources":["../src/IPv4Address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAEpB,KAAK,WAAW,GAAG;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,qBAAa,WAAW;;IAMtB,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,WAAW,CAAC;IACpE,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,MAAM,WAAW,EAAE,CAAC;IACpC,MAAM,CAAC,OAAO,EAAE,MAAM,WAAW,EAAE,CAAC;gBAGlC,WAAW,EAAE,SAAS,EACtB,cAAc,GAAE,MAAM,GAAG,IAAW,EACpC,EAAC,cAAsB,EAAC,GAAE,WAAgB;IA2B5C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,OAAO,IAAI,mBAAmB,CAEjC;IAED,IAAI,eAAe,IAAI,2BAA2B,CAEjD;IAgBD,OAAO,IAAI,WAAW;IAItB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO;IAItC,QAAQ,IAAI,mBAAmB;IAI/B,SAAS,IAAI,MAAM;IAInB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAMjC,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAIxC,IAAI,IAAI,WAAW,GAAG,IAAI;IAK1B,IAAI,IAAI,WAAW,GAAG,IAAI;IAK1B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;IAIvC,SAAS,IAAI,OAAO;IAWpB,QAAQ,IAAI,OAAO;IAKnB,UAAU,IAAI,OAAO;IAKrB,WAAW,IAAI,OAAO;IAKtB,WAAW,IAAI,OAAO;IAKtB,UAAU,IAAI,OAAO;IAKrB,cAAc,IAAI,qBAAqB;IAKvC,QAAQ,IAAI,MAAM;IAMlB,eAAe,IAAI,MAAM;IAKzB,KAAK,IAAI,MAAM;CAGhB"}
@@ -0,0 +1,157 @@
1
+ import { IPv4Network } from "./IPv4Network.js";
2
+ import { ipV4, parseNumberToIp, parseStringToIp } from "./utils.js";
3
+ export class IPv4Address {
4
+ #addressAsInteger = 0;
5
+ #prefix;
6
+ #address;
7
+ #network = null;
8
+ static fromInteger;
9
+ static fromString;
10
+ static isValid;
11
+ static private;
12
+ static rfc1918;
13
+ constructor(ipv4Address, prefixOverride = null, { allowZeroOctet = false } = {}) {
14
+ if (typeof ipv4Address === 'string') {
15
+ const { address, prefix, addressAsInteger } = parseStringToIp(ipv4Address, prefixOverride);
16
+ this.#addressAsInteger = addressAsInteger;
17
+ this.#prefix = prefix;
18
+ this.#address = address;
19
+ // Validate zero octet only for string input
20
+ if (!allowZeroOctet) {
21
+ this.#validateZeroOctet();
22
+ }
23
+ }
24
+ else if (typeof ipv4Address === 'number') {
25
+ const { address, prefix, addressAsInteger } = parseNumberToIp(ipv4Address);
26
+ this.#addressAsInteger = addressAsInteger;
27
+ this.#prefix = prefixOverride ?? prefix;
28
+ this.#address = address;
29
+ }
30
+ else if (ipv4Address instanceof IPv4Address) {
31
+ this.#prefix = prefixOverride ?? ipv4Address.#prefix;
32
+ this.#address = ipv4Address.#address;
33
+ this.#addressAsInteger = ipv4Address.#addressAsInteger;
34
+ }
35
+ else {
36
+ throw new Error(`Invalid IPv4 address type: ${typeof ipv4Address}`);
37
+ }
38
+ }
39
+ get prefix() {
40
+ return this.#prefix;
41
+ }
42
+ get address() {
43
+ return this.#address;
44
+ }
45
+ get addressWithCidr() {
46
+ return `${this.address}/${this.prefix}`;
47
+ }
48
+ #validateZeroOctet() {
49
+ const firstOctet = (this.#addressAsInteger >>> 24) & 0xFF;
50
+ if (firstOctet !== 0) {
51
+ return;
52
+ }
53
+ if (this.#addressAsInteger === 0 && [0, 8, 32].includes(this.#prefix)) {
54
+ return;
55
+ }
56
+ throw new Error('First octet cannot be 0 (except 0.0.0.0 with /0, /8, or /32)');
57
+ }
58
+ network() {
59
+ return this.#network ??= new IPv4Network(this);
60
+ }
61
+ isInSubnet(subnet) {
62
+ return new IPv4Network(subnet).contains(this);
63
+ }
64
+ toString() {
65
+ return this.#address;
66
+ }
67
+ toInteger() {
68
+ return this.#addressAsInteger;
69
+ }
70
+ equals(other) {
71
+ other = ipV4(other);
72
+ return this.toInteger() === other.toInteger() &&
73
+ this.prefix === other.prefix;
74
+ }
75
+ isSameAddress(other) {
76
+ return this.toInteger() === ipV4(other).toInteger();
77
+ }
78
+ next() {
79
+ if (this.toInteger() >= 0xFFFFFFFF)
80
+ return null;
81
+ return new IPv4Address(this.toInteger() + 1, this.prefix);
82
+ }
83
+ prev() {
84
+ if (this.toInteger() <= 0)
85
+ return null;
86
+ return new IPv4Address(this.toInteger() - 1, this.prefix);
87
+ }
88
+ withPrefix(prefix) {
89
+ return new IPv4Address(this.#addressAsInteger, prefix);
90
+ }
91
+ isPrivate() {
92
+ const int = this.#addressAsInteger;
93
+ // 10.0.0.0/8
94
+ if ((int & 0xFF000000) === 0x0A000000)
95
+ return true;
96
+ // 172.16.0.0/12
97
+ if (((int & 0xFFF00000) >>> 0) === 0xAC100000)
98
+ return true;
99
+ // 192.168.0.0/16
100
+ if (((int & 0xFFFF0000) >>> 0) === 0xC0A80000)
101
+ return true;
102
+ return false;
103
+ }
104
+ isPublic() {
105
+ return !this.isPrivate() && !this.isLoopback() && !this.isLinkLocal()
106
+ && !this.isMulticast() && !this.isReserved();
107
+ }
108
+ isLoopback() {
109
+ // 127.0.0.0/8
110
+ return (this.#addressAsInteger & 0xFF000000) === 0x7F000000;
111
+ }
112
+ isLinkLocal() {
113
+ // 169.254.0.0/16
114
+ return ((this.#addressAsInteger & 0xFFFF0000) >>> 0) === 0xA9FE0000;
115
+ }
116
+ isMulticast() {
117
+ // 224.0.0.0/4 (224-239.x.x.x)
118
+ return ((this.#addressAsInteger & 0xF0000000) >>> 0) === 0xE0000000;
119
+ }
120
+ isReserved() {
121
+ // 240.0.0.0/4 (240-255.x.x.x)
122
+ return ((this.#addressAsInteger & 0xF0000000) >>> 0) === 0xF0000000;
123
+ }
124
+ reversePointer() {
125
+ const octets = this.#address.split('.');
126
+ return `${octets[3]}.${octets[2]}.${octets[1]}.${octets[0]}.in-addr.arpa`;
127
+ }
128
+ toBinary() {
129
+ const format = (len, fill = true) => ((this.#addressAsInteger >>> len) & 0xFF).toString(2).padStart(fill ? 8 : 0, '0');
130
+ return `${format(24, false)}${format(16)}${format(8)}${format(0)}`;
131
+ }
132
+ toBinaryAddress() {
133
+ const format = (len) => ((this.#addressAsInteger >>> len) & 0xFF).toString(2).padStart(8, '0');
134
+ return `${format(24)}.${format(16)}.${format(8)}.${format(0)}`;
135
+ }
136
+ toHex() {
137
+ return this.#addressAsInteger.toString(16).toUpperCase().padStart(8, '0');
138
+ }
139
+ }
140
+ IPv4Address.fromInteger = (value, prefix = 32) => new IPv4Address(value, prefix);
141
+ IPv4Address.fromString = (value) => ipV4(value);
142
+ IPv4Address.isValid = (value) => {
143
+ try {
144
+ new IPv4Address(value);
145
+ return true;
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ };
151
+ IPv4Address.private = () => [
152
+ new IPv4Address('10.0.0.0/8'),
153
+ new IPv4Address('172.16.0.0/12'),
154
+ new IPv4Address('192.168.0.0/16')
155
+ ];
156
+ IPv4Address.rfc1918 = () => IPv4Address.private();
157
+ //# sourceMappingURL=IPv4Address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPv4Address.js","sourceRoot":"","sources":["../src/IPv4Address.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { IPv4Address } from "./IPv4Address.js";
2
+ import type { IPv4AddressAsString, IPv4AddressWithCidrAsString, IPv4Input, IPv4NetworkInput } from "./types.js";
3
+ export declare class IPv4Network {
4
+ #private;
5
+ constructor(address: IPv4NetworkInput);
6
+ get addressWithCidr(): IPv4AddressWithCidrAsString;
7
+ get address(): IPv4AddressAsString;
8
+ get prefix(): number;
9
+ get size(): number;
10
+ get firstHost(): IPv4Address | null;
11
+ get lastHost(): IPv4Address | null;
12
+ get broadcast(): IPv4Address;
13
+ get netmask(): IPv4Address;
14
+ get hostmask(): IPv4Address;
15
+ get hostCount(): number;
16
+ contains(other: IPv4Input): boolean;
17
+ overlaps(other: IPv4NetworkInput): boolean;
18
+ containsNetwork(other: IPv4NetworkInput): boolean;
19
+ isSubnetOf(other: IPv4NetworkInput): boolean;
20
+ isSupernetOf(other: IPv4NetworkInput): boolean;
21
+ toInteger(): number;
22
+ toString(): string;
23
+ equals(other: IPv4Input): boolean;
24
+ hosts(keepPrefix?: boolean): Generator<IPv4Address, void | IPv4Address, undefined | IPv4Address>;
25
+ addresses(keepPrefix?: boolean): Generator<IPv4Address, void | IPv4Address, undefined | IPv4Address>;
26
+ }
27
+ //# sourceMappingURL=IPv4Network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPv4Network.d.ts","sourceRoot":"","sources":["../src/IPv4Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAC,mBAAmB,EAAE,2BAA2B,EAAE,SAAS,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAE9G,qBAAa,WAAW;;gBAMV,OAAO,EAAE,gBAAgB;IAerC,IAAI,eAAe,IAAI,2BAA2B,CAEjD;IAED,IAAI,OAAO,IAAI,mBAAmB,CAEjC;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,SAAS,IAAI,WAAW,GAAG,IAAI,CAGlC;IAED,IAAI,QAAQ,IAAI,WAAW,GAAG,IAAI,CAGjC;IAED,IAAI,SAAS,IAAI,WAAW,CAE3B;IAED,IAAI,OAAO,IAAI,WAAW,CAGzB;IAED,IAAI,QAAQ,IAAI,WAAW,CAE1B;IAED,IAAI,SAAS,IAAI,MAAM,CAGtB;IAED,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAYnC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO;IAc1C,eAAe,CAAC,KAAK,EAAE,gBAAgB;IAcvC,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO;IAO5C,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO;IAI9C,SAAS,IAAI,MAAM;IAInB,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAM/B,KAAK,CAAC,UAAU,GAAE,OAAe,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC;IAWvG,SAAS,CAAC,UAAU,GAAE,OAAe,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC;CAO9G"}
@@ -0,0 +1,122 @@
1
+ import { IPv4Address } from "./IPv4Address.js";
2
+ import { intToIp, ipV4, networkAddressFromInt } from "./utils.js";
3
+ export class IPv4Network {
4
+ #addressAsInteger;
5
+ #prefix;
6
+ #address;
7
+ constructor(address) {
8
+ if (address instanceof IPv4Network) {
9
+ this.#address = address.#address;
10
+ this.#addressAsInteger = address.#addressAsInteger;
11
+ this.#prefix = address.#prefix;
12
+ return;
13
+ }
14
+ else if (!(address instanceof IPv4Address)) {
15
+ address = new IPv4Address(address);
16
+ }
17
+ this.#addressAsInteger = networkAddressFromInt(address.toInteger(), address.prefix);
18
+ this.#address = intToIp(this.#addressAsInteger);
19
+ this.#prefix = address.prefix;
20
+ }
21
+ get addressWithCidr() {
22
+ return `${this.address}/${this.prefix}`;
23
+ }
24
+ get address() {
25
+ return this.#address;
26
+ }
27
+ get prefix() {
28
+ return this.#prefix;
29
+ }
30
+ get size() {
31
+ return 2 ** (32 - this.prefix);
32
+ }
33
+ get firstHost() {
34
+ if (this.prefix >= 31)
35
+ return null;
36
+ return new IPv4Address(this.toInteger() + 1);
37
+ }
38
+ get lastHost() {
39
+ if (this.prefix >= 31)
40
+ return null;
41
+ return new IPv4Address(this.toInteger() + this.size - 2);
42
+ }
43
+ get broadcast() {
44
+ return new IPv4Address(this.toInteger() + this.size - 1);
45
+ }
46
+ get netmask() {
47
+ const mask = (0xFFFFFFFF << (32 - this.prefix)) >>> 0;
48
+ return new IPv4Address(mask);
49
+ }
50
+ get hostmask() {
51
+ return new IPv4Address((2 ** (32 - this.prefix)) - 1, null, { allowZeroOctet: true });
52
+ }
53
+ get hostCount() {
54
+ const s = this.size;
55
+ return s <= 2 ? 0 : s - 2;
56
+ }
57
+ contains(other) {
58
+ other = ipV4(other);
59
+ const prefix = this.prefix;
60
+ const mask = prefix === 0
61
+ ? 0
62
+ : (0xFFFFFFFF << (32 - prefix)) >>> 0;
63
+ return ((other.toInteger() & mask) >>> 0) === this.toInteger();
64
+ }
65
+ overlaps(other) {
66
+ if (!(other instanceof IPv4Network)) {
67
+ other = new IPv4Network(other);
68
+ }
69
+ const startA = this.toInteger();
70
+ const endA = startA + this.size - 1;
71
+ const startB = other.toInteger();
72
+ const endB = startB + other.size - 1;
73
+ return startA <= endB && startB <= endA;
74
+ }
75
+ containsNetwork(other) {
76
+ if (!(other instanceof IPv4Network)) {
77
+ other = new IPv4Network(other);
78
+ }
79
+ const startA = this.toInteger();
80
+ const endA = startA + this.size - 1;
81
+ const startB = other.toInteger();
82
+ const endB = startB + other.size - 1;
83
+ return startA <= startB && endB <= endA;
84
+ }
85
+ isSubnetOf(other) {
86
+ if (!(other instanceof IPv4Network)) {
87
+ other = new IPv4Network(other);
88
+ }
89
+ return other.containsNetwork(this);
90
+ }
91
+ isSupernetOf(other) {
92
+ return this.containsNetwork(other);
93
+ }
94
+ toInteger() {
95
+ return this.#addressAsInteger;
96
+ }
97
+ toString() {
98
+ return this.addressWithCidr;
99
+ }
100
+ equals(other) {
101
+ other = ipV4(other);
102
+ return this.toInteger() === other.toInteger() &&
103
+ this.prefix === other.prefix;
104
+ }
105
+ *hosts(keepPrefix = false) {
106
+ if (this.prefix >= 31)
107
+ return;
108
+ const start = this.toInteger() + 1;
109
+ const end = this.toInteger() + this.size - 1;
110
+ for (let i = start; i < end; i++) {
111
+ yield new IPv4Address(i, keepPrefix ? this.prefix : 32);
112
+ }
113
+ }
114
+ *addresses(keepPrefix = false) {
115
+ const start = this.toInteger();
116
+ const end = start + this.size;
117
+ for (let i = start; i < end; i++) {
118
+ yield new IPv4Address(i, keepPrefix ? this.prefix : 32);
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=IPv4Network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPv4Network.js","sourceRoot":"","sources":["../src/IPv4Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAC,MAAM,YAAY,CAAC;AAGhE,MAAM,OAAO,WAAW;IAEb,iBAAiB,CAAQ;IACzB,OAAO,CAAQ;IACf,QAAQ,CAAQ;IAEzB,YAAY,OAAyB;QACnC,IAAI,OAAO,YAAY,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;YAChC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAA;YAClD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;YAC9B,OAAM;QACR,CAAC;aAAM,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC,EAAE,CAAC;YAC7C,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;QACpC,CAAC;QAED,IAAI,CAAC,iBAAiB,GAAG,qBAAqB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QACnF,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAA;IAC/B,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAA;IACzC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,SAAS;QACX,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,QAAQ;QACV,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,OAAO;QACT,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAC,cAAc,EAAE,IAAI,EAAC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,SAAS;QACX,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,KAAgB;QACvB,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAEnB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,IAAI,GACR,MAAM,KAAK,CAAC;YACV,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAA;QAEzC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAA;IAChE,CAAC;IAED,QAAQ,CAAC,KAAuB;QAC9B,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC,EAAE,CAAC;YACpC,KAAK,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QAEnC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAChC,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAA;QAEpC,OAAO,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAA;IACzC,CAAC;IAED,eAAe,CAAC,KAAuB;QACrC,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC,EAAE,CAAC;YACpC,KAAK,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QAEnC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAChC,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAA;QAEpC,OAAO,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAA;IACzC,CAAC;IAED,UAAU,CAAC,KAAuB;QAChC,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC,EAAE,CAAC;YACpC,KAAK,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC;QACD,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,YAAY,CAAC,KAAuB;QAClC,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,iBAAiB,CAAA;IAC/B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,eAAe,CAAA;IAC7B,CAAC;IAED,MAAM,CAAC,KAAgB;QACrB,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QACnB,OAAO,IAAI,CAAC,SAAS,EAAE,KAAK,KAAK,CAAC,SAAS,EAAE;YAC3C,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;IACjC,CAAC;IAED,CAAE,KAAK,CAAC,aAAsB,KAAK;QACjC,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO;QAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAE7C,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,CAAE,SAAS,CAAC,aAAsB,KAAK;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export { ipV4 } from "./utils.js";
2
+ export { IPv4Address } from './IPv4Address.js';
3
+ export { IPv4Network } from './IPv4Network.js';
4
+ export { ipToInt, intToIp, networkAddressFromInt } from './utils.js';
5
+ export type { IPv4Input, IPv4NetworkInput } from './types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAGhC,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAG5C,OAAO,EACL,OAAO,EACP,OAAO,EACP,qBAAqB,EACtB,MAAM,YAAY,CAAA;AAGnB,YAAY,EACV,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ // core
2
+ export { ipV4 } from "./utils.js";
3
+ // classes
4
+ export { IPv4Address } from './IPv4Address.js';
5
+ export { IPv4Network } from './IPv4Network.js';
6
+ // utils
7
+ export { ipToInt, intToIp, networkAddressFromInt } from './utils.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAC;AAEhC,UAAU;AACV,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAE5C,QAAQ;AACR,OAAO,EACL,OAAO,EACP,OAAO,EACP,qBAAqB,EACtB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { IPv4Address } from "./IPv4Address.js";
2
+ import type { IPv4Network } from "./IPv4Network.js";
3
+ export type IPv4Input = IPv4Address | string | number;
4
+ export type IPv4NetworkInput = IPv4Input | IPv4Network;
5
+ export type ParserResult = {
6
+ address: string;
7
+ addressAsInteger: number;
8
+ prefix: number;
9
+ };
10
+ export type IPv4AddressAsString = string;
11
+ export type IPv4AddressWithCidrAsString = string;
12
+ export type IPv4AddressInAddrArpa = string;
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAElD,MAAM,MAAM,SAAS,GACnB,WAAW,GAAG,MAAM,GAAG,MAAM,CAAA;AAE/B,MAAM,MAAM,gBAAgB,GAC1B,SAAS,GAAG,WAAW,CAAA;AAEzB,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAA;AACxC,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAA;AAChD,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { IPv4Address } from "./IPv4Address.js";
2
+ import type { IPv4Input, ParserResult } from "./types.js";
3
+ export declare const intToIp: (value: number) => string;
4
+ export declare const ipV4: (address: IPv4Input) => IPv4Address;
5
+ export declare const ipToInt: (ipv4Address: string) => number;
6
+ export declare const parseStringToIp: (ipv4Address: string, prefixOverride?: number | null) => ParserResult;
7
+ export declare const parseNumberToIp: (ipv4Address: number) => ParserResult;
8
+ export declare const networkAddressFromInt: (ip: number, prefix: number) => number;
9
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAC,SAAS,EAAE,YAAY,EAAC,MAAM,YAAY,CAAC;AAExD,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,MAWvC,CAAA;AAED,eAAO,MAAM,IAAI,GAAI,SAAS,SAAS,KAAG,WAAuC,CAAA;AAEjF,eAAO,MAAM,OAAO,GAAI,aAAa,MAAM,KAAG,MA0B7C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,EAAE,iBAAgB,MAAM,GAAG,IAAW,KAAG,YA2B3F,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,KAAG,YAMrD,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,KAAG,MAelE,CAAA"}
package/dist/utils.js ADDED
@@ -0,0 +1,74 @@
1
+ import { IPv4Address } from "./IPv4Address.js";
2
+ export const intToIp = (value) => {
3
+ if (!Number.isInteger(value) || value < 0 || value > 0xFFFFFFFF) {
4
+ throw new Error('Invalid IPv4 integer');
5
+ }
6
+ return [
7
+ (value >>> 24) & 0xFF,
8
+ (value >>> 16) & 0xFF,
9
+ (value >>> 8) & 0xFF,
10
+ value & 0xFF
11
+ ].join('.');
12
+ };
13
+ export const ipV4 = (address) => new IPv4Address(address);
14
+ export const ipToInt = (ipv4Address) => {
15
+ const parts = ipv4Address.split('/');
16
+ if (parts.length > 2) {
17
+ throw new Error('Invalid IPv4 address format: too many "/" separators');
18
+ }
19
+ return parts[0].split('.').reduce((acc, part, _idx, arr) => {
20
+ if (arr.length !== 4) {
21
+ throw new Error('IPv4 address must have exactly 4 octets');
22
+ }
23
+ const num = Number(part);
24
+ if (!Number.isInteger(num)) {
25
+ throw new Error(`Octet "${part}" is not a valid integer`);
26
+ }
27
+ if (num < 0 || num > 255) {
28
+ throw new Error(`Octet ${num} is out of range (0-255)`);
29
+ }
30
+ return ((acc << 8) | num) >>> 0;
31
+ }, 0);
32
+ };
33
+ export const parseStringToIp = (ipv4Address, prefixOverride = null) => {
34
+ const parts = ipv4Address.split('/');
35
+ if (parts.length > 2) {
36
+ throw new Error('Invalid IPv4 address format: too many "/" separators');
37
+ }
38
+ let [address, prefixValue = 32] = parts;
39
+ const prefix = prefixOverride ?? Number(prefixValue);
40
+ if (!Number.isInteger(prefix)) {
41
+ throw new Error(`Prefix "${prefixValue}" is not a valid integer`);
42
+ }
43
+ if (prefix < 0 || prefix > 32) {
44
+ throw new Error(`Prefix ${prefix} is out of range (0-32)`);
45
+ }
46
+ const addressAsInteger = ipToInt(address);
47
+ address = intToIp(addressAsInteger);
48
+ return {
49
+ address,
50
+ addressAsInteger,
51
+ prefix
52
+ };
53
+ };
54
+ export const parseNumberToIp = (ipv4Address) => {
55
+ return {
56
+ address: intToIp(ipv4Address),
57
+ addressAsInteger: ipv4Address,
58
+ prefix: 32
59
+ };
60
+ };
61
+ export const networkAddressFromInt = (ip, prefix) => {
62
+ if (!Number.isInteger(ip) || ip < 0 || ip > 0xFFFFFFFF) {
63
+ throw new Error('Invalid IPv4 integer');
64
+ }
65
+ if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) {
66
+ throw new Error('Invalid prefix');
67
+ }
68
+ if (prefix === 0) {
69
+ return 0;
70
+ }
71
+ const mask = (0xFFFFFFFF << (32 - prefix)) >>> 0;
72
+ return (ip & mask) >>> 0;
73
+ };
74
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@pfeiferio/ipv4",
3
+ "version": "1.0.0",
4
+ "description": "A strict, well-tested IPv4 address and network utility library for Node.js",
5
+ "license": "MIT",
6
+ "author": "Pascal Pfeifer <pascal@pfeifer.zone>",
7
+ "sideEffects": false,
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "keywords": [
23
+ "ipv4",
24
+ "network",
25
+ "cidr",
26
+ "subnet",
27
+ "ip",
28
+ "networking",
29
+ "nodejs",
30
+ "typescript"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/pfeiferio/ipv4.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/pfeiferio/ipv4/issues"
38
+ },
39
+ "homepage": "https://github.com/pfeiferio/ipv4#readme",
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "scripts": {
47
+ "clean": "rm -rf dist",
48
+ "build": "tsc",
49
+ "test": "npm run build && node --test",
50
+ "test:coverage": "npm run build && node --test --experimental-test-coverage",
51
+ "test:watch": "node --test --watch",
52
+ "prepublishOnly": "npm run clean && npm test"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^20.17.9",
56
+ "typescript": "^5.9.3"
57
+ }
58
+ }