文件
hyb-oa/scripts/qa/validate-loopback-url.mjs
T

45 行
1.4 KiB
JavaScript

#!/usr/bin/env node
import path from "node:path";
import { pathToFileURL } from "node:url";
const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1", "[::1]"]);
export function validateLoopbackHttpUrl(input) {
let url;
try {
url = new URL(String(input ?? ""));
} catch {
throw new Error("base_url_invalid");
}
if (url.protocol !== "http:") throw new Error("base_url_protocol_not_http");
if (url.username || url.password) throw new Error("base_url_credentials_forbidden");
if (!LOOPBACK_HOSTS.has(url.hostname)) throw new Error("base_url_host_not_loopback");
if ((url.pathname && url.pathname !== "/") || url.search || url.hash) {
throw new Error("base_url_must_be_origin_only");
}
return url.origin;
}
export function validateTcpPort(input) {
const raw = String(input ?? "");
if (!/^[1-9][0-9]{0,4}$/u.test(raw)) throw new Error("port_invalid");
const port = Number(raw);
if (!Number.isSafeInteger(port) || port > 65535) throw new Error("port_out_of_range");
return String(port);
}
if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
try {
console.log(
process.argv[2] === "--port"
? validateTcpPort(process.argv[3])
: validateLoopbackHttpUrl(process.argv[2]),
);
} catch (error) {
console.error(`[local-candidate][ERROR] ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
}