Buckets:
| ; | |
| /* | |
| * Based on the packages get-port https://www.npmjs.com/package/get-port | |
| * and portfinder https://www.npmjs.com/package/portfinder | |
| * The code structure is similar to get-port, but it searches | |
| * ports deterministically like portfinder | |
| */ | |
| const net = require("net"); | |
| const os = require("os"); | |
| const minPort = 1024; | |
| const maxPort = 65_535; | |
| /** | |
| * @return {Set<string|undefined>} | |
| */ | |
| const getLocalHosts = () => { | |
| const interfaces = os.networkInterfaces(); | |
| // Add undefined value for createServer function to use default host, | |
| // and default IPv4 host in case createServer defaults to IPv6. | |
| // eslint-disable-next-line no-undefined | |
| const results = new Set([undefined, "0.0.0.0"]); | |
| for (const _interface of Object.values(interfaces)) { | |
| if (_interface) { | |
| for (const config of _interface) { | |
| results.add(config.address); | |
| } | |
| } | |
| } | |
| return results; | |
| }; | |
| /** | |
| * @param {number} basePort | |
| * @param {string | undefined} host | |
| * @return {Promise<number>} | |
| */ | |
| const checkAvailablePort = (basePort, host) => | |
| new Promise((resolve, reject) => { | |
| const server = net.createServer(); | |
| server.unref(); | |
| server.on("error", reject); | |
| server.listen(basePort, host, () => { | |
| // Next line should return AdressInfo because we're calling it after listen() and before close() | |
| const { port } = /** @type {import("net").AddressInfo} */ ( | |
| server.address() | |
| ); | |
| server.close(() => { | |
| resolve(port); | |
| }); | |
| }); | |
| }); | |
| /** | |
| * @param {number} port | |
| * @param {Set<string|undefined>} hosts | |
| * @return {Promise<number>} | |
| */ | |
| const getAvailablePort = async (port, hosts) => { | |
| /** | |
| * Errors that mean that host is not available. | |
| * @type {Set<string | undefined>} | |
| */ | |
| const nonExistentInterfaceErrors = new Set(["EADDRNOTAVAIL", "EINVAL"]); | |
| /* Check if the post is available on every local host name */ | |
| for (const host of hosts) { | |
| try { | |
| await checkAvailablePort(port, host); // eslint-disable-line no-await-in-loop | |
| } catch (error) { | |
| /* We throw an error only if the interface exists */ | |
| if ( | |
| !nonExistentInterfaceErrors.has( | |
| /** @type {NodeJS.ErrnoException} */ (error).code | |
| ) | |
| ) { | |
| throw error; | |
| } | |
| } | |
| } | |
| return port; | |
| }; | |
| /** | |
| * @param {number} basePort | |
| * @param {string=} host | |
| * @return {Promise<number>} | |
| */ | |
| async function getPorts(basePort, host) { | |
| if (basePort < minPort || basePort > maxPort) { | |
| throw new Error(`Port number must lie between ${minPort} and ${maxPort}`); | |
| } | |
| let port = basePort; | |
| const localhosts = getLocalHosts(); | |
| let hosts; | |
| if (host && !localhosts.has(host)) { | |
| hosts = new Set([host]); | |
| } else { | |
| /* If the host is equivalent to localhost | |
| we need to check every equivalent host | |
| else the port might falsely appear as available | |
| on some operating systems */ | |
| hosts = localhosts; | |
| } | |
| /** @type {Set<string | undefined>} */ | |
| const portUnavailableErrors = new Set(["EADDRINUSE", "EACCES"]); | |
| while (port <= maxPort) { | |
| try { | |
| const availablePort = await getAvailablePort(port, hosts); // eslint-disable-line no-await-in-loop | |
| return availablePort; | |
| } catch (error) { | |
| /* Try next port if port is busy; throw for any other error */ | |
| if ( | |
| !portUnavailableErrors.has( | |
| /** @type {NodeJS.ErrnoException} */ (error).code | |
| ) | |
| ) { | |
| throw error; | |
| } | |
| port += 1; | |
| } | |
| } | |
| throw new Error("No available ports found"); | |
| } | |
| module.exports = getPorts; | |
Xet Storage Details
- Size:
- 3.55 kB
- Xet hash:
- 34ca72b599328b76c90af7cccdf65bb3dc8564ad7f8e92850e0923289a2597f1
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.