UNPKG

@modern-js/utils

Version:

A Progressive React Framework for modern web development.

69 lines (68 loc) 3.29 kB
import { isIPv6 } from "net"; import os from "os"; import { chalk } from "../compiled.mjs"; import { DEFAULT_DEV_HOST } from "./constants.mjs"; import { isDev, isSingleEntry } from "./is/index.mjs"; const normalizeUrl = (url)=>url.replace(/([^:]\/)\/+/g, '$1'); const getIpv4Interfaces = ()=>{ const interfaces = os.networkInterfaces(); const ipv4Interfaces = []; Object.keys(interfaces).forEach((key)=>{ interfaces[key].forEach((detail)=>{ const familyV4Value = 'string' == typeof detail.family ? 'IPv4' : 4; if (detail.family === familyV4Value) ipv4Interfaces.push(detail); }); }); return ipv4Interfaces; }; const getHostInUrl = (host)=>{ if (isIPv6(host)) return '::' === host ? '[::1]' : `[${host}]`; return host; }; const getAddressUrls = (protocol = 'http', port, host)=>{ const LOCAL_LABEL = 'Local: '; const NETWORK_LABEL = 'Network: '; const isLocalhost = (url)=>url?.includes('localhost'); if (host && host !== DEFAULT_DEV_HOST) return [ { label: isLocalhost(host) ? LOCAL_LABEL : NETWORK_LABEL, url: `${protocol}://${getHostInUrl(host)}:${port}` } ]; const ipv4Interfaces = getIpv4Interfaces(); return ipv4Interfaces.reduce((memo, detail)=>{ if (isLocalhost(detail.address) || detail.internal) memo.push({ label: LOCAL_LABEL, url: `${protocol}://localhost:${port}` }); else memo.push({ label: NETWORK_LABEL, url: `${protocol}://${detail.address}:${port}` }); return memo; }, []); }; const prettyInstructions = (appContext, config)=>{ const { entrypoints, serverRoutes, port, apiOnly, checkedEntries } = appContext; const isHttps = isDev() && (config?.dev?.https || config?.tools?.devServer?.https); const urls = getAddressUrls(isHttps ? 'https' : 'http', port, config.dev?.host); const routes = apiOnly ? serverRoutes : serverRoutes.filter((route)=>route.entryName); let message = '\n'; if (isSingleEntry(entrypoints, config.source?.mainEntryName) || apiOnly) message += urls.map(({ label, url })=>` ${chalk.bold(`> ${label.padEnd(10)}`)}${chalk.cyanBright(normalizeUrl(`${url}/${routes[0].urlPath}`))}\n`).join(''); else { const maxNameLength = Math.max(...routes.map((r)=>r.entryName.length)); urls.forEach(({ label, url })=>{ message += ` ${chalk.bold(`> ${label}`)}${0 === routes.length ? chalk.cyanBright(url) : ''}\n`; routes.forEach(({ entryName, urlPath, isSSR })=>{ if (!checkedEntries.includes(entryName)) return; message += ` ${chalk.yellowBright(isSSR ? 'λ' : '○')} ${chalk.yellowBright(entryName.padEnd(maxNameLength + 8))}${chalk.cyanBright(normalizeUrl(`${url}/${urlPath}`))}\n`; }); }); message += '\n'; message += chalk.cyanBright(' λ (Server) server-side renders at runtime\n'); message += chalk.cyanBright(' ○ (Static) client-side renders as static HTML\n'); } if (config.dev?.cliShortcuts) message += ` ${chalk.dim('> press')} ${chalk.bold('h + enter')} ${chalk.dim('to show shortcuts')}\n`; return message; }; export { getAddressUrls, prettyInstructions };