feat: add ports to code

This commit is contained in:
2024-07-19 19:39:26 +02:00
parent 94b93a3a23
commit dfbfa900e1
5 changed files with 97 additions and 13 deletions

View File

@@ -18,11 +18,11 @@
* ``` * ```
*/ */
import delay from "delay";
import getPort from "port";
import psql, { type Sql } from "postgres"; import psql, { type Sql } from "postgres";
import { delay } from "std/async/delay.ts";
import type { Container } from "../docker/libraries/container.ts"; import type { Container } from "../docker/libraries/container.ts";
import getPort from "../docker/libraries/port.ts";
import { docker } from "../mod.ts"; import { docker } from "../mod.ts";
export class PostgresTestContainer { export class PostgresTestContainer {

View File

@@ -7,8 +7,6 @@
}, },
"imports": { "imports": {
"std/": "https://deno.land/std@0.224.0/", "std/": "https://deno.land/std@0.224.0/",
"delay": "npm:delay@6.0.0",
"port": "https://deno.land/x/getport@v2.1.2/mod.ts",
"postgres": "npm:postgres@3.4.4" "postgres": "npm:postgres@3.4.4"
}, },
"exclude": [ "exclude": [

10
deno.lock generated
View File

@@ -2,14 +2,9 @@
"version": "3", "version": "3",
"packages": { "packages": {
"specifiers": { "specifiers": {
"npm:delay@6.0.0": "npm:delay@6.0.0",
"npm:postgres@3.4.4": "npm:postgres@3.4.4" "npm:postgres@3.4.4": "npm:postgres@3.4.4"
}, },
"npm": { "npm": {
"delay@6.0.0": {
"integrity": "sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw==",
"dependencies": {}
},
"postgres@3.4.4": { "postgres@3.4.4": {
"integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==", "integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==",
"dependencies": {} "dependencies": {}
@@ -46,17 +41,16 @@
"https://deno.land/std@0.224.0/assert/mod.ts": "48b8cb8a619ea0b7958ad7ee9376500fe902284bb36f0e32c598c3dc34cbd6f3", "https://deno.land/std@0.224.0/assert/mod.ts": "48b8cb8a619ea0b7958ad7ee9376500fe902284bb36f0e32c598c3dc34cbd6f3",
"https://deno.land/std@0.224.0/assert/unimplemented.ts": "8c55a5793e9147b4f1ef68cd66496b7d5ba7a9e7ca30c6da070c1a58da723d73", "https://deno.land/std@0.224.0/assert/unimplemented.ts": "8c55a5793e9147b4f1ef68cd66496b7d5ba7a9e7ca30c6da070c1a58da723d73",
"https://deno.land/std@0.224.0/assert/unreachable.ts": "5ae3dbf63ef988615b93eb08d395dda771c96546565f9e521ed86f6510c29e19", "https://deno.land/std@0.224.0/assert/unreachable.ts": "5ae3dbf63ef988615b93eb08d395dda771c96546565f9e521ed86f6510c29e19",
"https://deno.land/std@0.224.0/async/delay.ts": "f90dd685b97c2f142b8069082993e437b1602b8e2561134827eeb7c12b95c499",
"https://deno.land/std@0.224.0/fmt/colors.ts": "508563c0659dd7198ba4bbf87e97f654af3c34eb56ba790260f252ad8012e1c5", "https://deno.land/std@0.224.0/fmt/colors.ts": "508563c0659dd7198ba4bbf87e97f654af3c34eb56ba790260f252ad8012e1c5",
"https://deno.land/std@0.224.0/internal/diff.ts": "6234a4b493ebe65dc67a18a0eb97ef683626a1166a1906232ce186ae9f65f4e6", "https://deno.land/std@0.224.0/internal/diff.ts": "6234a4b493ebe65dc67a18a0eb97ef683626a1166a1906232ce186ae9f65f4e6",
"https://deno.land/std@0.224.0/internal/format.ts": "0a98ee226fd3d43450245b1844b47003419d34d210fa989900861c79820d21c2", "https://deno.land/std@0.224.0/internal/format.ts": "0a98ee226fd3d43450245b1844b47003419d34d210fa989900861c79820d21c2",
"https://deno.land/std@0.224.0/internal/mod.ts": "534125398c8e7426183e12dc255bb635d94e06d0f93c60a297723abe69d3b22e", "https://deno.land/std@0.224.0/internal/mod.ts": "534125398c8e7426183e12dc255bb635d94e06d0f93c60a297723abe69d3b22e",
"https://deno.land/std@0.224.0/testing/_test_suite.ts": "f10a8a6338b60c403f07a76f3f46bdc9f1e1a820c0a1decddeb2949f7a8a0546", "https://deno.land/std@0.224.0/testing/_test_suite.ts": "f10a8a6338b60c403f07a76f3f46bdc9f1e1a820c0a1decddeb2949f7a8a0546",
"https://deno.land/std@0.224.0/testing/bdd.ts": "3e4de4ff6d8f348b5574661cef9501b442046a59079e201b849d0e74120d476b", "https://deno.land/std@0.224.0/testing/bdd.ts": "3e4de4ff6d8f348b5574661cef9501b442046a59079e201b849d0e74120d476b"
"https://deno.land/x/getport@v2.1.2/mod.ts": "e1d629c14008fc1da85278615c55e9356c206d35054577c49639248e3c036f17"
}, },
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"npm:delay@6.0.0",
"npm:postgres@3.4.4" "npm:postgres@3.4.4"
] ]
} }

View File

@@ -1,4 +1,4 @@
import delay from "delay"; import { delay } from "std/async/delay.ts";
import { modem } from "./modem.ts"; import { modem } from "./modem.ts";

92
docker/libraries/port.ts Normal file
View File

@@ -0,0 +1,92 @@
export const MIN_PORT = 1024;
export const MAX_PORT = 65535;
/**
* Try run listener to check if port is open.
*
* @param options
*/
export function checkPort(options: Deno.ListenOptions): CheckedPort {
const { port } = options;
try {
Deno.listen(options).close();
return { valid: true, port: port };
} catch (e) {
if (e.name !== "AddrInUse") {
throw e;
}
return { valid: false, port: port };
}
}
/**
* Create an array of number by min and max.
*
* @param from - Must be between 1024 and 65535
* @param to - Must be between 1024 and 65535 and greater than from
*/
export function makeRange(from: number, to: number): number[] {
if (!(from > MIN_PORT || from < MAX_PORT)) {
throw new RangeError("`from` must be between 1024 and 65535");
}
if (!(to > MIN_PORT || to < MAX_PORT)) {
throw new RangeError("`to` must be between 1024 and 65536");
}
if (!(to > from)) {
throw new RangeError("`to` must be greater than or equal to `from`");
}
const ports = [];
for (let port = from; port <= to; port++) {
ports.push(port);
}
return ports;
}
/**
* Return a random port between 1024 and 65535.
*
* @param hostname
*/
export function randomPort(hostname?: string): number {
const port = Math.ceil(Math.random() * ((MAX_PORT - 1) - MIN_PORT + 1) + MIN_PORT + 1);
const result: CheckedPort = checkPort({ hostname, port });
if (result.valid) {
return result.port;
}
return randomPort(hostname);
}
/**
* Return available port.
*
* @param port
* @param hostname
*/
export default function getPort(port?: number | number[], hostname?: string): number {
const listenOptions: Deno.ListenOptions = {
hostname: hostname || "0.0.0.0",
port: (port && !Array.isArray(port)) ? port : 0,
};
if (!port || Array.isArray(port)) {
const ports: number[] = (Array.isArray(port)) ? port : makeRange(MIN_PORT + 1, MAX_PORT - 1);
for (const port of ports) {
const result: CheckedPort = checkPort({ ...listenOptions, port });
if (result.valid) return result.port;
}
return getPort(ports[ports.length - 1]);
}
const result: CheckedPort = checkPort(listenOptions);
if (!result.valid) {
const range = makeRange(result.port + 1, MAX_PORT - 1);
return getPort(range);
}
return result.port;
}
export type CheckedPort = {
valid: boolean;
port: number;
};