UNPKG

xkite-core

Version:
177 lines (176 loc) 6.92 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var deps_exports = {}; __export(deps_exports, { default: () => deps_default, portNumbers: () => portNumbers }); module.exports = __toCommonJS(deps_exports); var import_node_net = __toESM(require("node:net"), 1); var import_node_os = __toESM(require("node:os"), 1); var Locked = class extends Error { constructor(port) { super(`${port} is locked`); } }; var lockedPorts = { old: new Set(), young: new Set() }; var releaseOldLockedPortsIntervalMs = 1e3 * 15; var minPort = 1024; var maxPort = 65535; var interval; var getLocalHosts = () => { const interfaces = import_node_os.default.networkInterfaces(); const results = new Set([void 0, "0.0.0.0"]); for (const _interface of Object.values(interfaces)) { for (const config of _interface) { results.add(config.address); } } return results; }; var checkAvailablePort = (options) => new Promise((resolve, reject) => { const server = import_node_net.default.createServer(); server.unref(); server.on("error", reject); server.listen(options, () => { const { port } = server.address(); server.close(() => { resolve(port); }); }); }); var getAvailablePort = (options, hosts) => __awaiter(void 0, void 0, void 0, function* () { if (options.host || options.port === 0) { return checkAvailablePort(options); } for (const host of hosts) { try { yield checkAvailablePort({ port: options.port, host }); } catch (error) { if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) { throw error; } } } return options.port; }); var portCheckSequence = function* (ports) { if (ports) { yield* ports; } yield 0; }; function getPorts(options) { return __awaiter(this, void 0, void 0, function* () { let ports; let exclude = new Set(); if (options) { if (options.port) { ports = typeof options.port === "number" ? [options.port] : options.port; } if (options.exclude) { const excludeIterable = options.exclude; if (typeof excludeIterable[Symbol.iterator] !== "function") { throw new TypeError("The `exclude` option must be an iterable."); } for (const element of excludeIterable) { if (typeof element !== "number") { throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded."); } if (!Number.isSafeInteger(element)) { throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`); } } exclude = new Set(excludeIterable); } } if (interval === void 0) { interval = setInterval(() => { lockedPorts.old = lockedPorts.young; lockedPorts.young = new Set(); }, releaseOldLockedPortsIntervalMs); if (interval.unref) { interval.unref(); } } const hosts = getLocalHosts(); for (const port of portCheckSequence(ports)) { try { if (exclude.has(port)) { continue; } let availablePort = yield getAvailablePort(Object.assign(Object.assign({}, options), { port }), hosts); while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) { if (port !== 0) { throw new Locked(port); } availablePort = yield getAvailablePort(Object.assign(Object.assign({}, options), { port }), hosts); } lockedPorts.young.add(availablePort); return availablePort; } catch (error) { if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) { throw error; } } } throw new Error("No available ports found"); }); } function portNumbers(from, to) { if (!Number.isInteger(from) || !Number.isInteger(to)) { throw new TypeError("`from` and `to` must be integer numbers"); } if (from < minPort || from > maxPort) { throw new RangeError(`'from' must be between ${minPort} and ${maxPort}`); } if (to < minPort || to > maxPort) { throw new RangeError(`'to' must be between ${minPort} and ${maxPort}`); } if (from > to) { throw new RangeError("`to` must be greater than or equal to `from`"); } const generator = function* (from2, to2) { for (let port = from2; port <= to2; port++) { yield port; } }; return generator(from, to); } var deps_default = getPorts; 0 && (module.exports = { portNumbers });