Skip to content

Commit

Permalink
Require Node.js 12.20 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Oct 3, 2021
1 parent c3bbed9 commit c08a4ae
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 134 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/main.yml
Expand Up @@ -14,13 +14,12 @@ jobs:
- windows-latest
- macos-latest
node-version:
- 16
- 14
- 12
- 10
- 8
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
93 changes: 42 additions & 51 deletions index.d.ts
@@ -1,64 +1,55 @@
/// <reference types="node"/>
import {ListenOptions} from 'net';
import {ListenOptions} from 'node:net';

declare namespace getPort {
interface Options extends Omit<ListenOptions, 'port'> {
/**
A preferred port or an iterable of preferred ports to use.
*/
readonly port?: number | Iterable<number>;

/**
The host on which port resolution should be performed. Can be either an IPv4 or IPv6 address.
*/
readonly host?: string;
}
}
export interface Options extends Omit<ListenOptions, 'port'> {
/**
A preferred port or an iterable of preferred ports to use.
*/
readonly port?: number | Iterable<number>;

declare const getPort: {
/**
Get an available TCP port number.
The host on which port resolution should be performed. Can be either an IPv4 or IPv6 address.
By default, it checks availability on all local addresses defined in [OS network interfaces](https://nodejs.org/api/os.html#os_os_networkinterfaces). If this option is set, it will only check the given host.
*/
readonly host?: string;
}

@returns Port number.
/**
Get an available TCP port number.
@example
```
import getPort = require('get-port');
@returns Port number.
(async () => {
console.log(await getPort());
//=> 51402
@example
```
import getPort from 'get-port';
// Pass in a preferred port
console.log(await getPort({port: 3000}));
// Will use 3000 if available, otherwise fall back to a random port
console.log(await getPort());
//=> 51402
// Pass in an array of preferred ports
console.log(await getPort({port: [3000, 3001, 3002]}));
// Will use any element in the preferred ports array if available, otherwise fall back to a random port
})();
```
*/
(options?: getPort.Options): Promise<number>;
// Pass in a preferred port
console.log(await getPort({port: 3000}));
// Will use 3000 if available, otherwise fall back to a random port
/**
Make a range of ports `from`...`to`.
// Pass in an array of preferred ports
console.log(await getPort({port: [3000, 3001, 3002]}));
// Will use any element in the preferred ports array if available, otherwise fall back to a random port
```
*/
export default function getPort(options?: Options): Promise<number>;

@param from - First port of the range. Must be in the range `1024`...`65535`.
@param to - Last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`.
@returns The ports in the range.
/**
Generate port numbers in the given range `from`...`to`.
@example
```
import getPort = require('get-port');
@param from - The first port of the range. Must be in the range `1024`...`65535`.
@param to - The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`.
@returns The port numbers in the range.
(async () => {
console.log(await getPort({port: getPort.makeRange(3000, 3100)}));
// Will use any port from 3000 to 3100, otherwise fall back to a random port
})();
```
*/
makeRange(from: number, to: number): Iterable<number>;
};
@example
```
import getPort, {portNumbers} from 'get-port';
export = getPort;
console.log(await getPort({port: portNumbers(3000, 3100)}));
// Will use any port from 3000 to 3100, otherwise fall back to a random port
```
*/
export function portNumbers(from: number, to: number): Iterable<number>;
22 changes: 12 additions & 10 deletions index.js
@@ -1,6 +1,5 @@
'use strict';
const net = require('net');
const os = require('os');
import net from 'node:net';
import os from 'node:os';

class Locked extends Error {
constructor(port) {
Expand All @@ -10,7 +9,7 @@ class Locked extends Error {

const lockedPorts = {
old: new Set(),
young: new Set()
young: new Set(),
};

// On this interval, the old locked ports are discarded,
Expand All @@ -23,6 +22,7 @@ let interval;

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.
const results = new Set([undefined, '0.0.0.0']);
Expand All @@ -41,6 +41,7 @@ const checkAvailablePort = options =>
const server = net.createServer();
server.unref();
server.on('error', reject);

server.listen(options, () => {
const {port} = server.address();
server.close(() => {
Expand Down Expand Up @@ -75,7 +76,7 @@ const portCheckSequence = function * (ports) {
yield 0; // Fall back to 0 if anything else failed
};

module.exports = async options => {
export default async function getPorts(options) {
let ports;

if (options) {
Expand Down Expand Up @@ -108,6 +109,7 @@ module.exports = async options => {
}

lockedPorts.young.add(availablePort);

return availablePort;
} catch (error) {
if (!['EADDRINUSE', 'EACCES'].includes(error.code) && !(error instanceof Locked)) {
Expand All @@ -117,18 +119,18 @@ module.exports = async options => {
}

throw new Error('No available ports found');
};
}

module.exports.makeRange = (from, to) => {
export function portNumbers(from, to) {
if (!Number.isInteger(from) || !Number.isInteger(to)) {
throw new TypeError('`from` and `to` must be integer numbers');
}

if (from < 1024 || from > 65535) {
if (from < 1024 || from > 65_535) {
throw new RangeError('`from` must be between 1024 and 65535');
}

if (to < 1024 || to > 65536) {
if (to < 1024 || to > 65_536) {
throw new RangeError('`to` must be between 1024 and 65536');
}

Expand All @@ -143,4 +145,4 @@ module.exports.makeRange = (from, to) => {
};

return generator(from, to);
};
}
4 changes: 2 additions & 2 deletions index.test-d.ts
@@ -1,9 +1,9 @@
import {expectType} from 'tsd';
import getPort = require('.');
import getPort, {portNumbers} from './index.js';

expectType<Promise<number>>(getPort());
expectType<Promise<number>>(getPort({port: 3000}));
expectType<Promise<number>>(getPort({port: [3000, 3001, 3002]}));
expectType<Promise<number>>(getPort({host: 'https://localhost'}));
expectType<Promise<number>>(getPort({ipv6Only: true}));
expectType<Iterable<number>>(getPort.makeRange(1024, 1025));
expectType<Iterable<number>>(portNumbers(1024, 1025));
2 changes: 1 addition & 1 deletion license
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
15 changes: 9 additions & 6 deletions package.json
Expand Up @@ -8,10 +8,12 @@
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=8"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"test": "xo && ava && tsd"
Expand All @@ -38,9 +40,10 @@
"chosen"
],
"devDependencies": {
"@types/node": "^12.12.21",
"ava": "^2.4.0",
"tsd": "^0.11.0",
"xo": "^0.25.3"
"@types/node": "^16.10.2",
"ava": "^3.15.0",
"tsd": "^0.17.0",
"typescript": "^4.4.3",
"xo": "^0.45.0"
}
}
52 changes: 24 additions & 28 deletions readme.md
@@ -1,51 +1,47 @@
# get-port

> Get an available [TCP port](https://en.wikipedia.org/wiki/Port_(computer_networking)).
>
>
## Install

```
$ npm install get-port
```sh
npm install get-port
```

## Usage

```js
const getPort = require('get-port');
import getPort from 'get-port';

(async () => {
console.log(await getPort());
//=> 51402
})();
console.log(await getPort());
//=> 51402
```

Pass in a preferred port:

```js
(async () => {
console.log(await getPort({port: 3000}));
// Will use 3000 if available, otherwise fall back to a random port
})();
import getPort from 'get-port';

console.log(await getPort({port: 3000}));
// Will use 3000 if available, otherwise fall back to a random port
```

Pass in an array of preferred ports:

```js
(async () => {
console.log(await getPort({port: [3000, 3001, 3002]}));
// Will use any element in the preferred ports array if available, otherwise fall back to a random port
})();
import getPort from 'get-port';

console.log(await getPort({port: [3000, 3001, 3002]}));
// Will use any element in the preferred ports array if available, otherwise fall back to a random port
```

Use the `makeRange()` helper in case you need a port in a certain range:
Use the `portNumbers()` helper in case you need a port in a certain range:

```js
(async () => {
console.log(await getPort({port: getPort.makeRange(3000, 3100)}));
// Will use any port from 3000 to 3100, otherwise fall back to a random port
})();
import getPort, {portNumbers} from 'get-port';

console.log(await getPort({port: portNumbers(3000, 3100)}));
// Will use any port from 3000 to 3100, otherwise fall back to a random port
```

## API
Expand All @@ -70,25 +66,25 @@ Type: `string`

The host on which port resolution should be performed. Can be either an IPv4 or IPv6 address.

By default, `get-port` checks availability on all local addresses defined in [OS network interfaces](https://nodejs.org/api/os.html#os_os_networkinterfaces). If this option is set, it will only check the specified host.
By default, it checks availability on all local addresses defined in [OS network interfaces](https://nodejs.org/api/os.html#os_os_networkinterfaces). If this option is set, it will only check the given host.

### getPort.makeRange(from, to)
### portNumbers(from, to)

Make a range of ports `from`...`to`.
Generate port numbers in the given range `from`...`to`.

Returns an `Iterable` for ports in the given range.
Returns an `Iterable` for port numbers in the given range.

#### from

Type: `number`

First port of the range. Must be in the range `1024`...`65535`.
The first port of the range. Must be in the range `1024`...`65535`.

#### to

Type: `number`

Last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`.
The last port of the range. Must be in the range `1024`...`65535` and must be greater than `from`.

## Beware

Expand Down

0 comments on commit c08a4ae

Please sign in to comment.