0.2.0 • Published 1 month ago

@synet/net v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

@synet/net

A robust network abstraction library for WireGuard management with strong error handling, supporting both local wireguard-tools and the synetd API.

Installation

npm install @synet/net

Usage

Basic Usage with Result Pattern

import { createWireguardService, AdapterType, Result } from '@synet/net';

// Create a WireGuard service using the synetd adapter (default)
const wireguardService = createWireguardService();

// Or use wireguard-tools adapter
const wireguardService = createWireguardService(AdapterType.WIREGUARD_TOOLS);

async function setupConnection() {
  // Generate keys with Result pattern
  const keysResult = await wireguardService.generateKeys();
  
  if (keysResult.isFailure) {
    console.error(`Error generating keys: ${keysResult.error?.message}`);
    return;
  }
  
  const keys = keysResult.value;
  
  // Configure interface
  const interfaceResult = await wireguardService.setInterface({
    privateKey: keys.privateKey,
    address: '10.0.0.2/32'
  });
  
  if (interfaceResult.isFailure) {
    console.error(`Error configuring interface: ${interfaceResult.error?.message}`);
    return;
  }
  
  // Add peer
  const peerResult = await wireguardService.addPeer({
    publicKey: 'PEER_PUBLIC_KEY',
    endpoint: 'peer.example.com:51820',
    allowedIPs: ['10.0.0.0/24'],
    persistentKeepalive: 25
  });
  
  if (peerResult.isFailure) {
    console.error(`Error adding peer: ${peerResult.error?.message}`);
    return;
  }
  
  // Bring up interface
  const upResult = await wireguardService.bringUp();
  
  if (upResult.isFailure) {
    console.error(`Error bringing up interface: ${upResult.error?.message}`);
    return;
  }
  
  console.log('Successfully connected to WireGuard network');
}

// Later, to disconnect
async function disconnect() {
  const result = await wireguardService.bringDown();
  if (result.isFailure) {
    console.error(`Error bringing down interface: ${result.error?.message}`);
  } else {
    console.log('Successfully disconnected');
  }
}

Complete Connection Example

Complete Connection Example with Error Handling

import { createWireguardService, AdapterType, NetworkError } from '@synet/net';

async function connect() {
  try {
    const wireguardService = createWireguardService();
  
    // Get existing keys or generate new ones
    const keysResult = await wireguardService.getKeys();
  
    let keys;
    if (keysResult.isSuccess && keysResult.value) {
      keys = keysResult.value;
    } else {
      const newKeysResult = await wireguardService.generateKeys();
      if (newKeysResult.isFailure) {
        throw new Error(`Failed to generate keys: ${newKeysResult.error?.message}`);
      }
      keys = newKeysResult.value;
    }
  
    // Connect in one go
    const connectResult = await wireguardService.connect({
      privateKey: keys.privateKey,
      address: '10.0.0.2/32',
      peer: {
        publicKey: 'GATEWAY_PUBLIC_KEY',
        endpoint: 'gateway.example.com:51820',
        allowedIPs: ['10.0.0.0/24'],
        persistentKeepalive: 25
      }
    });
  
    if (connectResult.isFailure) {
      throw connectResult.error;
    }
  
    console.log('Connected to WireGuard network');
  } catch (error) {
    if (error instanceof NetworkError) {
      console.error(`Network error: ${error.message}`);
    } else {
      console.error(`Unexpected error: ${error.message}`);
    }
  }
}

connect();

With Custom Logger

import { createWireguardService, AdapterType, ConsoleLogger } from '@synet/net';

// Create a custom logger
const logger = new ConsoleLogger('MyWireguardService');

// Pass the logger to the service factory
const wireguardService = createWireguardService(AdapterType.WIREGUARD_TOOLS, {}, logger);

Architecture

This package follows clean architecture principles with additional improvements:

Domain Layer:

  • Entities and interfaces with immutable properties
  • Well-defined error types for better error handling
  • Result pattern to handle operation outcomes
  • Repository interfaces for data access

Application Layer:

  • Use cases and business logic
  • WireguardService with proper error handling

Infrastructure Layer:

  • Implementations of interfaces (adapters)
  • File system and command execution abstractions
  • Repository implementations
  • Logging capabilities

Error Handling

The package uses a simplified Result pattern with enum-based error types for improved error handling:

Basic Error Handling

const result = await wireguardService.addPeer(peerConfig);

if (result.isSuccess) {
  // Operation succeeded
  console.log("Peer added successfully");
} else {
  // Operation failed with typed errors
  console.error(`Failed to add peer: ${result.errorMessage}`);
  
  // You can check the error type
  if (result.errorType === ErrorType.PEER) {
    console.error("There was an issue with the peer configuration");
  } else if (result.errorType === ErrorType.CONNECTION) {
    console.error("There was a connection problem");
  }
}

Using Helper Methods

await wireguardService.connect(config)
  .onSuccess(() => {
    console.log("Connected successfully!");
  })
  .onFailure((type, message, cause) => {
    switch (type) {
      case ErrorType.INTERFACE:
        console.error(`Interface error: ${message}`);
        break;
      case ErrorType.PEER:
        console.error(`Peer error: ${message}`);
        break;
      default:
        console.error(`Error: ${message}`);
    }
    
    // The cause parameter provides the original error (if available)
    if (cause) {
      console.debug("Original error:", cause);
    }
  });

Functional Transformation

You can transform successful results using the map method:

const keysResult = await wireguardService.generateKeys();
const publicKeyResult = keysResult.map(keys => keys.publicKey);

if (publicKeyResult.isSuccess) {
  console.log(`Generated public key: ${publicKeyResult.value}`);
}

Available Error Types

The package provides these error types for better categorization:

enum ErrorType {
  KEYS = 'keys',           // Key generation or management issues
  INTERFACE = 'interface', // Interface configuration problems
  PEER = 'peer',           // Peer-related issues
  CONNECTION = 'connection', // Network connection problems
  UNKNOWN = 'unknown'      // Unspecified errors
}

License

MIT

0.2.0

1 month ago

0.1.8

2 months ago

0.1.5

2 months ago

0.1.4

2 months ago

0.1.3

2 months ago

0.1.2

2 months ago

0.1.1

2 months ago

0.1.0

2 months ago