diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e74cb72..9c00b21 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,10 +94,10 @@ importers: playground: dependencies: h3: - specifier: ^1.8.0-rc.3 + specifier: ^1.8.0 version: 1.8.0 listhen: - specifier: ^1.2.2 + specifier: ^1.4.1 version: link:.. packages: @@ -919,6 +919,7 @@ packages: dependencies: is-glob: 4.0.3 micromatch: 4.0.5 + napi-wasm: 1.1.0 dev: false bundledDependencies: - napi-wasm @@ -3339,6 +3340,10 @@ packages: hasBin: true dev: true + /napi-wasm@1.1.0: + resolution: {integrity: sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==} + dev: false + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true diff --git a/src/_utils.ts b/src/_utils.ts index e4efbaa..3b5ffd8 100644 --- a/src/_utils.ts +++ b/src/_utils.ts @@ -39,6 +39,16 @@ export function formatURL(url: string) { ); } +const localhostRegex = /^127(\.\d{1,3}){3}$|^localhost$|^::1$/; +export function isLocalhost(hostname: string | undefined) { + return hostname === undefined ? false : localhostRegex.test(hostname); +} + +const anyhostRegex = /^$|^0\.0\.0\.0$|^::$/; +export function isAnyhost(hostname: string | undefined) { + return hostname === undefined ? false : anyhostRegex.test(hostname); +} + export function getPublicURL( urls: ListenURL[], listhenOptions: ListenOptions, diff --git a/src/listen.ts b/src/listen.ts index 9cb0579..5cd73e4 100644 --- a/src/listen.ts +++ b/src/listen.ts @@ -23,6 +23,8 @@ import { formatAddress, formatURL, getNetworkInterfaces, + isLocalhost, + isAnyhost, getPublicURL, } from "./_utils"; import { resolveCertificate } from "./_cert"; @@ -36,8 +38,10 @@ export async function listen( const _hostname = process.env.HOST ?? _options.hostname; const _public = _options.public ?? + (isLocalhost(_hostname) ? false : undefined) ?? + (isAnyhost(_hostname) ? true : undefined) ?? (process.argv.includes("--host") ? true : undefined) ?? - (_hostname === "localhost" ? false : _isProd); + _isProd; const listhenOptions = defu(_options, { name: "", @@ -54,6 +58,23 @@ export async function listen( autoClose: true, }); + if (listhenOptions.public && isLocalhost(listhenOptions.hostname)) { + console.warn( + `[listhen] Trying to listhen on private host ${JSON.stringify( + listhenOptions.hostname, + )} with public option disabled.`, + ); + listhenOptions.public = false; + } else if (!listhenOptions.public && isAnyhost(listhenOptions.hostname)) { + console.warn( + `[listhen] Trying to listhen on public host ${JSON.stringify( + listhenOptions.hostname, + )} with public option disabled. Using "localhost".`, + ); + listhenOptions.public = false; + listhenOptions.hostname = "localhost"; + } + if (listhenOptions.isTest) { listhenOptions.showURL = false; }