UNPKG

matterbridge

Version:
212 lines • 8.25 kB
/** * This file contains the network function. * * @file network.ts * @author Luca Liguori * @date 2024-02-17 * @version 1.0.0 * * Copyright 2024, 2025, 2026 Luca Liguori. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ // Node.js modules import os from 'node:os'; // AnsiLogger module import { AnsiLogger, idn, rs } from '../logger/export.js'; /** * Retrieves the IPv4 address of the first non-internal network interface. * @returns {string | undefined} The IPv4 address of the selected network interface, or undefined if not found. */ export function getIpv4InterfaceAddress() { let ipv4Address; const networkInterfaces = os.networkInterfaces(); // console.log('Available Network Interfaces:', networkInterfaces); for (const interfaceDetails of Object.values(networkInterfaces)) { if (!interfaceDetails) { break; } for (const detail of interfaceDetails) { if (detail.family === 'IPv4' && !detail.internal && ipv4Address === undefined) { ipv4Address = detail.address; } } if (ipv4Address !== undefined) { break; } } // console.log('Selected Network Interfaces:', ipv4Address); return ipv4Address; } /** * Retrieves the IPv6 address of the first non-internal network interface. * @returns {string | undefined} The IPv4 address of the selected network interface, or undefined if not found. */ export function getIpv6InterfaceAddress() { let ipv6Address; const networkInterfaces = os.networkInterfaces(); // console.log('Available Network Interfaces:', networkInterfaces); for (const interfaceDetails of Object.values(networkInterfaces)) { if (!interfaceDetails) { break; } for (const detail of interfaceDetails) { if (detail.family === 'IPv6' && !detail.internal && ipv6Address === undefined) { ipv6Address = detail.address; } } if (ipv6Address !== undefined) { break; } } // console.log('Selected Network Interfaces:', ipv6Address); return ipv6Address; } /** * Retrieves the mac address of the first non-internal network interface. * @returns {string | undefined} The IPv4 address of the selected network interface, or undefined if not found. */ export function getMacAddress() { let macAddress; const networkInterfaces = os.networkInterfaces(); // console.log('Available Network Interfaces:', networkInterfaces); for (const interfaceDetails of Object.values(networkInterfaces)) { if (!interfaceDetails) { break; } for (const detail of interfaceDetails) { if (detail.family === 'IPv6' && !detail.internal && macAddress === undefined) { macAddress = detail.mac; } } if (macAddress !== undefined) { break; } } return macAddress; } /** * Logs the available network interfaces and their details. * @param {boolean} log - Whether to enable logging of network interface details. */ export function logInterfaces(debug = true) { const log = new AnsiLogger({ logName: 'MatterbridgeUtils', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "info" /* LogLevel.INFO */ }); log.logLevel = "info" /* LogLevel.INFO */; log.logName = 'LogInterfaces'; const networkInterfaces = os.networkInterfaces(); if (debug) log.info('Available Network Interfaces:'); for (const [interfaceName, networkInterface] of Object.entries(networkInterfaces)) { if (!networkInterface) break; if (debug) log.info(`Interface: ${idn}${interfaceName}${rs}`); for (const detail of networkInterface) { if (debug) log.info('Details:', detail); } } } /** * Resolves the given hostname to an IP address. * * @param {string} hostname - The hostname to resolve. * @param {0 | 4 | 6} [family=4] - The address family to use (0 for any, 4 for IPv4, 6 for IPv6). Default is 4. * @returns {Promise<string | null>} - A promise that resolves to the IP address or null if not found. * * @remarks * This function uses DNS lookup to resolve the hostname, which can take some time to complete. */ export async function resolveHostname(hostname, family = 4) { const dns = await import('node:dns'); try { const addresses = await dns.promises.lookup(hostname.toLowerCase() /* + '.local'*/, { family }); return addresses.address; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (error) { return null; } } /** * Retrieves the version of an npm package from the npm registry. * * @param {string} packageName - The name of the npm package. * @param {string} [tag='latest'] - The tag of the package version to retrieve (default is 'latest'). * @param {number} [timeout=5000] - The timeout duration in milliseconds (default is 5000ms). * @returns {Promise<string>} A promise that resolves to the version string of the package. * @throws {Error} If the request fails or the tag is not found. */ export async function getNpmPackageVersion(packageName, tag = 'latest', timeout = 10000) { const https = await import('https'); return new Promise((resolve, reject) => { const url = `https://registry.npmjs.org/${packageName}`; const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(); reject(new Error(`Request timed out after ${timeout / 1000} seconds`)); }, timeout); const req = https.get(url, { signal: controller.signal }, (res) => { let data = ''; if (res.statusCode !== 200) { clearTimeout(timeoutId); res.resume(); // Discard response data to close the socket properly req.destroy(); // Forcefully close the request reject(new Error(`Failed to fetch data. Status code: ${res.statusCode}`)); return; } res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { clearTimeout(timeoutId); try { const jsonData = JSON.parse(data); // console.log(`Package ${packageName} tag ${tag}`, jsonData); const version = jsonData['dist-tags']?.[tag]; if (version) { resolve(version); } else { reject(new Error(`Tag "${tag}" not found for package "${packageName}"`)); } } catch (error) { reject(new Error(`Failed to parse response JSON: ${error instanceof Error ? error.message : error}`)); } }); }); req.on('error', (error) => { clearTimeout(timeoutId); reject(new Error(`Request failed: ${error instanceof Error ? error.message : error}`)); }); }); } /** * Retrieves the path to the global Node.js modules directory. * @returns A promise that resolves to the path of the global Node.js modules directory. */ export async function getGlobalNodeModules() { const { exec } = await import('node:child_process'); return new Promise((resolve, reject) => { exec('npm root -g', (error, stdout) => { if (error) { reject(error); } else { resolve(stdout.trim()); } }); }); } //# sourceMappingURL=network.js.map