From 6fbba3f4c6521393702fd824693a0e5ca78f7bbb Mon Sep 17 00:00:00 2001 From: tone <3341154833@qq.com> Date: Wed, 15 Oct 2025 16:00:59 +0800 Subject: [PATCH] feat: add getRandomAvailablePort function and update tests --- __tests__/unit/utils/utils.test.ts | 8 +++++++- src/utils/utils.ts | 29 ++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/__tests__/unit/utils/utils.test.ts b/__tests__/unit/utils/utils.test.ts index b104ba8..a7bd9d0 100644 --- a/__tests__/unit/utils/utils.test.ts +++ b/__tests__/unit/utils/utils.test.ts @@ -1,4 +1,4 @@ -import { isObject, isString, makeId } from "@/utils/utils" +import { getRandomAvailablePort, isObject, isString, makeId } from "@/utils/utils" test('makeId', () => { const id = makeId(); @@ -20,4 +20,10 @@ test('isString', () => { expect(isString(str)).toBeTruthy(); const aNumber = 1; expect(isString(aNumber)).toBeFalsy(); +}) + +test('getRandomAvailablePort', async () => { + const port = await getRandomAvailablePort(); + expect(port).toBeGreaterThanOrEqual(1); + expect(port).toBeLessThanOrEqual(65535); }) \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 9fa51e5..e4322c6 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -14,4 +14,31 @@ export type ToDeepPromise = { : T[K] extends object ? ToDeepPromise : T[K] -}; \ No newline at end of file +}; + +export async function getRandomAvailablePort() { + const { createServer } = await import('http'); + const server = createServer(); + + return new Promise((resolve, reject) => { + server.on('listening', () => { + const address = server.address(); + if (address && isObject(address)) { + const port = address.port; + server.close(() => { + resolve(port); + }) + } else { + server.close(); + reject(new Error('Failed to get port')); + } + }); + + server.on('error', (err) => { + server.close(); + reject(err); + }); + + server.listen(0); + }) +} \ No newline at end of file