feat(smartnetwork): Add exclude option to findFreePort and skip excluded ports during search
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-09-12 - 4.4.0 - feat(smartnetwork)
|
||||||
|
Add exclude option to findFreePort and skip excluded ports during search
|
||||||
|
|
||||||
|
- Add an 'exclude' array to IFindFreePortOptions so callers can specify ports to ignore when searching for a free port.
|
||||||
|
- Respect excluded ports in findFreePort for both random (randomize=true) and sequential searches so excluded ports are never returned.
|
||||||
|
- Add .claude/settings.local.json to include local permissions used for development/CI helpers.
|
||||||
|
|
||||||
## 2025-09-12 - 4.3.0 - feat(smartnetwork)
|
## 2025-09-12 - 4.3.0 - feat(smartnetwork)
|
||||||
Add randomizable port search and switch DNS resolution to @push.rocks/smartdns; export smartdns and update docs
|
Add randomizable port search and switch DNS resolution to @push.rocks/smartdns; export smartdns and update docs
|
||||||
|
|
||||||
|
14
readme.md
14
readme.md
@@ -99,6 +99,19 @@ const findFreePort = async () => {
|
|||||||
// Find a random free port in range (useful to avoid port conflicts)
|
// Find a random free port in range (useful to avoid port conflicts)
|
||||||
const randomPort = await network.findFreePort(3000, 3100, { randomize: true });
|
const randomPort = await network.findFreePort(3000, 3100, { randomize: true });
|
||||||
console.log(`🎲 Random free port: ${randomPort}`);
|
console.log(`🎲 Random free port: ${randomPort}`);
|
||||||
|
|
||||||
|
// Exclude specific ports from the search
|
||||||
|
const portWithExclusions = await network.findFreePort(3000, 3100, {
|
||||||
|
exclude: [3000, 3001, 3005] // Skip these ports even if they're free
|
||||||
|
});
|
||||||
|
console.log(`🚫 Free port (excluding specific ports): ${portWithExclusions}`);
|
||||||
|
|
||||||
|
// Combine randomize with exclude options
|
||||||
|
const randomWithExclusions = await network.findFreePort(3000, 3100, {
|
||||||
|
randomize: true,
|
||||||
|
exclude: [3000, 3001, 3005]
|
||||||
|
});
|
||||||
|
console.log(`🎲🚫 Random free port (with exclusions): ${randomWithExclusions}`);
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -333,6 +346,7 @@ interface SmartNetworkOptions {
|
|||||||
|
|
||||||
interface IFindFreePortOptions {
|
interface IFindFreePortOptions {
|
||||||
randomize?: boolean; // If true, returns a random free port instead of the first one
|
randomize?: boolean; // If true, returns a random free port instead of the first one
|
||||||
|
exclude?: number[]; // Array of port numbers to exclude from the search
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Hop {
|
interface Hop {
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartnetwork',
|
name: '@push.rocks/smartnetwork',
|
||||||
version: '4.3.0',
|
version: '4.4.0',
|
||||||
description: 'A toolkit for network diagnostics including speed tests, port availability checks, and more.'
|
description: 'A toolkit for network diagnostics including speed tests, port availability checks, and more.'
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,8 @@ export interface Hop {
|
|||||||
export interface IFindFreePortOptions {
|
export interface IFindFreePortOptions {
|
||||||
/** If true, selects a random available port within the range instead of the first one */
|
/** If true, selects a random available port within the range instead of the first one */
|
||||||
randomize?: boolean;
|
randomize?: boolean;
|
||||||
|
/** Array of port numbers to exclude from the search */
|
||||||
|
exclude?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SmartNetwork {
|
export class SmartNetwork {
|
||||||
@@ -169,12 +171,20 @@ export class SmartNetwork {
|
|||||||
throw new NetworkError('Start port must be less than or equal to end port', 'EINVAL');
|
throw new NetworkError('Start port must be less than or equal to end port', 'EINVAL');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a set of excluded ports for efficient lookup
|
||||||
|
const excludedPorts = new Set(options?.exclude || []);
|
||||||
|
|
||||||
// If randomize option is true, collect all available ports and select randomly
|
// If randomize option is true, collect all available ports and select randomly
|
||||||
if (options?.randomize) {
|
if (options?.randomize) {
|
||||||
const availablePorts: number[] = [];
|
const availablePorts: number[] = [];
|
||||||
|
|
||||||
// Scan the range to find all available ports
|
// Scan the range to find all available ports
|
||||||
for (let port = startPort; port <= endPort; port++) {
|
for (let port = startPort; port <= endPort; port++) {
|
||||||
|
// Skip excluded ports
|
||||||
|
if (excludedPorts.has(port)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const isUnused = await this.isLocalPortUnused(port);
|
const isUnused = await this.isLocalPortUnused(port);
|
||||||
if (isUnused) {
|
if (isUnused) {
|
||||||
availablePorts.push(port);
|
availablePorts.push(port);
|
||||||
@@ -192,6 +202,11 @@ export class SmartNetwork {
|
|||||||
} else {
|
} else {
|
||||||
// Default behavior: return the first available port (sequential search)
|
// Default behavior: return the first available port (sequential search)
|
||||||
for (let port = startPort; port <= endPort; port++) {
|
for (let port = startPort; port <= endPort; port++) {
|
||||||
|
// Skip excluded ports
|
||||||
|
if (excludedPorts.has(port)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const isUnused = await this.isLocalPortUnused(port);
|
const isUnused = await this.isLocalPortUnused(port);
|
||||||
if (isUnused) {
|
if (isUnused) {
|
||||||
return port;
|
return port;
|
||||||
|
Reference in New Issue
Block a user