@push.rocks/smartnetwork 4.5.1 β†’ 4.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartnetwork',
6
- version: '4.5.1',
6
+ version: '4.5.2',
7
7
  description: 'A toolkit for network diagnostics including speed tests, port availability checks, and more.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwwQkFBMEI7SUFDaEMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDhGQUE4RjtDQUM1RyxDQUFBIn0=
package/license CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Lossless GmbH
3
+ Copyright (c) 2015 Task Venture Capital GmbH
4
4
  Copyright (c) 2020 TomΓ‘s Arias
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartnetwork",
3
- "version": "4.5.1",
3
+ "version": "4.5.2",
4
4
  "private": false,
5
5
  "description": "A toolkit for network diagnostics including speed tests, port availability checks, and more.",
6
6
  "exports": {
package/readme.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # @push.rocks/smartnetwork 🌐
2
2
 
3
- Comprehensive network diagnostics and utilities for Node.js applications
3
+ Comprehensive network diagnostics and IP intelligence for Node.js β€” speed tests, port scanning, ICMP ping, traceroute, DNS, RDAP, ASN lookups, and geolocation in a single, promise-based toolkit.
4
4
 
5
- ## πŸš€ Install
5
+ ## Issue Reporting and Security
6
+
7
+ For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
6
8
 
7
- To install `@push.rocks/smartnetwork`, run the following command in your terminal:
9
+ ## πŸš€ Install
8
10
 
9
11
  ```bash
10
12
  pnpm install @push.rocks/smartnetwork --save
@@ -12,29 +14,31 @@ pnpm install @push.rocks/smartnetwork --save
12
14
 
13
15
  ## 🎯 Overview
14
16
 
15
- **@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building network monitoring tools, implementing health checks, or just need to debug connectivity issues, this library has you covered with a clean, promise-based API.
17
+ **@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building monitoring dashboards, investigating IP ownership, or debugging connectivity β€” this library has you covered with a clean, async API and zero-config setup.
18
+
19
+ Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port checks, gateway detection) are powered by a bundled **Rust binary** for maximum performance and cross-platform reliability. Everything else β€” speed tests, DNS, public IP discovery, IP intelligence, HTTP health checks β€” runs in pure TypeScript.
16
20
 
17
21
  ### ✨ Key Features
18
22
 
19
- - **🏎️ Speed Testing** - Measure download/upload speeds using Cloudflare's infrastructure
20
- - **πŸ”Œ Port Management** - Check local/remote port availability, find free ports (sequential or random)
21
- - **πŸ“‘ Connectivity Testing** - Ping hosts, trace routes, check endpoints
22
- - **🌍 DNS Operations** - Resolve A, AAAA, and MX records with smart local/remote resolution
23
- - **πŸ” Network Discovery** - Get network interfaces, gateways, public IPs
24
- - **⚑ Performance Caching** - Built-in caching for expensive operations
25
- - **πŸ”§ Plugin Architecture** - Extend functionality with custom plugins
26
- - **πŸ“ Full TypeScript Support** - Complete type definitions included
23
+ | Category | Capabilities |
24
+ |----------|-------------|
25
+ | 🏎️ **Speed Testing** | Download/upload benchmarks via Cloudflare's global infrastructure |
26
+ | πŸ”Œ **Port Management** | Local/remote port checks, find free ports (sequential or random), exclusion lists |
27
+ | πŸ“‘ **Connectivity** | ICMP ping with stats, hop-by-hop traceroute, HTTP/HTTPS health checks |
28
+ | 🌍 **DNS** | A, AAAA, MX resolution with system-first + DoH fallback strategy |
29
+ | πŸ” **IP Intelligence** | ASN, organization, geolocation, RDAP registration β€” all from free public sources |
30
+ | πŸ–₯️ **Network Discovery** | Interfaces, default gateway, public IPv4/IPv6 |
31
+ | ⚑ **Caching** | Built-in TTL cache for expensive lookups |
32
+ | πŸ”§ **Extensible** | Plugin architecture for custom functionality |
33
+ | πŸ“ **TypeScript** | Full type definitions, ESM-native |
27
34
 
28
35
  ## πŸ’» Usage
29
36
 
30
37
  ### Basic Setup
31
38
 
32
- First, import and initialize SmartNetwork:
33
-
34
39
  ```typescript
35
40
  import { SmartNetwork } from '@push.rocks/smartnetwork';
36
41
 
37
- // Basic instance
38
42
  const network = new SmartNetwork();
39
43
 
40
44
  // Start the Rust bridge (auto-started on first use, but explicit start is recommended)
@@ -42,396 +46,359 @@ await network.start();
42
46
 
43
47
  // ... use the network instance ...
44
48
 
45
- // Clean up when done (stops the Rust bridge process)
49
+ // Clean up when done
46
50
  await network.stop();
47
-
48
- // With caching enabled (60 seconds TTL)
49
- const cachedNetwork = new SmartNetwork({ cacheTtl: 60000 });
50
51
  ```
51
52
 
52
- ### 🏎️ Network Speed Testing
53
-
54
- Measure your network performance using Cloudflare's global infrastructure:
53
+ Enable caching for repeated lookups:
55
54
 
56
55
  ```typescript
57
- const speedTest = async () => {
58
- // Quick speed test
59
- const result = await network.getSpeed();
60
- console.log(`Download: ${result.downloadSpeed} Mbps`);
61
- console.log(`Upload: ${result.uploadSpeed} Mbps`);
62
-
63
- // Advanced configuration
64
- const advancedResult = await network.getSpeed({
65
- parallelStreams: 3, // Number of concurrent connections
66
- duration: 5 // Test duration in seconds
67
- });
68
- console.log(`Download: ${advancedResult.downloadSpeed} Mbps`);
69
- console.log(`Upload: ${advancedResult.uploadSpeed} Mbps`);
70
- };
56
+ const network = new SmartNetwork({ cacheTtl: 60000 }); // 60s TTL
71
57
  ```
72
58
 
73
- ### πŸ”Œ Port Management
59
+ ---
74
60
 
75
- #### Check Local Port Availability
61
+ ### πŸ•΅οΈ IP Intelligence
76
62
 
77
- Verify if a port is available on your local machine (checks both IPv4 and IPv6):
63
+ Get ASN, organization, geolocation, and RDAP registration data for any IPv4 address. Combines three free public data sources in parallel:
78
64
 
79
- ```typescript
80
- const checkLocalPort = async (port: number) => {
81
- const isUnused = await network.isLocalPortUnused(port);
82
- if (isUnused) {
83
- console.log(`βœ… Port ${port} is available`);
84
- } else {
85
- console.log(`❌ Port ${port} is in use`);
86
- }
87
- };
65
+ - **RDAP** β€” direct queries to RIRs (RIPE, ARIN, APNIC, LACNIC, AFRINIC) for authoritative registration data
66
+ - **Team Cymru DNS** β€” fast ASN resolution via DNS TXT records
67
+ - **MaxMind GeoLite2** β€” in-memory MMDB databases (auto-downloaded from CDN, periodically refreshed)
88
68
 
89
- await checkLocalPort(8080);
69
+ ```typescript
70
+ const intel = await network.getIpIntelligence('8.8.8.8');
71
+
72
+ console.log(intel);
73
+ // {
74
+ // asn: 15169,
75
+ // asnOrg: 'Google LLC',
76
+ // registrantOrg: 'Google LLC',
77
+ // registrantCountry: 'United States',
78
+ // networkRange: '8.8.8.0/24',
79
+ // abuseContact: null,
80
+ // country: null,
81
+ // countryCode: 'US',
82
+ // city: null,
83
+ // latitude: 37.751,
84
+ // longitude: -97.822,
85
+ // accuracyRadius: null,
86
+ // timezone: 'America/Chicago'
87
+ // }
90
88
  ```
91
89
 
92
- #### Find Free Port in Range
93
-
94
- Automatically discover available ports:
90
+ Works great for your own IP too:
95
91
 
96
92
  ```typescript
97
- const findFreePort = async () => {
98
- // Find a free port between 3000 and 3100 (sequential - returns first available)
99
- const freePort = await network.findFreePort(3000, 3100);
100
-
101
- if (freePort) {
102
- console.log(`πŸŽ‰ Found free port: ${freePort}`);
103
- } else {
104
- console.log('😒 No free ports available in range');
105
- }
106
-
107
- // Find a random free port in range (useful to avoid port conflicts)
108
- const randomPort = await network.findFreePort(3000, 3100, { randomize: true });
109
- console.log(`🎲 Random free port: ${randomPort}`);
110
-
111
- // Exclude specific ports from the search
112
- const portWithExclusions = await network.findFreePort(3000, 3100, {
113
- exclude: [3000, 3001, 3005] // Skip these ports even if they're free
114
- });
115
- console.log(`🚫 Free port (excluding specific ports): ${portWithExclusions}`);
116
-
117
- // Combine randomize with exclude options
118
- const randomWithExclusions = await network.findFreePort(3000, 3100, {
119
- randomize: true,
120
- exclude: [3000, 3001, 3005]
121
- });
122
- console.log(`🎲🚫 Random free port (with exclusions): ${randomWithExclusions}`);
123
- };
93
+ const publicIps = await network.getPublicIps();
94
+ if (publicIps.v4) {
95
+ const myIntel = await network.getIpIntelligence(publicIps.v4);
96
+ console.log(`You're on AS${myIntel.asn} (${myIntel.asnOrg}) in ${myIntel.city}, ${myIntel.countryCode}`);
97
+ }
124
98
  ```
125
99
 
126
- #### Check Remote Port Availability
127
-
128
- Test if services are accessible on remote servers:
100
+ The `IIpIntelligenceResult` interface:
129
101
 
130
102
  ```typescript
131
- // Method 1: Using "host:port" syntax
132
- const isOpen1 = await network.isRemotePortAvailable('example.com:443');
133
-
134
- // Method 2: Using separate host and port
135
- const isOpen2 = await network.isRemotePortAvailable('example.com', 443);
136
-
137
- // Method 3: With advanced options
138
- const isOpen3 = await network.isRemotePortAvailable('example.com', {
139
- port: 443,
140
- protocol: 'tcp', // Only TCP is supported
141
- retries: 3, // Number of connection attempts
142
- timeout: 5000 // Timeout per attempt in ms
143
- });
144
-
145
- // Note: UDP is not supported
146
- try {
147
- await network.isRemotePortAvailable('example.com', {
148
- port: 53,
149
- protocol: 'udp'
150
- });
151
- } catch (e) {
152
- console.error('UDP not supported:', e.code); // ENOTSUP
103
+ interface IIpIntelligenceResult {
104
+ // ASN (Team Cymru primary, MaxMind fallback)
105
+ asn: number | null;
106
+ asnOrg: string | null;
107
+
108
+ // Registration (RDAP)
109
+ registrantOrg: string | null;
110
+ registrantCountry: string | null;
111
+ networkRange: string | null; // CIDR or range
112
+ abuseContact: string | null; // abuse email from RDAP
113
+
114
+ // Geolocation (MaxMind GeoLite2)
115
+ country: string | null;
116
+ countryCode: string | null; // ISO 3166-1 alpha-2
117
+ city: string | null;
118
+ latitude: number | null;
119
+ longitude: number | null;
120
+ accuracyRadius: number | null; // km
121
+ timezone: string | null; // IANA timezone
153
122
  }
154
123
  ```
155
124
 
156
- ### πŸ“‘ Network Connectivity
125
+ > πŸ’‘ The GeoLite2 databases are fetched into memory from jsDelivr CDN on first use (~32 MB total). They auto-refresh in the background every 7 days (configurable via `IpIntelligence` options). No disk I/O, no API keys, no rate limits.
157
126
 
158
- #### Ping Operations
127
+ ---
159
128
 
160
- Test connectivity and measure latency:
129
+ ### 🏎️ Speed Testing
130
+
131
+ Measure network performance via Cloudflare's global infrastructure:
161
132
 
162
133
  ```typescript
163
- // Simple ping
164
- const pingResult = await network.ping('google.com');
165
- console.log(`Host alive: ${pingResult.alive}`);
166
- console.log(`RTT: ${pingResult.time} ms`);
167
-
168
- // Detailed ping statistics
169
- const pingStats = await network.ping('google.com', {
170
- count: 5, // Number of pings
171
- timeout: 1000 // Timeout per ping in ms
134
+ const result = await network.getSpeed();
135
+ console.log(`⬇️ Download: ${result.downloadSpeed} Mbps`);
136
+ console.log(`⬆️ Upload: ${result.uploadSpeed} Mbps`);
137
+
138
+ // Advanced: parallel streams + fixed duration
139
+ const advanced = await network.getSpeed({
140
+ parallelStreams: 3,
141
+ duration: 5,
172
142
  });
173
-
174
- console.log(`πŸ“Š Ping Statistics:`);
175
- console.log(` Packet loss: ${pingStats.packetLoss}%`);
176
- console.log(` Min: ${pingStats.min} ms`);
177
- console.log(` Max: ${pingStats.max} ms`);
178
- console.log(` Avg: ${pingStats.avg.toFixed(2)} ms`);
179
- console.log(` Stddev: ${pingStats.stddev.toFixed(2)} ms`);
180
143
  ```
181
144
 
182
- #### Traceroute
183
-
184
- Analyze network paths hop-by-hop:
145
+ ---
185
146
 
186
- ```typescript
187
- const hops = await network.traceroute('google.com', {
188
- maxHops: 10, // Maximum number of hops
189
- timeout: 5000 // Timeout in ms
190
- });
147
+ ### πŸ”Œ Port Management
191
148
 
192
- console.log('πŸ›€οΈ Route to destination:');
193
- hops.forEach(hop => {
194
- const rtt = hop.rtt === null ? '*' : `${hop.rtt} ms`;
195
- console.log(` ${hop.ttl}\t${hop.ip}\t${rtt}`);
196
- });
197
- ```
149
+ #### Check Local Port Availability
198
150
 
199
- *Note: Falls back to a single-hop stub if the `traceroute` binary is unavailable.*
151
+ Checks both IPv4 and IPv6:
200
152
 
201
- ### 🌍 DNS Operations
153
+ ```typescript
154
+ const isUnused = await network.isLocalPortUnused(8080);
155
+ console.log(isUnused ? 'βœ… Port 8080 is free' : '❌ Port 8080 is in use');
156
+ ```
202
157
 
203
- Resolve various DNS record types using @push.rocks/smartdns with intelligent resolution strategy:
158
+ #### Find Free Port in Range
204
159
 
205
160
  ```typescript
206
- const dnsRecords = await network.resolveDns('example.com');
161
+ // First available
162
+ const port = await network.findFreePort(3000, 3100);
207
163
 
208
- console.log('πŸ” DNS Records:');
209
- console.log(' A records:', dnsRecords.A); // IPv4 addresses
210
- console.log(' AAAA records:', dnsRecords.AAAA); // IPv6 addresses
164
+ // Random pick (avoids clustering)
165
+ const randomPort = await network.findFreePort(3000, 3100, { randomize: true });
211
166
 
212
- // MX records include priority
213
- dnsRecords.MX.forEach(mx => {
214
- console.log(` πŸ“§ Mail server: ${mx.exchange} (priority: ${mx.priority})`);
167
+ // With exclusions
168
+ const port2 = await network.findFreePort(3000, 3100, {
169
+ randomize: true,
170
+ exclude: [3000, 3001, 3005],
215
171
  });
216
-
217
- // Properly handles local hostnames (localhost, etc.)
218
- const localDns = await network.resolveDns('localhost');
219
- console.log(' Localhost:', localDns.A); // Returns ['127.0.0.1']
220
172
  ```
221
173
 
222
- *DNS resolution uses a `prefer-system` strategy: tries system resolver first (respects /etc/hosts and local DNS), with automatic fallback to Cloudflare DoH for external domains.*
223
-
224
- ### πŸ₯ HTTP/HTTPS Health Checks
225
-
226
- Monitor endpoint availability and response times:
174
+ #### Check Remote Port
227
175
 
228
176
  ```typescript
229
- const health = await network.checkEndpoint('https://api.example.com/health', {
230
- timeout: 5000 // Request timeout in ms
231
- });
177
+ // Simple
178
+ const isOpen = await network.isRemotePortAvailable('example.com', 443);
232
179
 
233
- console.log(`🩺 Endpoint Health:`);
234
- console.log(` Status: ${health.status}`);
235
- console.log(` RTT: ${health.rtt} ms`);
236
- console.log(` Headers:`, health.headers);
180
+ // With retries and timeout
181
+ const isOpen2 = await network.isRemotePortAvailable('example.com', {
182
+ port: 443,
183
+ retries: 3,
184
+ timeout: 5000,
185
+ });
237
186
  ```
238
187
 
239
- ### πŸ–₯️ Network Interface Information
188
+ ---
240
189
 
241
- #### Get All Network Interfaces
242
-
243
- List all network adapters on the system:
190
+ ### πŸ“‘ Ping & Traceroute
244
191
 
245
192
  ```typescript
246
- const gateways = await network.getGateways();
193
+ // Simple ping
194
+ const ping = await network.ping('google.com');
195
+ console.log(`Alive: ${ping.alive}, RTT: ${ping.time} ms`);
247
196
 
248
- Object.entries(gateways).forEach(([name, interfaces]) => {
249
- console.log(`πŸ”Œ Interface: ${name}`);
250
- interfaces.forEach(iface => {
251
- console.log(` ${iface.family}: ${iface.address}`);
252
- console.log(` Netmask: ${iface.netmask}`);
253
- console.log(` MAC: ${iface.mac}`);
254
- });
197
+ // Multi-ping with statistics
198
+ const stats = await network.ping('google.com', { count: 10, timeout: 2000 });
199
+ console.log(`πŸ“Š min=${stats.min} avg=${stats.avg.toFixed(1)} max=${stats.max} loss=${stats.packetLoss}%`);
200
+
201
+ // Traceroute
202
+ const hops = await network.traceroute('google.com', { maxHops: 20 });
203
+ hops.forEach(hop => {
204
+ const rtt = hop.rtt === null ? '*' : `${hop.rtt} ms`;
205
+ console.log(` ${hop.ttl}\t${hop.ip}\t${rtt}`);
255
206
  });
256
207
  ```
257
208
 
258
- #### Get Default Gateway
209
+ > ⚠️ ICMP ping requires `CAP_NET_RAW` or appropriate `ping_group_range` sysctl on Linux.
259
210
 
260
- Retrieve the primary network interface:
211
+ ---
261
212
 
262
- ```typescript
263
- const defaultGateway = await network.getDefaultGateway();
213
+ ### 🌍 DNS Resolution
264
214
 
265
- if (defaultGateway) {
266
- console.log('🌐 Default Gateway:');
267
- console.log(' IPv4:', defaultGateway.ipv4.address);
268
- console.log(' IPv6:', defaultGateway.ipv6.address);
269
- }
215
+ Uses `@push.rocks/smartdns` with a system-first strategy and automatic DoH (DNS-over-HTTPS) fallback:
216
+
217
+ ```typescript
218
+ const dns = await network.resolveDns('example.com');
219
+ console.log('A records:', dns.A); // ['93.184.216.34']
220
+ console.log('AAAA records:', dns.AAAA); // ['2606:2800:220:1:248:1893:25c8:1946']
221
+ dns.MX.forEach(mx => {
222
+ console.log(`πŸ“§ ${mx.exchange} (priority ${mx.priority})`);
223
+ });
270
224
  ```
271
225
 
272
- ### 🌎 Public IP Discovery
226
+ ---
273
227
 
274
- Discover your public-facing IP addresses:
228
+ ### πŸ₯ HTTP/HTTPS Health Checks
275
229
 
276
230
  ```typescript
277
- const publicIps = await network.getPublicIps();
278
-
279
- console.log(`🌍 Public IPs:`);
280
- console.log(` IPv4: ${publicIps.v4 || 'Not available'}`);
281
- console.log(` IPv6: ${publicIps.v6 || 'Not available'}`);
231
+ const health = await network.checkEndpoint('https://api.example.com/health', {
232
+ timeout: 5000,
233
+ rejectUnauthorized: true,
234
+ });
235
+ console.log(`Status: ${health.status}, RTT: ${health.rtt.toFixed(0)} ms`);
282
236
  ```
283
237
 
284
- ### ⚑ Performance Caching
238
+ ---
285
239
 
286
- Reduce network calls with built-in caching:
240
+ ### πŸ–₯️ Network Interfaces & Public IPs
287
241
 
288
242
  ```typescript
289
- // Create instance with 60-second cache TTL
290
- const cachedNetwork = new SmartNetwork({ cacheTtl: 60000 });
243
+ // All interfaces
244
+ const gateways = await network.getGateways();
245
+ Object.entries(gateways).forEach(([name, ifaces]) => {
246
+ console.log(`πŸ”Œ ${name}:`);
247
+ ifaces.forEach(i => console.log(` ${i.family}: ${i.address}`));
248
+ });
291
249
 
292
- // First call fetches from network
293
- const gateways1 = await cachedNetwork.getGateways();
294
- const publicIps1 = await cachedNetwork.getPublicIps();
250
+ // Default gateway
251
+ const gw = await network.getDefaultGateway();
252
+ if (gw) {
253
+ console.log(`🌐 Gateway IPv4: ${gw.ipv4.address}`);
254
+ }
295
255
 
296
- // Subsequent calls within 60 seconds use cache
297
- const gateways2 = await cachedNetwork.getGateways(); // From cache ⚑
298
- const publicIps2 = await cachedNetwork.getPublicIps(); // From cache ⚑
256
+ // Public IPs (multiple fallback services: ipify, ident.me, seeip, icanhazip)
257
+ const publicIps = await network.getPublicIps();
258
+ console.log(`🌍 IPv4: ${publicIps.v4 || 'N/A'}`);
259
+ console.log(`🌍 IPv6: ${publicIps.v6 || 'N/A'}`);
299
260
  ```
300
261
 
301
- ### πŸ”§ Plugin Architecture
262
+ ---
302
263
 
303
- Extend SmartNetwork with custom functionality:
264
+ ### ⚑ Caching
304
265
 
305
- ```typescript
306
- // Define your plugin
307
- class CustomNetworkPlugin {
308
- constructor(private smartNetwork: SmartNetwork) {}
309
-
310
- async customMethod() {
311
- // Your custom network logic here
312
- return 'Custom result';
313
- }
314
- }
315
-
316
- // Register the plugin
317
- SmartNetwork.registerPlugin('customPlugin', CustomNetworkPlugin);
266
+ Caching applies to `getGateways()`, `getPublicIps()`, and `getIpIntelligence()`:
318
267
 
319
- // Use the plugin
320
- const network = new SmartNetwork();
321
- const PluginClass = SmartNetwork.pluginsRegistry.get('customPlugin');
322
- const plugin = new PluginClass(network);
323
- await plugin.customMethod();
268
+ ```typescript
269
+ const network = new SmartNetwork({ cacheTtl: 60000 }); // 60s
324
270
 
325
- // Clean up when done
326
- SmartNetwork.unregisterPlugin('customPlugin');
271
+ const ips1 = await network.getPublicIps(); // fetches
272
+ const ips2 = await network.getPublicIps(); // cache hit ⚑
327
273
  ```
328
274
 
329
- ### 🚨 Error Handling
275
+ ---
330
276
 
331
- Handle network errors gracefully with custom error types:
277
+ ### 🚨 Error Handling
332
278
 
333
279
  ```typescript
334
- import { NetworkError } from '@push.rocks/smartnetwork';
280
+ import { SmartNetwork, NetworkError, TimeoutError } from '@push.rocks/smartnetwork';
335
281
 
336
282
  try {
337
283
  await network.isRemotePortAvailable('example.com', { protocol: 'udp' });
338
284
  } catch (error) {
339
285
  if (error instanceof NetworkError) {
340
- console.error(`❌ Network error: ${error.message}`);
341
- console.error(` Error code: ${error.code}`);
286
+ console.error(`${error.message} (code: ${error.code})`); // ENOTSUP
342
287
  }
343
288
  }
344
289
  ```
345
290
 
346
- ### πŸ“š TypeScript Support
291
+ Error codes: `EINVAL` (invalid argument), `ENOTSUP` (not supported), `ETIMEOUT` (timeout).
347
292
 
348
- This package is written in TypeScript and provides comprehensive type definitions:
293
+ ---
294
+
295
+ ### πŸ”§ Plugin Architecture
349
296
 
350
297
  ```typescript
351
- interface SmartNetworkOptions {
352
- cacheTtl?: number; // Cache TTL in milliseconds
298
+ class MyPlugin {
299
+ constructor(private network: SmartNetwork) {}
300
+ async doStuff() { /* ... */ }
353
301
  }
354
302
 
355
- interface IFindFreePortOptions {
356
- randomize?: boolean; // If true, returns a random free port instead of the first one
357
- exclude?: number[]; // Array of port numbers to exclude from the search
358
- }
303
+ SmartNetwork.registerPlugin('myPlugin', MyPlugin);
359
304
 
360
- interface Hop {
361
- ttl: number; // Time to live
362
- ip: string; // IP address of the hop
363
- rtt: number | null; // Round trip time in ms
364
- }
305
+ const PluginClass = SmartNetwork.pluginsRegistry.get('myPlugin');
306
+ const plugin = new PluginClass(network);
307
+ await plugin.doStuff();
365
308
 
366
- // ... and many more types for complete type safety
309
+ SmartNetwork.unregisterPlugin('myPlugin');
367
310
  ```
368
311
 
369
- ## πŸ› οΈ Advanced Examples
312
+ ---
370
313
 
371
- ### Building a Network Monitor
314
+ ### πŸ“ Custom Logging
315
+
316
+ Replace the default `console` logger:
372
317
 
373
318
  ```typescript
374
- const monitorNetwork = async () => {
319
+ import { setLogger } from '@push.rocks/smartnetwork';
320
+
321
+ setLogger({
322
+ debug: (msg) => myLogger.debug(msg),
323
+ info: (msg) => myLogger.info(msg),
324
+ warn: (msg) => myLogger.warn(msg),
325
+ error: (msg) => myLogger.error(msg),
326
+ });
327
+ ```
328
+
329
+ ---
330
+
331
+ ## πŸ› οΈ Advanced Example: Network Monitor
332
+
333
+ ```typescript
334
+ const monitor = async () => {
375
335
  const network = new SmartNetwork({ cacheTtl: 30000 });
376
-
336
+
377
337
  // Check critical services
378
338
  const services = [
379
- { name: 'Web Server', host: 'example.com', port: 443 },
380
- { name: 'Database', host: 'db.internal', port: 5432 },
381
- { name: 'Cache', host: 'redis.internal', port: 6379 }
339
+ { name: 'Web', host: 'example.com', port: 443 },
340
+ { name: 'DB', host: 'db.internal', port: 5432 },
382
341
  ];
383
-
384
- for (const service of services) {
385
- const isUp = await network.isRemotePortAvailable(service.host, service.port);
386
- console.log(`${service.name}: ${isUp ? 'βœ… UP' : '❌ DOWN'}`);
342
+
343
+ for (const svc of services) {
344
+ const up = await network.isRemotePortAvailable(svc.host, svc.port);
345
+ console.log(`${svc.name}: ${up ? 'βœ… UP' : '❌ DOWN'}`);
387
346
  }
388
-
389
- // Check internet connectivity
390
- const ping = await network.ping('8.8.8.8');
391
- console.log(`Internet: ${ping.alive ? 'βœ… Connected' : '❌ Disconnected'}`);
392
-
393
- // Measure network performance
394
- const speed = await network.getSpeed();
395
- console.log(`Speed: ⬇️ ${speed.downloadSpeed} Mbps / ⬆️ ${speed.uploadSpeed} Mbps`);
396
- };
397
347
 
398
- // Run monitor every minute
399
- setInterval(monitorNetwork, 60000);
400
- ```
348
+ // Internet connectivity + latency
349
+ const ping = await network.ping('8.8.8.8');
350
+ console.log(`Internet: ${ping.alive ? 'βœ…' : '❌'} (${ping.time} ms)`);
401
351
 
402
- ### Service Discovery
352
+ // Speed
353
+ const speed = await network.getSpeed();
354
+ console.log(`Speed: ⬇️ ${speed.downloadSpeed} / ⬆️ ${speed.uploadSpeed} Mbps`);
403
355
 
404
- ```typescript
405
- const discoverServices = async () => {
406
- const network = new SmartNetwork();
407
- const commonPorts = [22, 80, 443, 3000, 3306, 5432, 6379, 8080, 9200];
408
-
409
- console.log('πŸ” Scanning local services...');
410
-
411
- for (const port of commonPorts) {
412
- const isUsed = !(await network.isLocalPortUnused(port));
413
- if (isUsed) {
414
- console.log(` Port ${port}: In use (possible service running)`);
415
- }
356
+ // Who am I?
357
+ const ips = await network.getPublicIps();
358
+ if (ips.v4) {
359
+ const intel = await network.getIpIntelligence(ips.v4);
360
+ console.log(`AS${intel.asn} (${intel.asnOrg}) β€” ${intel.city || intel.countryCode}`);
416
361
  }
362
+
363
+ await network.stop();
417
364
  };
418
365
  ```
419
366
 
367
+ ## πŸ“‹ Full API Reference
368
+
369
+ | Method | Description | Requires Rust |
370
+ |--------|-------------|:---:|
371
+ | `start()` / `stop()` | Start/stop the Rust binary bridge | β€” |
372
+ | `getSpeed(opts?)` | Cloudflare speed test (download + upload) | No |
373
+ | `ping(host, opts?)` | ICMP ping with optional multi-ping stats | Yes |
374
+ | `traceroute(host, opts?)` | Hop-by-hop network path analysis | Yes |
375
+ | `isLocalPortUnused(port)` | Check if local port is free (IPv4+IPv6) | Yes |
376
+ | `findFreePort(start, end, opts?)` | Find available port in range | Yes |
377
+ | `isRemotePortAvailable(target, opts?)` | TCP port check on remote host | Yes |
378
+ | `getGateways()` | List all network interfaces | No |
379
+ | `getDefaultGateway()` | Get default gateway info | Yes |
380
+ | `getPublicIps()` | Discover public IPv4/IPv6 (4 fallback services) | No |
381
+ | `resolveDns(host)` | Resolve A, AAAA, MX records | No |
382
+ | `checkEndpoint(url, opts?)` | HTTP/HTTPS health check with RTT | No |
383
+ | `getIpIntelligence(ip)` | ASN + org + geo + RDAP registration | No |
384
+
420
385
  ## License and Legal Information
421
386
 
422
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
387
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
423
388
 
424
389
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
425
390
 
426
391
  ### Trademarks
427
392
 
428
- This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
393
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
394
+
395
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
429
396
 
430
397
  ### Company Information
431
398
 
432
- Task Venture Capital GmbH
433
- Registered at District court Bremen HRB 35230 HB, Germany
399
+ Task Venture Capital GmbH
400
+ Registered at District Court Bremen HRB 35230 HB, Germany
434
401
 
435
- For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
402
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
436
403
 
437
- By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
404
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartnetwork',
6
- version: '4.5.1',
6
+ version: '4.5.2',
7
7
  description: 'A toolkit for network diagnostics including speed tests, port availability checks, and more.'
8
8
  }