Project Init

This commit is contained in:
Muluhabt
2026-05-29 15:23:46 +03:00
commit 2fbc557aac
67387 changed files with 6063341 additions and 0 deletions

20
node_modules/detect-port/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 - present node-modules and other contributors
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

121
node_modules/detect-port/README.md generated vendored Normal file
View File

@@ -0,0 +1,121 @@
# detect-port
[![NPM version][npm-image]][npm-url]
[![CI](https://github.com/node-modules/detect-port/actions/workflows/nodejs.yml/badge.svg)](https://github.com/node-modules/detect-port/actions/workflows/nodejs.yml)
[![Test coverage][codecov-image]][codecov-url]
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url]
[![Node.js Version][node-version-image]][node-version-url]
[npm-image]: https://img.shields.io/npm/v/detect-port.svg?style=flat-square
[npm-url]: https://npmjs.org/package/detect-port
[codecov-image]: https://codecov.io/gh/node-modules/detect-port/branch/master/graph/badge.svg
[codecov-url]: https://codecov.io/gh/node-modules/detect-port
[snyk-image]: https://snyk.io/test/npm/detect-port/badge.svg?style=flat-square
[snyk-url]: https://snyk.io/test/npm/detect-port
[download-image]: https://img.shields.io/npm/dm/detect-port.svg?style=flat-square
[download-url]: https://npmjs.org/package/detect-port
[node-version-image]: https://img.shields.io/node/v/detect-port.svg?style=flat-square
[node-version-url]: https://nodejs.org/en/download/
> Node.js implementation of port detector
## Who are using or has used
- ⭐⭐⭐[eggjs/egg](//github.com/eggjs/egg)
- ⭐⭐⭐[alibaba/ice](//github.com/alibaba/ice)
- ⭐⭐⭐[alibaba/uirecorder](//github.com/alibaba/uirecorder)
- ⭐⭐⭐[facebook/create-react-app](//github.com/facebook/create-react-app/blob/main/packages/react-dev-utils/package.json)
- ⭐⭐⭐[facebook/flipper](//github.com/facebook/flipper)
- ⭐⭐⭐[umijs/umi](//github.com/umijs/umi)
- ⭐⭐⭐[gatsbyjs/gatsby](//github.com/gatsbyjs/gatsby)
- ⭐⭐⭐[electron-react-boilerplate/electron-react-boilerplate](//github.com/electron-react-boilerplate/electron-react-boilerplate)
- ⭐⭐⭐[zeit/micro](//github.com/zeit/micro)
- ⭐⭐⭐[rails/webpacker](//github.com/rails/webpacker)
- ⭐⭐⭐[storybookjs/storybook](//github.com/storybookjs/storybook)
[For more](//github.com/node-modules/detect-port/network/dependents)
## Usage
```bash
npm i detect-port
```
CommonJS
```javascript
const { detect } = require('detect-port');
detect(port)
.then(realPort => {
if (port == realPort) {
console.log(`port: ${port} was not occupied`);
} else {
console.log(`port: ${port} was occupied, try port: ${realPort}`);
}
})
.catch(err => {
console.log(err);
});
```
ESM and TypeScript
```ts
import { detect } from 'detect-port';
detect(port)
.then(realPort => {
if (port == realPort) {
console.log(`port: ${port} was not occupied`);
} else {
console.log(`port: ${port} was occupied, try port: ${realPort}`);
}
})
.catch(err => {
console.log(err);
});
```
## Command Line Tool
```bash
npm i detect-port -g
```
### Quick Start
```bash
# get an available port randomly
$ detect
# detect pointed port
$ detect 80
# output verbose log
$ detect --verbose
# more help
$ detect --help
```
## FAQ
Most likely network error, check that your `/etc/hosts` and make sure the content below:
```bash
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
```
## License
[MIT](LICENSE)
## Contributors
[![Contributors](https://contrib.rocks/image?repo=node-modules/detect-port)](https://github.com/node-modules/detect-port/graphs/contributors)
Made with [contributors-img](https://contrib.rocks).

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
export {};

79
node_modules/detect-port/dist/commonjs/bin/detect-port.js generated vendored Executable file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env node
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = require("node:fs");
const detect_port_js_1 = require("../detect-port.js");
const pkgFile = node_path_1.default.join(__dirname, '../../../package.json');
const pkg = JSON.parse((0, node_fs_1.readFileSync)(pkgFile, 'utf-8'));
const args = process.argv.slice(2);
let arg_0 = args[0];
if (arg_0 && ['-v', '--version'].includes(arg_0.toLowerCase())) {
console.log(pkg.version);
process.exit(0);
}
const removeByValue = (arr, val) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === val) {
arr.splice(i, 1);
break;
}
}
};
const port = parseInt(arg_0, 10);
const isVerbose = args.includes('--verbose');
removeByValue(args, '--verbose');
arg_0 = args[0];
if (!arg_0) {
const random = Math.floor(9000 + Math.random() * (65535 - 9000));
(0, detect_port_js_1.detectPort)(random, (err, port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
console.log(`get available port ${port} randomly`);
}
else {
console.log(port || random);
}
});
}
else if (isNaN(port)) {
console.log();
console.log(` \u001b[37m${pkg.description}\u001b[0m`);
console.log();
console.log(' Usage:');
console.log();
console.log(` ${pkg.name} [port]`);
console.log();
console.log(' Options:');
console.log();
console.log(' -v, --version output version and exit');
console.log(' -h, --help output usage information');
console.log(' --verbose output verbose log');
console.log();
console.log(' Further help:');
console.log();
console.log(` ${pkg.homepage}`);
console.log();
}
else {
(0, detect_port_js_1.detectPort)(port, (err, _port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
if (port !== _port) {
console.log(`port ${port} was occupied`);
}
console.log(`get available port ${_port}`);
}
else {
console.log(_port || port);
}
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0ZWN0LXBvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmluL2RldGVjdC1wb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLDBEQUE2QjtBQUM3QixxQ0FBdUM7QUFDdkMsc0RBQStDO0FBRS9DLE1BQU0sT0FBTyxHQUFHLG1CQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0FBQzlELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBQSxzQkFBWSxFQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBRXZELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25DLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVwQixJQUFJLEtBQUssSUFBSSxDQUFFLElBQUksRUFBRSxXQUFXLENBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNqRSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN6QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUM7QUFFRCxNQUFNLGFBQWEsR0FBRyxDQUFDLEdBQWEsRUFBRSxHQUFXLEVBQUUsRUFBRTtJQUNuRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ25CLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLE1BQU07UUFDUixDQUFDO0lBQ0gsQ0FB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

View File

@@ -0,0 +1,12 @@
export type DetectPortCallback = (err: Error | null, port?: number) => void;
export interface PortConfig {
port?: number | string;
hostname?: string | undefined;
callback?: DetectPortCallback;
}
export declare class IPAddressNotAvailableError extends Error {
constructor(options?: ErrorOptions);
}
export declare function detectPort(port?: number | PortConfig | string): Promise<number>;
export declare function detectPort(callback: DetectPortCallback): void;
export declare function detectPort(port: number | PortConfig | string | undefined, callback: DetectPortCallback): void;

130
node_modules/detect-port/dist/commonjs/detect-port.js generated vendored Normal file

File diff suppressed because one or more lines are too long

5
node_modules/detect-port/dist/commonjs/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import { detectPort } from './detect-port.js';
export default detectPort;
export * from './detect-port.js';
export declare const detect: typeof detectPort;
export * from './wait-port.js';

24
node_modules/detect-port/dist/commonjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"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.detect = void 0;
const detect_port_js_1 = require("./detect-port.js");
exports.default = detect_port_js_1.detectPort;
__exportStar(require("./detect-port.js"), exports);
// keep alias detectPort to detect
exports.detect = detect_port_js_1.detectPort;
__exportStar(require("./wait-port.js"), exports);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxREFBOEM7QUFFOUMsa0JBQWUsMkJBQVUsQ0FBQztBQUUxQixtREFBaUM7QUFDakMsa0NBQWtDO0FBQ3JCLFFBQUEsTUFBTSxHQUFHLDJCQUFVLENBQUM7QUFFakMsaURBQStCIn0=

3
node_modules/detect-port/dist/commonjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

10
node_modules/detect-port/dist/commonjs/wait-port.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
export declare class WaitPortRetryError extends Error {
retries: number;
count: number;
constructor(message: string, retries: number, count: number, options?: ErrorOptions);
}
export interface WaitPortOptions {
retryInterval?: number;
retries?: number;
}
export declare function waitPort(port: number, options?: WaitPortOptions): Promise<boolean>;

44
node_modules/detect-port/dist/commonjs/wait-port.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WaitPortRetryError = void 0;
exports.waitPort = waitPort;
const node_util_1 = require("node:util");
const detect_port_js_1 = require("./detect-port.js");
const debug = (0, node_util_1.debuglog)('detect-port:wait-port');
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
class WaitPortRetryError extends Error {
retries;
count;
constructor(message, retries, count, options) {
super(message, options);
this.name = this.constructor.name;
this.retries = retries;
this.count = count;
Error.captureStackTrace(this, this.constructor);
}
}
exports.WaitPortRetryError = WaitPortRetryError;
async function waitPort(port, options = {}) {
const { retryInterval = 1000, retries = Infinity } = options;
let count = 1;
async function loop() {
debug('wait port %d, retries %d, count %d', port, retries, count);
if (count > retries) {
const err = new WaitPortRetryError('retries exceeded', retries, count);
throw err;
}
count++;
const freePort = await (0, detect_port_js_1.detectPort)(port);
if (freePort === port) {
await sleep(retryInterval);
return loop();
}
return true;
}
return await loop();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FpdC1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhaXQtcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2QkEsNEJBb0JDO0FBakRELHlDQUFxQztBQUNyQyxxREFBOEM7QUFFOUMsTUFBTSxLQUFLLEdBQUcsSUFBQSxvQkFBUSxFQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFaEQsU0FBUyxLQUFLLENBQUMsRUFBVTtJQUN2QixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzNCLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsTUFBYSxrQkFBbUIsU0FBUSxLQUFLO0lBQzNDLE9BQU8sQ0FBUztJQUNoQixLQUFLLENBQVM7SUFFZCxZQUFZLE9BQWUsRUFBRSxPQUFlLEVBQUUsS0FBYSxFQUFFLE9BQXNCO1FBQ2pGLEtBQUssQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRCxDQUFDO0NBQ0Y7QUFYRCxnREFXQztBQU9NLEtBQUssVUFBVSxRQUFRLENBQUMsSUFBWSxFQUFFLFVBQTJCLEVBQUU7SUFDeEUsTUFBTSxFQUFFLGFBQWEsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLFFBQVEsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUM3RCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFFZCxLQUFLLFVBQVUsSUFBSTtRQUNqQixLQUFLLENBQUMsb0NBQW9DLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRSxJQUFJLEtBQUssR0FBRyxPQUFPLEVBQUUsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLGtCQUFrQixDQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2RSxNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7UUFDRCxLQUFLLEVBQUUsQ0FBQztRQUNSLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSwyQkFBVSxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3RCLE1BQU0sS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDaEIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sTUFBTSxJQUFJLEVBQUUsQ0FBQztBQUN0QixDQUFDIn0=

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
export {};

74
node_modules/detect-port/dist/esm/bin/detect-port.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env node
import path from 'node:path';
import { readFileSync } from 'node:fs';
import { detectPort } from '../detect-port.js';
const pkgFile = path.join(__dirname, '../../../package.json');
const pkg = JSON.parse(readFileSync(pkgFile, 'utf-8'));
const args = process.argv.slice(2);
let arg_0 = args[0];
if (arg_0 && ['-v', '--version'].includes(arg_0.toLowerCase())) {
console.log(pkg.version);
process.exit(0);
}
const removeByValue = (arr, val) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === val) {
arr.splice(i, 1);
break;
}
}
};
const port = parseInt(arg_0, 10);
const isVerbose = args.includes('--verbose');
removeByValue(args, '--verbose');
arg_0 = args[0];
if (!arg_0) {
const random = Math.floor(9000 + Math.random() * (65535 - 9000));
detectPort(random, (err, port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
console.log(`get available port ${port} randomly`);
}
else {
console.log(port || random);
}
});
}
else if (isNaN(port)) {
console.log();
console.log(` \u001b[37m${pkg.description}\u001b[0m`);
console.log();
console.log(' Usage:');
console.log();
console.log(` ${pkg.name} [port]`);
console.log();
console.log(' Options:');
console.log();
console.log(' -v, --version output version and exit');
console.log(' -h, --help output usage information');
console.log(' --verbose output verbose log');
console.log();
console.log(' Further help:');
console.log();
console.log(` ${pkg.homepage}`);
console.log();
}
else {
detectPort(port, (err, _port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
if (port !== _port) {
console.log(`port ${port} was occupied`);
}
console.log(`get available port ${_port}`);
}
else {
console.log(_port || port);
}
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0ZWN0LXBvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmluL2RldGVjdC1wb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFL0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztBQUM5RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUV2RCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFcEIsSUFBSSxLQUFLLElBQUksQ0FBRSxJQUFJLEVBQUUsV0FBVyxDQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDakUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFhLEVBQUUsR0FBVyxFQUFFLEVBQUU7SUFDbkQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNwQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNuQixHQUFHLENBQUMs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

12
node_modules/detect-port/dist/esm/detect-port.d.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
export type DetectPortCallback = (err: Error | null, port?: number) => void;
export interface PortConfig {
port?: number | string;
hostname?: string | undefined;
callback?: DetectPortCallback;
}
export declare class IPAddressNotAvailableError extends Error {
constructor(options?: ErrorOptions);
}
export declare function detectPort(port?: number | PortConfig | string): Promise<number>;
export declare function detectPort(callback: DetectPortCallback): void;
export declare function detectPort(port: number | PortConfig | string | undefined, callback: DetectPortCallback): void;

125
node_modules/detect-port/dist/esm/detect-port.js generated vendored Normal file

File diff suppressed because one or more lines are too long

5
node_modules/detect-port/dist/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import { detectPort } from './detect-port.js';
export default detectPort;
export * from './detect-port.js';
export declare const detect: typeof detectPort;
export * from './wait-port.js';

7
node_modules/detect-port/dist/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import { detectPort } from './detect-port.js';
export default detectPort;
export * from './detect-port.js';
// keep alias detectPort to detect
export const detect = detectPort;
export * from './wait-port.js';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTlDLGVBQWUsVUFBVSxDQUFDO0FBRTFCLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsa0NBQWtDO0FBQ2xDLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFFakMsY0FBYyxnQkFBZ0IsQ0FBQyJ9

3
node_modules/detect-port/dist/esm/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

10
node_modules/detect-port/dist/esm/wait-port.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
export declare class WaitPortRetryError extends Error {
retries: number;
count: number;
constructor(message: string, retries: number, count: number, options?: ErrorOptions);
}
export interface WaitPortOptions {
retryInterval?: number;
retries?: number;
}
export declare function waitPort(port: number, options?: WaitPortOptions): Promise<boolean>;

39
node_modules/detect-port/dist/esm/wait-port.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
import { debuglog } from 'node:util';
import { detectPort } from './detect-port.js';
const debug = debuglog('detect-port:wait-port');
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
export class WaitPortRetryError extends Error {
retries;
count;
constructor(message, retries, count, options) {
super(message, options);
this.name = this.constructor.name;
this.retries = retries;
this.count = count;
Error.captureStackTrace(this, this.constructor);
}
}
export async function waitPort(port, options = {}) {
const { retryInterval = 1000, retries = Infinity } = options;
let count = 1;
async function loop() {
debug('wait port %d, retries %d, count %d', port, retries, count);
if (count > retries) {
const err = new WaitPortRetryError('retries exceeded', retries, count);
throw err;
}
count++;
const freePort = await detectPort(port);
if (freePort === port) {
await sleep(retryInterval);
return loop();
}
return true;
}
return await loop();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FpdC1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhaXQtcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU5QyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUVoRCxTQUFTLEtBQUssQ0FBQyxFQUFVO0lBQ3ZCLE9BQU8sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDM0IsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsS0FBSztJQUMzQyxPQUFPLENBQVM7SUFDaEIsS0FBSyxDQUFTO0lBRWQsWUFBWSxPQUFlLEVBQUUsT0FBZSxFQUFFLEtBQWEsRUFBRSxPQUFzQjtRQUNqRixLQUFLLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbEQsQ0FBQztDQUNGO0FBT0QsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRLENBQUMsSUFBWSxFQUFFLFVBQTJCLEVBQUU7SUFDeEUsTUFBTSxFQUFFLGFBQWEsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLFFBQVEsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUM3RCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFFZCxLQUFLLFVBQVUsSUFBSTtRQUNqQixLQUFLLENBQUMsb0NBQW9DLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRSxJQUFJLEtBQUssR0FBRyxPQUFPLEVBQUUsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLGtCQUFrQixDQUFDLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2RSxNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7UUFDRCxLQUFLLEVBQUUsQ0FBQztRQUNSLE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3RCLE1BQU0sS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDaEIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sTUFBTSxJQUFJLEVBQUUsQ0FBQztBQUN0QixDQUFDIn0=

4
node_modules/detect-port/dist/package.json generated vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"name": "detect-port",
"version": "2.1.0"
}

73
node_modules/detect-port/package.json generated vendored Normal file
View File

@@ -0,0 +1,73 @@
{
"name": "detect-port",
"version": "2.1.0",
"description": "Node.js implementation of port detector",
"keywords": [
"detect",
"port"
],
"bin": {
"detect": "dist/commonjs/bin/detect-port.js",
"detect-port": "dist/commonjs/bin/detect-port.js"
},
"main": "./dist/commonjs/index.js",
"files": [
"dist",
"src"
],
"repository": {
"type": "git",
"url": "git://github.com/node-modules/detect-port.git"
},
"dependencies": {
"address": "^2.0.1"
},
"devDependencies": {
"@eggjs/tsconfig": "^1.3.3",
"@types/mocha": "^10.0.6",
"@types/node": "^22.10.1",
"egg-bin": "^6.9.0",
"eslint": "^8.52.0",
"eslint-config-egg": "^13.0.0",
"execa": "^8.0.1",
"mm": "^3.4.0",
"strip-ansi": "^7.1.0",
"tshy": "^3.0.2",
"tshy-after": "^1.0.0",
"typescript": "^5.2.2"
},
"scripts": {
"pretest": "npm run lint -- --fix && npm run prepublishOnly",
"test": "egg-bin test",
"lint": "eslint src test --ext ts",
"ci": "npm run lint && npm run cov && npm run prepublishOnly",
"prepublishOnly": "tshy && tshy-after",
"precov": "npm run prepublishOnly",
"cov": "egg-bin cov"
},
"engines": {
"node": ">= 16.0.0"
},
"homepage": "https://github.com/node-modules/detect-port",
"license": "MIT",
"tshy": {
"exports": {
".": "./src/index.ts"
}
},
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
}
},
"types": "./dist/commonjs/index.d.ts",
"type": "module",
"module": "./dist/esm/index.js"
}

79
node_modules/detect-port/src/bin/detect-port.ts generated vendored Executable file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env node
import path from 'node:path';
import { readFileSync } from 'node:fs';
import { detectPort } from '../detect-port.js';
const pkgFile = path.join(__dirname, '../../../package.json');
const pkg = JSON.parse(readFileSync(pkgFile, 'utf-8'));
const args = process.argv.slice(2);
let arg_0 = args[0];
if (arg_0 && [ '-v', '--version' ].includes(arg_0.toLowerCase())) {
console.log(pkg.version);
process.exit(0);
}
const removeByValue = (arr: string[], val: string) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === val) {
arr.splice(i, 1);
break;
}
}
};
const port = parseInt(arg_0, 10);
const isVerbose = args.includes('--verbose');
removeByValue(args, '--verbose');
arg_0 = args[0];
if (!arg_0) {
const random = Math.floor(9000 + Math.random() * (65535 - 9000));
detectPort(random, (err, port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
console.log(`get available port ${port} randomly`);
} else {
console.log(port || random);
}
});
} else if (isNaN(port)) {
console.log();
console.log(` \u001b[37m${pkg.description}\u001b[0m`);
console.log();
console.log(' Usage:');
console.log();
console.log(` ${pkg.name} [port]`);
console.log();
console.log(' Options:');
console.log();
console.log(' -v, --version output version and exit');
console.log(' -h, --help output usage information');
console.log(' --verbose output verbose log');
console.log();
console.log(' Further help:');
console.log();
console.log(` ${pkg.homepage}`);
console.log();
} else {
detectPort(port, (err, _port) => {
if (isVerbose) {
if (err) {
console.log(`get available port failed with ${err}`);
}
if (port !== _port) {
console.log(`port ${port} was occupied`);
}
console.log(`get available port ${_port}`);
} else {
console.log(_port || port);
}
});
}

145
node_modules/detect-port/src/detect-port.ts generated vendored Normal file
View File

@@ -0,0 +1,145 @@
import { createServer, AddressInfo } from 'node:net';
import { debuglog } from 'node:util';
import { ip } from 'address';
const debug = debuglog('detect-port');
export type DetectPortCallback = (err: Error | null, port?: number) => void;
export interface PortConfig {
port?: number | string;
hostname?: string | undefined;
callback?: DetectPortCallback;
}
export class IPAddressNotAvailableError extends Error {
constructor(options?: ErrorOptions) {
super('The IP address is not available on this machine', options);
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
}
export function detectPort(port?: number | PortConfig | string): Promise<number>;
export function detectPort(callback: DetectPortCallback): void;
export function detectPort(port: number | PortConfig | string | undefined, callback: DetectPortCallback): void;
export function detectPort(port?: number | string | PortConfig | DetectPortCallback, callback?: DetectPortCallback) {
let hostname: string | undefined = '';
if (port && typeof port === 'object') {
hostname = port.hostname;
callback = port.callback;
port = port.port;
} else {
if (typeof port === 'function') {
callback = port;
port = void 0;
}
}
port = parseInt(port as unknown as string) || 0;
let maxPort = port + 10;
if (maxPort > 65535) {
maxPort = 65535;
}
debug('detect free port between [%s, %s)', port, maxPort);
if (typeof callback === 'function') {
return tryListen(port, maxPort, hostname)
.then(port => callback(null, port))
.catch(callback);
}
// promise
return tryListen(port as number, maxPort, hostname);
}
async function handleError(port: number, maxPort: number, hostname?: string) {
if (port >= maxPort) {
debug('port: %s >= maxPort: %s, give up and use random port', port, maxPort);
port = 0;
maxPort = 0;
}
return await tryListen(port, maxPort, hostname);
}
async function tryListen(port: number, maxPort: number, hostname?: string): Promise<number> {
// use user hostname
if (hostname) {
try {
return await listen(port, hostname);
} catch (err: any) {
if (err.code === 'EADDRNOTAVAIL') {
throw new IPAddressNotAvailableError({ cause: err });
}
return await handleError(++port, maxPort, hostname);
}
}
// 1. check null / undefined
try {
await listen(port);
} catch (err) {
// ignore random listening
if (port === 0) {
throw err;
}
return await handleError(++port, maxPort, hostname);
}
// 2. check 0.0.0.0
try {
await listen(port, '0.0.0.0');
} catch (err) {
return await handleError(++port, maxPort, hostname);
}
// 3. check 127.0.0.1
try {
await listen(port, '127.0.0.1');
} catch (err) {
return await handleError(++port, maxPort, hostname);
}
// 4. check localhost
try {
await listen(port, 'localhost');
} catch (err: any) {
// if localhost refer to the ip that is not unknown on the machine, you will see the error EADDRNOTAVAIL
// https://stackoverflow.com/questions/10809740/listen-eaddrnotavail-error-in-node-js
if (err.code !== 'EADDRNOTAVAIL') {
return await handleError(++port, maxPort, hostname);
}
}
// 5. check current ip
try {
return await listen(port, ip());
} catch (err) {
return await handleError(++port, maxPort, hostname);
}
}
function listen(port: number, hostname?: string) {
const server = createServer();
return new Promise<number>((resolve, reject) => {
server.once('error', err => {
debug('listen %s:%s error: %s', hostname, port, err);
server.close();
if ((err as any).code === 'ENOTFOUND') {
debug('ignore dns ENOTFOUND error, get free %s:%s', hostname, port);
return resolve(port);
}
return reject(err);
});
debug('try listen %d on %s', port, hostname);
server.listen(port, hostname, () => {
port = (server.address() as AddressInfo).port;
debug('get free %s:%s', hostname, port);
server.close();
return resolve(port);
});
});
}

9
node_modules/detect-port/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { detectPort } from './detect-port.js';
export default detectPort;
export * from './detect-port.js';
// keep alias detectPort to detect
export const detect = detectPort;
export * from './wait-port.js';

50
node_modules/detect-port/src/wait-port.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import { debuglog } from 'node:util';
import { detectPort } from './detect-port.js';
const debug = debuglog('detect-port:wait-port');
function sleep(ms: number) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
export class WaitPortRetryError extends Error {
retries: number;
count: number;
constructor(message: string, retries: number, count: number, options?: ErrorOptions) {
super(message, options);
this.name = this.constructor.name;
this.retries = retries;
this.count = count;
Error.captureStackTrace(this, this.constructor);
}
}
export interface WaitPortOptions {
retryInterval?: number;
retries?: number;
}
export async function waitPort(port: number, options: WaitPortOptions = {}) {
const { retryInterval = 1000, retries = Infinity } = options;
let count = 1;
async function loop() {
debug('wait port %d, retries %d, count %d', port, retries, count);
if (count > retries) {
const err = new WaitPortRetryError('retries exceeded', retries, count);
throw err;
}
count++;
const freePort = await detectPort(port);
if (freePort === port) {
await sleep(retryInterval);
return loop();
}
return true;
}
return await loop();
}