UNPKG

@oxog/port-terminator

Version:

Cross-platform utility to terminate processes on ports with zero dependencies

183 lines 9.36 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isLinux = exports.isMacOS = exports.isWindows = exports.getPlatform = exports.parsePortRange = exports.validatePorts = exports.validatePort = exports.Logger = exports.PortScanner = exports.ProcessKiller = exports.ProcessFinder = exports.PortTerminator = void 0; exports.killPort = killPort; exports.killPorts = killPorts; exports.getProcessOnPort = getProcessOnPort; exports.getProcessesOnPort = getProcessesOnPort; exports.isPortAvailable = isPortAvailable; exports.waitForPort = waitForPort; const process_finder_1 = require("./core/process-finder"); const process_killer_1 = require("./core/process-killer"); const validators_1 = require("./utils/validators"); const errors_1 = require("./errors"); const logger_1 = require("./utils/logger"); class PortTerminator { constructor(options = {}) { this.processFinder = new process_finder_1.ProcessFinder(); this.processKiller = new process_killer_1.ProcessKiller(); this.options = { method: options.method || 'both', timeout: options.timeout || 30000, force: options.force || false, silent: options.silent || false, gracefulTimeout: options.gracefulTimeout || 5000, }; this.logger = new logger_1.Logger('info', this.options.silent); } async terminate(port) { const ports = Array.isArray(port) ? port : [port]; const validatedPorts = (0, validators_1.validatePorts)(ports); this.logger.info(`Terminating processes on port${ports.length > 1 ? 's' : ''}: ${validatedPorts.join(', ')}`); const results = await this.terminateMultiple(validatedPorts); return Array.from(results.values()).every((success) => success); } async terminateMultiple(ports) { const validatedPorts = (0, validators_1.validatePorts)(ports); const results = new Map(); const protocol = this.options.method; await Promise.all(validatedPorts.map(async (port) => { try { this.logger.debug(`Finding processes on port ${port}`); const processes = await this.processFinder.findByPort(port, protocol); if (processes.length === 0) { this.logger.warn(`No processes found on port ${port}`); results.set(port, true); return; } this.logger.info(`Found ${processes.length} process(es) on port ${port}`); const killedProcesses = await this.processKiller.killProcessesByPort(port, this.options.force, this.options.gracefulTimeout, protocol); const success = killedProcesses.length === processes.length; results.set(port, success); if (success) { this.logger.info(`Successfully terminated ${killedProcesses.length} process(es) on port ${port}`); } else { this.logger.error(`Failed to terminate some processes on port ${port}`); } } catch (error) { this.logger.error(`Error terminating processes on port ${port}: ${error instanceof Error ? error.message : 'Unknown error'}`); results.set(port, false); } })); return results; } async getProcesses(port) { const validatedPort = (0, validators_1.validatePort)(port); const protocol = this.options.method; this.logger.debug(`Getting processes on port ${validatedPort}`); return this.processFinder.findByPort(validatedPort, protocol); } async isPortAvailable(port) { const validatedPort = (0, validators_1.validatePort)(port); const protocol = this.options.method; return this.processFinder.isPortAvailable(validatedPort, protocol); } async waitForPort(port, timeout) { const validatedPort = (0, validators_1.validatePort)(port); const timeoutMs = timeout ? (0, validators_1.validateTimeout)(timeout) : this.options.timeout; const protocol = this.options.method; this.logger.debug(`Waiting for port ${validatedPort} to become available (timeout: ${timeoutMs}ms)`); const success = await this.processFinder.waitForPortToBeAvailable(validatedPort, timeoutMs, protocol); if (!success) { throw new errors_1.TimeoutError(`waitForPort(${validatedPort})`, timeoutMs); } return success; } async terminateWithDetails(ports) { const validatedPorts = (0, validators_1.validatePorts)(ports); const results = []; const protocol = this.options.method; for (const port of validatedPorts) { try { const processes = await this.processFinder.findByPort(port, protocol); if (processes.length === 0) { results.push({ port, success: true, processes: [], }); continue; } const killedProcesses = await this.processKiller.killProcessesByPort(port, this.options.force, this.options.gracefulTimeout, protocol); results.push({ port, success: killedProcesses.length === processes.length, processes: killedProcesses, }); } catch (error) { results.push({ port, success: false, processes: [], error: error instanceof Error ? error.message : 'Unknown error', }); } } return results; } } exports.PortTerminator = PortTerminator; // Convenience functions async function killPort(port, options = {}) { const terminator = new PortTerminator(options); return terminator.terminate(port); } async function killPorts(ports, options = {}) { const terminator = new PortTerminator(options); return terminator.terminateMultiple(ports); } async function getProcessOnPort(port, options = {}) { const terminator = new PortTerminator(options); const processes = await terminator.getProcesses(port); return processes.length > 0 ? processes[0] : null; } async function getProcessesOnPort(port, options = {}) { const terminator = new PortTerminator(options); return terminator.getProcesses(port); } async function isPortAvailable(port, options = {}) { const terminator = new PortTerminator(options); return terminator.isPortAvailable(port); } async function waitForPort(port, timeout, options = {}) { const terminator = new PortTerminator(options); return terminator.waitForPort(port, timeout); } // Re-export types and errors __exportStar(require("./types"), exports); __exportStar(require("./errors"), exports); var process_finder_2 = require("./core/process-finder"); Object.defineProperty(exports, "ProcessFinder", { enumerable: true, get: function () { return process_finder_2.ProcessFinder; } }); var process_killer_2 = require("./core/process-killer"); Object.defineProperty(exports, "ProcessKiller", { enumerable: true, get: function () { return process_killer_2.ProcessKiller; } }); var port_scanner_1 = require("./core/port-scanner"); Object.defineProperty(exports, "PortScanner", { enumerable: true, get: function () { return port_scanner_1.PortScanner; } }); var logger_2 = require("./utils/logger"); Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_2.Logger; } }); var validators_2 = require("./utils/validators"); Object.defineProperty(exports, "validatePort", { enumerable: true, get: function () { return validators_2.validatePort; } }); Object.defineProperty(exports, "validatePorts", { enumerable: true, get: function () { return validators_2.validatePorts; } }); Object.defineProperty(exports, "parsePortRange", { enumerable: true, get: function () { return validators_2.parsePortRange; } }); var platform_1 = require("./utils/platform"); Object.defineProperty(exports, "getPlatform", { enumerable: true, get: function () { return platform_1.getPlatform; } }); Object.defineProperty(exports, "isWindows", { enumerable: true, get: function () { return platform_1.isWindows; } }); Object.defineProperty(exports, "isMacOS", { enumerable: true, get: function () { return platform_1.isMacOS; } }); Object.defineProperty(exports, "isLinux", { enumerable: true, get: function () { return platform_1.isLinux; } }); //# sourceMappingURL=index.js.map