Files
smartnetwork/readme.md
Juergen Kunz d1ab85cbb3
Some checks failed
Default (tags) / security (push) Successful in 46s
Default (tags) / test (push) Failing after 6m10s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
feat(port-management): add findFreePort method for automatic port discovery within a range
2025-07-31 22:04:20 +00:00

9.4 KiB

@push.rocks/smartnetwork

Comprehensive network diagnostics and utilities for Node.js applications

Install

To install @push.rocks/smartnetwork, run the following command in your terminal:

npm install @push.rocks/smartnetwork --save

Usage

The @push.rocks/smartnetwork package provides a comprehensive suite of network diagnostic tools including speed tests, port availability checks, ping operations, DNS resolution, HTTP endpoint health checks, and more.

Basic Setup

First, import the package into your project:

import { SmartNetwork } from '@push.rocks/smartnetwork';

Then, create an instance of SmartNetwork:

const myNetwork = new SmartNetwork();

// Or with caching enabled (60 seconds TTL)
const myNetworkCached = new SmartNetwork({ cacheTtl: 60000 });

Network Speed Testing

Measure network download and upload speeds using Cloudflare's speed test infrastructure:

const speedTest = async () => {
  // Basic speed test
  const result = await myNetwork.getSpeed();
  console.log(`Download: ${result.downloadSpeed} Mbps`);
  console.log(`Upload: ${result.uploadSpeed} Mbps`);

  // Advanced speed test with options
  const advancedResult = await myNetwork.getSpeed({ 
    parallelStreams: 3,  // Number of concurrent connections
    duration: 5          // Test duration in seconds
  });
  console.log(`Download: ${advancedResult.downloadSpeed} Mbps`);
  console.log(`Upload: ${advancedResult.uploadSpeed} Mbps`);
};

Port Management

Check Local Port Availability

Verify if a specific port is available on your local machine (checks both IPv4 and IPv6):

const checkLocalPort = async (port: number) => {
  const isUnused = await myNetwork.isLocalPortUnused(port);
  if (isUnused) {
    console.log(`Port ${port} is available`);
  } else {
    console.log(`Port ${port} is in use`);
  }
};

await checkLocalPort(8080);

Find Free Port in Range

Automatically find the first available port within a specified range:

const findFreePort = async () => {
  // Find a free port between 3000 and 3100
  const freePort = await myNetwork.findFreePort(3000, 3100);
  
  if (freePort) {
    console.log(`Found free port: ${freePort}`);
  } else {
    console.log('No free ports available in the specified range');
  }
};

Check Remote Port Availability

Verify if a port is open on a remote server:

// Method 1: Using "host:port" syntax
const isOpen1 = await myNetwork.isRemotePortAvailable('example.com:443');

// Method 2: Using separate host and port
const isOpen2 = await myNetwork.isRemotePortAvailable('example.com', 443);

// Method 3: With options (retries, timeout)
const isOpen3 = await myNetwork.isRemotePortAvailable('example.com', {
  port: 443,
  protocol: 'tcp',     // Only TCP is supported
  retries: 3,          // Number of connection attempts
  timeout: 5000        // Timeout per attempt in ms
});

// Note: UDP is not supported and will throw an error
try {
  await myNetwork.isRemotePortAvailable('example.com', { 
    port: 53, 
    protocol: 'udp' 
  });
} catch (e) {
  console.error(e.code); // ENOTSUP
}

Network Connectivity

Ping Operations

Send ICMP echo requests to test connectivity and measure latency:

// Simple ping
const pingResult = await myNetwork.ping('google.com');
console.log(`Host alive: ${pingResult.alive}`);
console.log(`RTT: ${pingResult.time} ms`);

// Ping with statistics (multiple pings)
const pingStats = await myNetwork.ping('google.com', { 
  count: 5,          // Number of pings
  timeout: 1000      // Timeout per ping in ms
});

console.log(`Packet loss: ${pingStats.packetLoss}%`);
console.log(`Min: ${pingStats.min} ms`);
console.log(`Max: ${pingStats.max} ms`);
console.log(`Avg: ${pingStats.avg.toFixed(2)} ms`);
console.log(`Stddev: ${pingStats.stddev.toFixed(2)} ms`);

Traceroute

Perform hop-by-hop network path analysis:

const hops = await myNetwork.traceroute('google.com', { 
  maxHops: 10,      // Maximum number of hops
  timeout: 5000     // Timeout in ms
});

hops.forEach(hop => {
  const rtt = hop.rtt === null ? '*' : `${hop.rtt} ms`;
  console.log(`${hop.ttl}\t${hop.ip}\t${rtt}`);
});

Note: Falls back to a single-hop stub if the traceroute binary is unavailable on the system.

DNS Operations

Resolve DNS records for a hostname:

const dnsRecords = await myNetwork.resolveDns('example.com');

console.log('A records:', dnsRecords.A);        // IPv4 addresses
console.log('AAAA records:', dnsRecords.AAAA);  // IPv6 addresses
console.log('MX records:', dnsRecords.MX);      // Mail servers

// MX records include priority
dnsRecords.MX.forEach(mx => {
  console.log(`Mail server: ${mx.exchange} (priority: ${mx.priority})`);
});

HTTP/HTTPS Endpoint Health Checks

Check the health and response time of HTTP/HTTPS endpoints:

const health = await myNetwork.checkEndpoint('https://example.com', {
  timeout: 5000  // Request timeout in ms
});

console.log(`Status: ${health.status}`);
console.log(`RTT: ${health.rtt} ms`);
console.log('Headers:', health.headers);

Network Interface Information

Get Network Gateways

List all network interfaces on the system:

const gateways = await myNetwork.getGateways();

Object.entries(gateways).forEach(([name, interfaces]) => {
  console.log(`Interface: ${name}`);
  interfaces.forEach(iface => {
    console.log(`  ${iface.family}: ${iface.address}`);
    console.log(`  Netmask: ${iface.netmask}`);
    console.log(`  MAC: ${iface.mac}`);
  });
});

Get Default Gateway

Retrieve the system's default network gateway:

const defaultGateway = await myNetwork.getDefaultGateway();

if (defaultGateway) {
  console.log('IPv4 Gateway:', defaultGateway.ipv4.address);
  console.log('IPv6 Gateway:', defaultGateway.ipv6.address);
}

Public IP Discovery

Discover your public IPv4 and IPv6 addresses:

const publicIps = await myNetwork.getPublicIps();

console.log(`Public IPv4: ${publicIps.v4 || 'Not available'}`);
console.log(`Public IPv6: ${publicIps.v6 || 'Not available'}`);

Caching

SmartNetwork supports caching for gateway and public IP lookups to reduce repeated network calls:

// Create instance with 60-second cache TTL
const cachedNetwork = new SmartNetwork({ cacheTtl: 60000 });

// These calls will use cached results if called within 60 seconds
const gateways1 = await cachedNetwork.getGateways();
const publicIps1 = await cachedNetwork.getPublicIps();

// Subsequent calls within TTL return cached results
const gateways2 = await cachedNetwork.getGateways();    // From cache
const publicIps2 = await cachedNetwork.getPublicIps();  // From cache

Plugin Architecture

Extend SmartNetwork's functionality with custom plugins:

// Define your plugin
class CustomNetworkPlugin {
  constructor(private smartNetwork: SmartNetwork) {}
  
  async customMethod() {
    // Your custom network functionality
  }
}

// Register the plugin
SmartNetwork.registerPlugin('customPlugin', CustomNetworkPlugin);

// Use the plugin
const network = new SmartNetwork();
const plugin = new (SmartNetwork.pluginsRegistry.get('customPlugin'))(network);
await plugin.customMethod();

// Unregister when no longer needed
SmartNetwork.unregisterPlugin('customPlugin');

Error Handling

The package uses custom NetworkError class for network-related errors:

import { NetworkError } from '@push.rocks/smartnetwork';

try {
  await myNetwork.isRemotePortAvailable('example.com', { protocol: 'udp' });
} catch (error) {
  if (error instanceof NetworkError) {
    console.error(`Network error: ${error.message}`);
    console.error(`Error code: ${error.code}`);
  }
}

TypeScript Support

This package is written in TypeScript and provides full type definitions. Key interfaces include:

interface SmartNetworkOptions {
  cacheTtl?: number;  // Cache TTL in milliseconds
}

interface Hop {
  ttl: number;        // Time to live
  ip: string;         // IP address of the hop
  rtt: number | null; // Round trip time in ms
}

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 file within this repository.

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.

Trademarks

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.

Company Information

Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany

For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.

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.