@hamedb89/localghost 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +278 -0
- package/assets/localghost-app-icon.png +0 -0
- package/assets/localghost-banner.png +0 -0
- package/assets/localghost-mascot.png +0 -0
- package/assets/localghost-wordmark.png +0 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +804 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-Cde1Bich.d.ts +31 -0
- package/dist/index.d.ts +132 -0
- package/dist/index.js +648 -0
- package/dist/index.js.map +1 -0
- package/dist/vite.d.ts +18 -0
- package/dist/vite.js +202 -0
- package/dist/vite.js.map +1 -0
- package/docs/brand.md +43 -0
- package/docs/flows.md +141 -0
- package/docs/github.md +129 -0
- package/docs/localghost.1.md +124 -0
- package/package.json +92 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/parse.ts","../src/caddy.ts","../src/fs.ts","../src/doctor.ts","../src/hosts-file.ts","../src/init.ts","../src/routes.ts","../src/state.ts","../src/update-check.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, unlinkSync } from \"node:fs\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport { getProjectName, readDevHosts, resolveDevHostsPath, sanitizeProjectName, type ReadDevHostsOptions } from \"./config.js\";\nimport { getCaddyfilePath, validateCaddyfile, writeCaddyfile, runCaddy } from \"./caddy.js\";\nimport { checkCaddy, runDoctor } from \"./doctor.js\";\nimport { removeSystemHosts, updateSystemHosts } from \"./hosts-file.js\";\nimport { initLocalghost, type PackageManager } from \"./init.js\";\nimport { findLocalMdnsHosts } from \"./parse.js\";\nimport { formatDomainRoutes } from \"./routes.js\";\nimport { getLocalghostStatePath, readLocalghostState, writeLocalghostState } from \"./state.js\";\nimport { checkForUpdate, formatUpdateMessage, LOCALGHOST_VERSION, maybeNotifyAboutUpdate } from \"./update-check.js\";\n\nfunction warnAboutLocalMdns(entries: ReturnType<typeof readDevHosts>) {\n const localHosts = findLocalMdnsHosts(entries);\n\n if (localHosts.length > 0) {\n console.warn(\n `Warning: .local can collide with mDNS/Bonjour. Prefer .localhost for dev hosts: ${localHosts.join(\", \")}`\n );\n }\n}\n\nfunction logDomainRoutes(entries: ReturnType<typeof readDevHosts>) {\n console.log(formatDomainRoutes(entries));\n}\n\nfunction parsePort(value: string) {\n const port = Number.parseInt(value, 10);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new InvalidArgumentError(\"Port must be a number between 1 and 65535.\");\n }\n\n return port;\n}\n\nfunction parsePackageManager(value: string): PackageManager {\n if (value === \"npm\" || value === \"yarn\" || value === \"pnpm\") return value;\n throw new InvalidArgumentError(\"Package manager must be npm, yarn, or pnpm.\");\n}\n\nfunction collect(value: string, previous: string[] = []) {\n return [...previous, value];\n}\n\ntype ConfigCliOptions = {\n cwd: string;\n config?: string[];\n configPattern?: string;\n};\n\nfunction readOptionsFromCli(options: ConfigCliOptions): ReadDevHostsOptions {\n return {\n cwd: options.cwd,\n ...(options.config && options.config.length > 0 ? { configFiles: options.config } : {}),\n ...(options.configPattern ? { configPattern: options.configPattern } : {})\n };\n}\n\nasync function assertCaddyReady() {\n const caddy = await checkCaddy();\n if (caddy.found) return;\n\n throw new Error([\n \"Caddy was not found.\",\n `Install it with: ${caddy.installHint}`,\n \"Localghost will not install it for you. No surprise spells.\"\n ].join(\"\\n\"));\n}\n\nconst program = new Command();\n\nprogram\n .name(\"localghost\")\n .description(\"Buh. Friendly local hostnames for app repos.\")\n .version(LOCALGHOST_VERSION)\n .option(\"--no-update-check\", \"Skip the npm update check for this run\");\n\nprogram.hook(\"postAction\", async (_thisCommand, actionCommand) => {\n if (actionCommand.name() === \"update\") return;\n\n const options = program.opts<{ updateCheck?: boolean }>();\n await maybeNotifyAboutUpdate({ disabled: options.updateCheck === false });\n});\n\nprogram\n .command(\"init\")\n .description(\"Create a .localghost config for this project\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--config <file>\", \"Config file to create\", \".localghost\")\n .option(\"--host <host>\", \"Primary local hostname\")\n .option(\"--port <number>\", \"Primary app port\", parsePort)\n .option(\"--api-host <host>\", \"API local hostname\")\n .option(\"--api-port <number>\", \"API port\", parsePort)\n .option(\"--package-manager <npm|yarn|pnpm>\", \"Package manager for suggested commands\", parsePackageManager)\n .option(\"--write-scripts\", \"Add localghost scripts to package.json\")\n .option(\"--force\", \"Overwrite an existing config file\")\n .action((options: {\n cwd: string;\n config: string;\n host?: string;\n port?: number;\n apiHost?: string;\n apiPort?: number;\n packageManager?: PackageManager;\n writeScripts?: boolean;\n force?: boolean;\n }) => {\n const result = initLocalghost({ ...options, configFile: options.config });\n\n if (result.configCreated) {\n console.log(`Buh. Created ${result.configPath}`);\n } else {\n console.log(`${result.configPath} already exists. Use --force to rewrite it.`);\n }\n\n if (options.writeScripts) {\n if (result.packageJsonChanged) {\n console.log(`Updated ${result.packageJsonPath}`);\n } else if (result.packageJsonPath) {\n console.log(`${result.packageJsonPath} already has localghost scripts.`);\n } else {\n console.log(\"No package.json found; skipped script setup.\");\n }\n }\n\n console.log(\"Next:\");\n for (const step of result.nextSteps) {\n console.log(` ${step}`);\n }\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Check machine prerequisites\")\n .action(async () => {\n const result = await runDoctor();\n\n if (result.caddy.found) {\n console.log(`Caddy: ${result.caddy.version ?? \"found\"}`);\n } else {\n console.log(\"Caddy: missing\");\n console.log(`Run: ${result.caddy.installHint}`);\n console.log(\"Localghost will not install it for you. No surprise spells.\");\n }\n\n if (!result.ok) {\n process.exitCode = 1;\n }\n });\n\nprogram\n .command(\"update\")\n .description(\"Check npm for a newer localghost release\")\n .option(\"--json\", \"Print raw JSON\")\n .action(async (options: { json?: boolean }) => {\n const result = await checkForUpdate({ force: true, timeoutMs: 5000 });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n const message = formatUpdateMessage(result);\n if (message) {\n console.log(message);\n return;\n }\n\n if (result.source === \"error\") {\n console.log(`Could not check npm for updates: ${result.error ?? \"unknown error\"}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`localghost is up to date. Current: ${result.currentVersion}`);\n });\n\nprogram\n .command(\"setup\")\n .description(\"Update /etc/hosts and generate/validate Caddyfile\")\n .option(\"--project <name>\", \"Managed /etc/hosts block name\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--config <file>\", \"Config file to look for. Can be repeated.\", collect, [])\n .option(\"--config-pattern <regex>\", \"Regex for config filenames in the project root\")\n .action(async (options: ConfigCliOptions & { project?: string }) => {\n await assertCaddyReady();\n\n const projectName = sanitizeProjectName(options.project ?? getProjectName(options.cwd));\n const readOptions = readOptionsFromCli(options);\n const configPath = resolveDevHostsPath(readOptions).path;\n const entries = readDevHosts(readOptions);\n\n warnAboutLocalMdns(entries);\n logDomainRoutes(entries);\n\n const hostsResult = await updateSystemHosts(projectName, entries);\n\n if (hostsResult.changed) {\n console.log(`Updated ${hostsResult.hostsPath}`);\n } else {\n console.log(`${hostsResult.hostsPath} already up to date`);\n }\n\n const caddyfile = await writeCaddyfile(entries, options.cwd);\n await validateCaddyfile(caddyfile);\n\n const statePath = writeLocalghostState(options.cwd, {\n action: \"setup\",\n projectName,\n cwd: options.cwd,\n configPath,\n hostsPath: hostsResult.hostsPath,\n hostsChanged: hostsResult.changed,\n ...(hostsResult.tempPath ? { hostsTempPath: hostsResult.tempPath } : {}),\n caddyfilePath: caddyfile,\n entries\n });\n\n console.log(`Generated ${caddyfile}`);\n console.log(`State ${statePath}`);\n console.log(\"Setup complete.\");\n });\n\nprogram\n .command(\"teardown\")\n .description(\"Remove Localghost's managed /etc/hosts block\")\n .option(\"--project <name>\", \"Managed /etc/hosts block name\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--remove-caddyfile\", \"Also remove ops/local/Caddyfile\")\n .action(async (options: { project?: string; cwd: string; removeCaddyfile?: boolean }) => {\n const projectName = sanitizeProjectName(options.project ?? getProjectName(options.cwd));\n const hostsResult = await removeSystemHosts(projectName);\n const caddyfilePath = getCaddyfilePath(options.cwd);\n let caddyfileRemoved = false;\n\n if (options.removeCaddyfile && existsSync(caddyfilePath)) {\n unlinkSync(caddyfilePath);\n caddyfileRemoved = true;\n }\n\n const statePath = writeLocalghostState(options.cwd, {\n action: \"teardown\",\n projectName,\n cwd: options.cwd,\n hostsPath: hostsResult.hostsPath,\n hostsChanged: hostsResult.changed,\n ...(hostsResult.tempPath ? { hostsTempPath: hostsResult.tempPath } : {}),\n caddyfilePath,\n caddyfileRemoved\n });\n\n if (hostsResult.removed) {\n console.log(`Removed Localghost hosts block from ${hostsResult.hostsPath}`);\n } else {\n console.log(`No Localghost hosts block found in ${hostsResult.hostsPath}`);\n }\n\n if (options.removeCaddyfile) {\n console.log(caddyfileRemoved ? `Removed ${caddyfilePath}` : `${caddyfilePath} was not present`);\n }\n\n console.log(`State ${statePath}`);\n });\n\nprogram\n .command(\"status\")\n .description(\"Print Localghost's project-local state file\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--json\", \"Print raw JSON\")\n .action((options: { cwd: string; json?: boolean }) => {\n const state = readLocalghostState(options.cwd);\n const statePath = getLocalghostStatePath(options.cwd);\n\n if (!state) {\n console.log(`No Localghost state found at ${statePath}`);\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(state, null, 2));\n return;\n }\n\n console.log(`State: ${statePath}`);\n console.log(`Last action: ${state.action}`);\n console.log(`Updated: ${state.updatedAt}`);\n console.log(`Project: ${state.projectName}`);\n if (state.configPath) console.log(`Config: ${state.configPath}`);\n if (state.hostsPath) console.log(`Hosts: ${state.hostsPath}`);\n if (state.caddyfilePath) console.log(`Caddyfile: ${state.caddyfilePath}`);\n if (typeof state.caddyfileRemoved === \"boolean\") console.log(`Caddyfile removed: ${state.caddyfileRemoved}`);\n });\n\nprogram\n .command(\"routes\")\n .description(\"Print domain to upstream routes\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--config <file>\", \"Config file to look for. Can be repeated.\", collect, [])\n .option(\"--config-pattern <regex>\", \"Regex for config filenames in the project root\")\n .option(\"--http\", \"Print domain URLs with http instead of https\")\n .action((options: ConfigCliOptions & { http?: boolean }) => {\n const entries = readDevHosts(readOptionsFromCli(options));\n warnAboutLocalMdns(entries);\n console.log(formatDomainRoutes(entries, { https: !options.http }));\n });\n\nprogram\n .command(\"dev\")\n .description(\"Generate Caddyfile and run Caddy\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--config <file>\", \"Config file to look for. Can be repeated.\", collect, [])\n .option(\"--config-pattern <regex>\", \"Regex for config filenames in the project root\")\n .action(async (options: ConfigCliOptions) => {\n await assertCaddyReady();\n\n const entries = readDevHosts(readOptionsFromCli(options));\n\n warnAboutLocalMdns(entries);\n logDomainRoutes(entries);\n\n const caddyfile = await writeCaddyfile(entries, options.cwd);\n await validateCaddyfile(caddyfile);\n await runCaddy(caddyfile);\n });\n\nprogram\n .command(\"print\")\n .description(\"Print parsed host config\")\n .option(\"--cwd <path>\", \"Project directory\", process.cwd())\n .option(\"--config <file>\", \"Config file to look for. Can be repeated.\", collect, [])\n .option(\"--config-pattern <regex>\", \"Regex for config filenames in the project root\")\n .action((options: ConfigCliOptions) => {\n const entries = readDevHosts(readOptionsFromCli(options));\n warnAboutLocalMdns(entries);\n console.log(JSON.stringify(entries, null, 2));\n });\n\nprogram.parseAsync().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n});\n","import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { parseDevHosts } from \"./parse.js\";\n\nexport const LOCALGHOST_CONFIG_FILE = \".localghost\";\n\nexport type ConfigPattern = string | RegExp;\n\nexport type ReadDevHostsOptions = {\n cwd?: string;\n fileName?: string;\n configFiles?: string[];\n configPattern?: ConfigPattern;\n};\n\nexport type ResolvedDevHostsPath = {\n path: string;\n fileName: string;\n exists: boolean;\n searchedFiles: string[];\n configPattern?: ConfigPattern;\n};\n\nfunction unique(values: string[]) {\n return [...new Set(values.filter(Boolean))];\n}\n\nfunction toRegExp(pattern: ConfigPattern) {\n return typeof pattern === \"string\" ? new RegExp(pattern) : pattern;\n}\n\nfunction findPatternMatches(cwd: string, pattern: ConfigPattern) {\n const matcher = toRegExp(pattern);\n\n return readdirSync(cwd, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => {\n matcher.lastIndex = 0;\n return matcher.test(name);\n })\n .sort();\n}\n\nexport function getConfigFileCandidates(options: ReadDevHostsOptions = {}) {\n const cwd = options.cwd ?? process.cwd();\n const exactFiles = unique([\n ...(options.fileName ? [options.fileName] : []),\n ...(options.configFiles ?? [])\n ]);\n const patternFiles = options.configPattern ? findPatternMatches(cwd, options.configPattern) : [];\n const candidates = unique([...exactFiles, ...patternFiles]);\n\n if (candidates.length > 0) return candidates;\n if (exactFiles.length > 0 || options.configPattern) return [];\n return [LOCALGHOST_CONFIG_FILE];\n}\n\nexport function resolveDevHostsPath(options: ReadDevHostsOptions = {}): ResolvedDevHostsPath {\n const cwd = options.cwd ?? process.cwd();\n const searchedFiles = getConfigFileCandidates(options);\n\n for (const fileName of searchedFiles) {\n const path = resolve(cwd, fileName);\n if (existsSync(path)) {\n return {\n path,\n fileName: basename(fileName),\n exists: true,\n searchedFiles,\n ...(options.configPattern ? { configPattern: options.configPattern } : {})\n };\n }\n }\n\n const fileName = searchedFiles[0] ?? LOCALGHOST_CONFIG_FILE;\n\n return {\n path: resolve(cwd, fileName),\n fileName: basename(fileName),\n exists: false,\n searchedFiles,\n ...(options.configPattern ? { configPattern: options.configPattern } : {})\n };\n}\n\nexport function getDevHostsPath(options: ReadDevHostsOptions = {}) {\n return resolveDevHostsPath(options).path;\n}\n\nfunction formatSearchedFiles(files: string[], pattern?: ConfigPattern) {\n if (files.length > 0) return files.map((file) => `\\`${file}\\``).join(\", \");\n if (pattern) return `files matching ${pattern.toString()}`;\n return `\\`${LOCALGHOST_CONFIG_FILE}\\``;\n}\n\nexport function readDevHosts(options: ReadDevHostsOptions | string = {}) {\n const resolvedOptions = typeof options === \"string\" ? { cwd: options } : options;\n const resolvedPath = resolveDevHostsPath(resolvedOptions);\n\n if (!resolvedPath.exists) {\n const cwd = resolvedOptions.cwd ?? process.cwd();\n throw new Error(\n `Missing Localghost config in ${cwd}. Looked for ${formatSearchedFiles(resolvedPath.searchedFiles, resolvedPath.configPattern)}. Run \\`localghost init\\` or pass --config/--config-pattern.`\n );\n }\n\n return parseDevHosts(readFileSync(resolvedPath.path, \"utf8\"), resolvedPath.fileName);\n}\n\nexport function getProjectName(cwd = process.cwd()) {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf8\")) as { name?: unknown };\n const name = typeof pkg.name === \"string\" && pkg.name ? pkg.name : \"app\";\n return sanitizeProjectName(name.replace(/^@/, \"\"));\n } catch {\n return \"app\";\n }\n}\n\nexport function sanitizeProjectName(value: string) {\n const projectName = value.replace(/[^\\w.-]+/g, \"-\").replace(/^-+|-+$/g, \"\");\n return projectName || \"app\";\n}\n","export type DevHostEntry = {\n host: string;\n port: number;\n target: string;\n};\n\nconst HOST_PATTERN = /^(?=.{1,253}$)(?!-)[a-z0-9-]+(\\.[a-z0-9-]+)*\\.?$/i;\n\nexport function parseDevHosts(input: string, fileName = \".localghost\"): DevHostEntry[] {\n const entries: DevHostEntry[] = [];\n\n input.split(/\\r?\\n/).forEach((rawLine, index) => {\n const line = rawLine.replace(/#.*/, \"\").trim();\n\n if (!line) {\n return;\n }\n\n const parts = line.split(/\\s+/);\n const host = parts[0];\n const portRaw = parts[1];\n\n if (!host || !portRaw || parts.length > 2) {\n throw new Error(`Invalid ${fileName} line ${index + 1}: \"${rawLine}\"`);\n }\n\n if (!HOST_PATTERN.test(host)) {\n throw new Error(`Invalid host on line ${index + 1}: \"${host}\"`);\n }\n\n const port = Number(portRaw);\n\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`Invalid port on line ${index + 1}: \"${portRaw}\"`);\n }\n\n entries.push({\n host: host.toLowerCase().replace(/\\.$/, \"\"),\n port,\n target: `127.0.0.1:${port}`\n });\n });\n\n return entries;\n}\n\nexport function findLocalMdnsHosts(entries: DevHostEntry[]): string[] {\n return [...new Set(entries.map((entry) => entry.host).filter((host) => host.endsWith(\".local\")))];\n}\n","import { dirname, join } from \"node:path\";\nimport { execa } from \"execa\";\nimport { writeTextFile } from \"./fs.js\";\nimport type { DevHostEntry } from \"./parse.js\";\n\nfunction groupByPort(entries: DevHostEntry[]) {\n const groups = new Map<number, DevHostEntry[]>();\n\n for (const entry of entries) {\n const group = groups.get(entry.port) ?? [];\n group.push(entry);\n groups.set(entry.port, group);\n }\n\n return groups;\n}\n\nexport function getCaddyfilePath(cwd = process.cwd()) {\n return join(cwd, \"ops/local/Caddyfile\");\n}\n\nexport function renderCaddyfile(entries: DevHostEntry[]) {\n const groups = groupByPort(entries);\n const blocks = [...groups.entries()]\n .sort(([leftPort], [rightPort]) => leftPort - rightPort)\n .map(([port, group]) => {\n const hosts = group\n .map((entry) => entry.host)\n .sort()\n .join(\", \");\n\n return `${hosts} {\n reverse_proxy 127.0.0.1:${port}\n}`;\n });\n\n return `{\n local_certs\n}\n\n${blocks.join(\"\\n\\n\")}\n`;\n}\n\nexport async function writeCaddyfile(entries: DevHostEntry[], cwd = process.cwd()) {\n const path = getCaddyfilePath(cwd);\n writeTextFile(path, renderCaddyfile(entries));\n return path;\n}\n\nexport async function validateCaddyfile(path: string) {\n await execa(\"caddy\", [\"validate\", \"--config\", path], {\n cwd: dirname(path),\n stdio: \"inherit\"\n });\n}\n\nexport async function runCaddy(path: string) {\n await execa(\"caddy\", [\"run\", \"--config\", path], {\n cwd: dirname(path),\n stdio: \"inherit\"\n });\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nexport function readTextFile(path: string) {\n return readFileSync(path, \"utf8\");\n}\n\nexport function writeTextFile(path: string, value: string) {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, value, \"utf8\");\n return path;\n}\n","import { execa } from \"execa\";\n\nexport type DoctorResult = {\n ok: boolean;\n caddy: {\n found: boolean;\n version?: string;\n installHint: string;\n };\n};\n\nexport async function checkCaddy(): Promise<DoctorResult[\"caddy\"]> {\n try {\n const result = await execa(\"caddy\", [\"version\"], { reject: false });\n const version = [result.stdout, result.stderr].filter(Boolean).join(\"\\n\").trim();\n\n return {\n found: result.exitCode === 0,\n ...(version ? { version } : {}),\n installHint: \"brew install caddy\"\n };\n } catch {\n return {\n found: false,\n installHint: \"brew install caddy\"\n };\n }\n}\n\nexport async function runDoctor(): Promise<DoctorResult> {\n const caddy = await checkCaddy();\n return {\n ok: caddy.found,\n caddy\n };\n}\n","import { writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { execa } from \"execa\";\nimport { sanitizeProjectName } from \"./config.js\";\nimport { readTextFile } from \"./fs.js\";\nimport type { DevHostEntry } from \"./parse.js\";\n\nexport type UpdateSystemHostsResult = {\n changed: boolean;\n hostsPath: string;\n tempPath?: string;\n};\n\nexport type RemoveSystemHostsResult = UpdateSystemHostsResult & {\n removed: boolean;\n};\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction getManagedBlockPattern(projectName: string) {\n const sanitizedProjectName = sanitizeProjectName(projectName);\n const start = `# localghost:start ${sanitizedProjectName}`;\n const end = `# localghost:end ${sanitizedProjectName}`;\n return new RegExp(`${escapeRegExp(start)}[\\\\s\\\\S]*?${escapeRegExp(end)}\\\\n?`, \"m\");\n}\n\nexport function getSystemHostsPath() {\n return process.platform === \"win32\" ? \"C:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts\" : \"/etc/hosts\";\n}\n\nexport function renderHostsBlock(projectName: string, entries: DevHostEntry[]) {\n const sanitizedProjectName = sanitizeProjectName(projectName);\n const hosts = [...new Set(entries.map((entry) => entry.host))].sort();\n\n return [\n `# localghost:start ${sanitizedProjectName}`,\n ...hosts.map((host) => `127.0.0.1 ${host}`),\n `# localghost:end ${sanitizedProjectName}`,\n \"\"\n ].join(\"\\n\");\n}\n\nexport function upsertManagedBlock(existing: string, projectName: string, block: string) {\n const pattern = getManagedBlockPattern(projectName);\n\n if (pattern.test(existing)) {\n return existing.replace(pattern, block);\n }\n\n return `${existing.trimEnd()}\\n\\n${block}`;\n}\n\nexport function removeManagedBlock(existing: string, projectName: string) {\n const pattern = getManagedBlockPattern(projectName);\n\n if (!pattern.test(existing)) {\n return existing;\n }\n\n return existing.replace(pattern, \"\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\nasync function writeSystemHostsFile(hostsPath: string, next: string, projectName: string) {\n const sanitizedProjectName = sanitizeProjectName(projectName);\n const tempPath = join(tmpdir(), `localghost-${sanitizedProjectName}-hosts`);\n writeFileSync(tempPath, next, \"utf8\");\n\n if (process.platform === \"win32\") {\n throw new Error(`Windows support: run as administrator and copy ${tempPath} to ${hostsPath}.`);\n }\n\n await execa(\"sudo\", [\"cp\", tempPath, hostsPath], { stdio: \"inherit\" });\n\n return tempPath;\n}\n\nexport async function updateSystemHosts(projectName: string, entries: DevHostEntry[]): Promise<UpdateSystemHostsResult> {\n const sanitizedProjectName = sanitizeProjectName(projectName);\n const hostsPath = getSystemHostsPath();\n const existing = readTextFile(hostsPath);\n const block = renderHostsBlock(sanitizedProjectName, entries);\n const next = upsertManagedBlock(existing, sanitizedProjectName, block);\n\n if (next === existing) {\n return { changed: false, hostsPath };\n }\n\n const tempPath = await writeSystemHostsFile(hostsPath, next, sanitizedProjectName);\n\n return { changed: true, hostsPath, tempPath };\n}\n\nexport async function removeSystemHosts(projectName: string): Promise<RemoveSystemHostsResult> {\n const sanitizedProjectName = sanitizeProjectName(projectName);\n const hostsPath = getSystemHostsPath();\n const existing = readTextFile(hostsPath);\n const next = removeManagedBlock(existing, sanitizedProjectName);\n\n if (next === existing) {\n return { changed: false, removed: false, hostsPath };\n }\n\n const tempPath = await writeSystemHostsFile(hostsPath, next, sanitizedProjectName);\n\n return { changed: true, removed: true, hostsPath, tempPath };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getProjectName, LOCALGHOST_CONFIG_FILE, sanitizeProjectName } from \"./config.js\";\nimport { writeTextFile } from \"./fs.js\";\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\";\n\nexport type InitOptions = {\n cwd?: string;\n host?: string;\n port?: number;\n apiHost?: string;\n apiPort?: number;\n force?: boolean;\n packageManager?: PackageManager;\n writeScripts?: boolean;\n configFile?: string;\n};\n\nexport type InitResult = {\n configPath: string;\n configCreated: boolean;\n packageJsonPath?: string;\n packageJsonChanged: boolean;\n packageManager: PackageManager;\n nextSteps: string[];\n};\n\nexport function detectPackageManager(cwd = process.cwd()): PackageManager {\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n return \"npm\";\n}\n\nexport function packageRunCommand(packageManager: PackageManager, script: string): string {\n if (packageManager === \"yarn\") return `yarn ${script}`;\n if (packageManager === \"pnpm\") return `pnpm ${script}`;\n return `npm run ${script}`;\n}\n\nexport function packageAddCommand(packageManager: PackageManager, packageName = \"@hamedb89/localghost\"): string {\n if (packageManager === \"yarn\") return `yarn add -D ${packageName}`;\n if (packageManager === \"pnpm\") return `pnpm add -D ${packageName}`;\n return `npm install -D ${packageName}`;\n}\n\nfunction renderConfig(options: Required<Pick<InitOptions, \"host\" | \"port\" | \"apiHost\" | \"apiPort\">>) {\n return [\n \"# Buh. Friendly names for local services.\",\n \"# Format: <host> <port>\",\n `${options.host} ${options.port}`,\n `www.${options.host} ${options.port}`,\n `${options.apiHost} ${options.apiPort}`,\n \"\"\n ].join(\"\\n\");\n}\n\nfunction readPackageJson(path: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction shellQuote(value: string) {\n if (/^[A-Za-z0-9_./:-]+$/.test(value)) return value;\n return `'${value.replace(/'/g, `'\"'\"'`)}'`;\n}\n\nfunction getConfigFlag(configFile: string) {\n return configFile === LOCALGHOST_CONFIG_FILE ? \"\" : ` --config ${shellQuote(configFile)}`;\n}\n\nfunction updatePackageScripts(packageJsonPath: string, configFile: string): boolean {\n const pkg = readPackageJson(packageJsonPath);\n if (!pkg) return false;\n\n const scripts = typeof pkg.scripts === \"object\" && pkg.scripts ? (pkg.scripts as Record<string, unknown>) : {};\n const configFlag = getConfigFlag(configFile);\n const nextScripts = {\n ...scripts,\n \"localghost:setup\": scripts[\"localghost:setup\"] ?? `localghost setup${configFlag}`,\n \"localghost:proxy\": scripts[\"localghost:proxy\"] ?? `localghost dev${configFlag}`,\n \"localghost:print\": scripts[\"localghost:print\"] ?? `localghost print${configFlag}`,\n \"localghost:routes\": scripts[\"localghost:routes\"] ?? `localghost routes${configFlag}`,\n \"localghost:status\": scripts[\"localghost:status\"] ?? \"localghost status\",\n \"localghost:teardown\": scripts[\"localghost:teardown\"] ?? \"localghost teardown\",\n \"localghost:doctor\": scripts[\"localghost:doctor\"] ?? \"localghost doctor\",\n \"localghost:update\": scripts[\"localghost:update\"] ?? \"localghost update\"\n };\n\n const changed = JSON.stringify(scripts) !== JSON.stringify(nextScripts);\n if (!changed) return false;\n\n pkg.scripts = nextScripts;\n writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`, \"utf8\");\n return true;\n}\n\nexport function initLocalghost(options: InitOptions = {}): InitResult {\n const cwd = options.cwd ?? process.cwd();\n const projectName = sanitizeProjectName(getProjectName(cwd).split(\"/\").pop() ?? \"app\");\n const host = options.host ?? `${projectName}.localhost`;\n const port = options.port ?? 5173;\n const apiHost = options.apiHost ?? `api.${host}`;\n const apiPort = options.apiPort ?? 8787;\n const packageManager = options.packageManager ?? detectPackageManager(cwd);\n const configFile = options.configFile ?? LOCALGHOST_CONFIG_FILE;\n const configPath = join(cwd, configFile);\n const configExists = existsSync(configPath);\n\n if (configExists && !options.force) {\n return {\n configPath,\n configCreated: false,\n packageJsonChanged: false,\n packageManager,\n nextSteps: [\n packageRunCommand(packageManager, \"localghost:doctor\"),\n packageRunCommand(packageManager, \"localghost:setup\"),\n packageRunCommand(packageManager, \"localghost:proxy\")\n ]\n };\n }\n\n writeTextFile(configPath, renderConfig({ host, port, apiHost, apiPort }));\n\n const packageJsonPath = join(cwd, \"package.json\");\n const packageJsonChanged = options.writeScripts ? updatePackageScripts(packageJsonPath, configFile) : false;\n\n return {\n configPath,\n configCreated: true,\n ...(existsSync(packageJsonPath) ? { packageJsonPath } : {}),\n packageJsonChanged,\n packageManager,\n nextSteps: [\n packageRunCommand(packageManager, \"localghost:doctor\"),\n packageRunCommand(packageManager, \"localghost:setup\"),\n packageRunCommand(packageManager, \"localghost:proxy\")\n ]\n };\n}\n","import type { DevHostEntry } from \"./parse.js\";\n\nexport type DomainRoute = {\n host: string;\n port: number;\n url: string;\n upstream: string;\n};\n\nexport type DomainRouteOptions = {\n https?: boolean;\n};\n\nexport function getDomainRoutes(entries: DevHostEntry[], options: DomainRouteOptions = {}): DomainRoute[] {\n const protocol = options.https === false ? \"http\" : \"https\";\n\n return [...entries]\n .sort((left, right) => left.host.localeCompare(right.host) || left.port - right.port)\n .map((entry) => ({\n host: entry.host,\n port: entry.port,\n url: `${protocol}://${entry.host}/`,\n upstream: `http://${entry.target}`\n }));\n}\n\nexport function formatDomainRoutes(entries: DevHostEntry[], options: DomainRouteOptions = {}) {\n const routes = getDomainRoutes(entries, options);\n\n if (routes.length === 0) {\n return \"localghost routes\\n no routes\";\n }\n\n return [\n \"localghost routes\",\n ...routes.map((route) => ` ${route.url} -> ${route.upstream}`)\n ].join(\"\\n\");\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readTextFile, writeTextFile } from \"./fs.js\";\nimport type { DevHostEntry } from \"./parse.js\";\n\nexport const LOCALGHOST_STATE_FILE = \"ops/local/localghost-state.json\";\n\nexport type LocalghostStateAction = \"setup\" | \"teardown\";\n\nexport type LocalghostState = {\n version: 1;\n action: LocalghostStateAction;\n updatedAt: string;\n projectName: string;\n cwd: string;\n configPath?: string;\n hostsPath?: string;\n hostsChanged?: boolean;\n hostsTempPath?: string;\n caddyfilePath?: string;\n caddyfileRemoved?: boolean;\n entries?: DevHostEntry[];\n};\n\nexport type WriteLocalghostStateInput = Omit<LocalghostState, \"version\" | \"updatedAt\">;\n\nexport function getLocalghostStatePath(cwd = process.cwd()) {\n return join(cwd, LOCALGHOST_STATE_FILE);\n}\n\nexport function readLocalghostState(cwd = process.cwd()): LocalghostState | null {\n const path = getLocalghostStatePath(cwd);\n if (!existsSync(path)) return null;\n return JSON.parse(readTextFile(path)) as LocalghostState;\n}\n\nexport function writeLocalghostState(cwd: string, state: WriteLocalghostStateInput) {\n const path = getLocalghostStatePath(cwd);\n writeTextFile(path, `${JSON.stringify({ version: 1, updatedAt: new Date().toISOString(), ...state }, null, 2)}\\n`);\n return path;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const LOCALGHOST_PACKAGE_NAME = \"@hamedb89/localghost\";\nexport const LOCALGHOST_VERSION = \"0.1.0\";\nexport const UPDATE_CHECK_CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nexport const UPDATE_CHECK_NOTIFY_TTL_MS = 24 * 60 * 60 * 1000;\nexport const UPDATE_CHECK_TIMEOUT_MS = 900;\n\nexport type UpdateCheckCache = {\n checkedAt: string;\n latestVersion?: string;\n notifiedVersion?: string;\n notifiedAt?: string;\n};\n\nexport type UpdateCheckResult = {\n currentVersion: string;\n packageName: string;\n latestVersion?: string;\n updateAvailable: boolean;\n source: \"cache\" | \"registry\" | \"disabled\" | \"error\";\n error?: string;\n};\n\ntype RegistryPackageResponse = {\n \"dist-tags\"?: {\n latest?: unknown;\n };\n};\n\nfunction truthyEnv(value: string | undefined) {\n return value === \"1\" || value === \"true\" || value === \"yes\";\n}\n\nexport function isUpdateCheckDisabled(env: NodeJS.ProcessEnv = process.env) {\n return truthyEnv(env.LOCALGHOST_NO_UPDATE_CHECK);\n}\n\nexport function getUpdateCheckCachePath(env: NodeJS.ProcessEnv = process.env) {\n if (env.LOCALGHOST_UPDATE_CHECK_CACHE) return env.LOCALGHOST_UPDATE_CHECK_CACHE;\n\n const cacheRoot = env.XDG_CACHE_HOME || join(homedir(), \".cache\");\n return join(cacheRoot, \"localghost\", \"update-check.json\");\n}\n\nfunction readCache(path = getUpdateCheckCachePath()): UpdateCheckCache | null {\n if (!existsSync(path)) return null;\n\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as UpdateCheckCache;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(cache: UpdateCheckCache, path = getUpdateCheckCachePath()) {\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(cache, null, 2)}\\n`, \"utf8\");\n } catch {\n // Update checks should never make the real command fail.\n }\n}\n\nfunction ageMs(date: string | undefined, now = Date.now()) {\n if (!date) return Number.POSITIVE_INFINITY;\n const time = Date.parse(date);\n return Number.isFinite(time) ? now - time : Number.POSITIVE_INFINITY;\n}\n\nfunction isCacheFresh(cache: UpdateCheckCache | null, ttlMs: number, now = Date.now()) {\n return Boolean(cache?.latestVersion && ageMs(cache.checkedAt, now) >= 0 && ageMs(cache.checkedAt, now) < ttlMs);\n}\n\ntype ParsedVersion = {\n major: number;\n minor: number;\n patch: number;\n prerelease?: string;\n};\n\nfunction parseVersion(version: string): ParsedVersion | null {\n const match = version.trim().replace(/^v/, \"\").match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/);\n if (!match) return null;\n\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n ...(match[4] ? { prerelease: match[4] } : {})\n };\n}\n\nexport function compareVersions(a: string, b: string) {\n const left = parseVersion(a);\n const right = parseVersion(b);\n\n if (!left || !right) return a.localeCompare(b);\n\n for (const key of [\"major\", \"minor\", \"patch\"] as const) {\n if (left[key] !== right[key]) return left[key] > right[key] ? 1 : -1;\n }\n\n if (left.prerelease === right.prerelease) return 0;\n if (!left.prerelease) return 1;\n if (!right.prerelease) return -1;\n return left.prerelease.localeCompare(right.prerelease);\n}\n\nexport function isNewerVersion(candidate: string | undefined, current = LOCALGHOST_VERSION) {\n return Boolean(candidate && compareVersions(candidate, current) > 0);\n}\n\nasync function fetchLatestVersion(packageName: string, timeoutMs: number) {\n const encodedName = packageName.startsWith(\"@\") ? `@${packageName.slice(1).replace(\"/\", \"%2f\")}` : packageName;\n const response = await fetch(`https://registry.npmjs.org/${encodedName}`, {\n signal: AbortSignal.timeout(timeoutMs),\n headers: {\n accept: \"application/vnd.npm.install-v1+json\"\n }\n });\n\n if (!response.ok) throw new Error(`npm registry returned ${response.status}`);\n\n const data = (await response.json()) as RegistryPackageResponse;\n const latest = data[\"dist-tags\"]?.latest;\n if (typeof latest !== \"string\" || latest.length === 0) throw new Error(\"npm registry response did not include latest dist-tag\");\n\n return latest;\n}\n\nexport async function checkForUpdate(options: {\n force?: boolean;\n packageName?: string;\n currentVersion?: string;\n timeoutMs?: number;\n cachePath?: string;\n env?: NodeJS.ProcessEnv;\n} = {}): Promise<UpdateCheckResult> {\n const env = options.env ?? process.env;\n const packageName = options.packageName ?? LOCALGHOST_PACKAGE_NAME;\n const currentVersion = options.currentVersion ?? LOCALGHOST_VERSION;\n const cachePath = options.cachePath ?? getUpdateCheckCachePath(env);\n\n if (!options.force && isUpdateCheckDisabled(env)) {\n return {\n currentVersion,\n packageName,\n updateAvailable: false,\n source: \"disabled\"\n };\n }\n\n const cache = readCache(cachePath);\n if (!options.force && isCacheFresh(cache, UPDATE_CHECK_CACHE_TTL_MS)) {\n const latestVersion = cache?.latestVersion;\n return {\n currentVersion,\n packageName,\n ...(latestVersion ? { latestVersion } : {}),\n updateAvailable: isNewerVersion(latestVersion, currentVersion),\n source: \"cache\"\n };\n }\n\n try {\n const latestVersion = await fetchLatestVersion(packageName, options.timeoutMs ?? UPDATE_CHECK_TIMEOUT_MS);\n writeCache({ checkedAt: new Date().toISOString(), latestVersion }, cachePath);\n\n return {\n currentVersion,\n packageName,\n latestVersion,\n updateAvailable: isNewerVersion(latestVersion, currentVersion),\n source: \"registry\"\n };\n } catch (error) {\n const latestVersion = cache?.latestVersion;\n return {\n currentVersion,\n packageName,\n ...(latestVersion ? { latestVersion } : {}),\n updateAvailable: isNewerVersion(latestVersion, currentVersion),\n source: \"error\",\n error: error instanceof Error ? error.message : String(error)\n };\n }\n}\n\nexport function formatUpdateMessage(result: UpdateCheckResult) {\n if (!result.updateAvailable || !result.latestVersion) return null;\n\n return [\n `localghost ${result.latestVersion} is available. Current: ${result.currentVersion}`,\n `Update with: npm i -g ${result.packageName}@latest`\n ].join(\"\\n\");\n}\n\nexport function shouldNotifyAboutUpdate(result: UpdateCheckResult, cachePath = getUpdateCheckCachePath(), now = Date.now()) {\n if (!result.updateAvailable || !result.latestVersion) return false;\n\n const cache = readCache(cachePath);\n if (cache?.notifiedVersion !== result.latestVersion) return true;\n\n return ageMs(cache.notifiedAt, now) >= UPDATE_CHECK_NOTIFY_TTL_MS;\n}\n\nexport function markUpdateNotified(result: UpdateCheckResult, cachePath = getUpdateCheckCachePath()) {\n if (!result.latestVersion) return;\n\n const cache = readCache(cachePath) ?? { checkedAt: new Date().toISOString() };\n writeCache(\n {\n ...cache,\n latestVersion: result.latestVersion,\n notifiedVersion: result.latestVersion,\n notifiedAt: new Date().toISOString()\n },\n cachePath\n );\n}\n\nexport async function maybeNotifyAboutUpdate(options: { disabled?: boolean } = {}) {\n if (options.disabled) return;\n\n const cachePath = getUpdateCheckCachePath();\n const result = await checkForUpdate({ cachePath });\n if (!shouldNotifyAboutUpdate(result, cachePath)) return;\n\n const message = formatUpdateMessage(result);\n if (!message) return;\n\n console.warn(`\\n${message}`);\n markUpdateNotified(result, cachePath);\n}\n"],"mappings":"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","names":["existsSync","fileName","dirname","join","readFileSync","join","dirname","execa","writeFileSync","join","execa","join","writeFileSync","execa","existsSync","readFileSync","writeFileSync","join","existsSync","join","readFileSync","writeFileSync","join","existsSync","existsSync","join","join","existsSync","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","existsSync"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type DevHostEntry = {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
target: string;
|
|
5
|
+
};
|
|
6
|
+
declare function parseDevHosts(input: string, fileName?: string): DevHostEntry[];
|
|
7
|
+
declare function findLocalMdnsHosts(entries: DevHostEntry[]): string[];
|
|
8
|
+
|
|
9
|
+
declare const LOCALGHOST_CONFIG_FILE = ".localghost";
|
|
10
|
+
type ConfigPattern = string | RegExp;
|
|
11
|
+
type ReadDevHostsOptions = {
|
|
12
|
+
cwd?: string;
|
|
13
|
+
fileName?: string;
|
|
14
|
+
configFiles?: string[];
|
|
15
|
+
configPattern?: ConfigPattern;
|
|
16
|
+
};
|
|
17
|
+
type ResolvedDevHostsPath = {
|
|
18
|
+
path: string;
|
|
19
|
+
fileName: string;
|
|
20
|
+
exists: boolean;
|
|
21
|
+
searchedFiles: string[];
|
|
22
|
+
configPattern?: ConfigPattern;
|
|
23
|
+
};
|
|
24
|
+
declare function getConfigFileCandidates(options?: ReadDevHostsOptions): string[];
|
|
25
|
+
declare function resolveDevHostsPath(options?: ReadDevHostsOptions): ResolvedDevHostsPath;
|
|
26
|
+
declare function getDevHostsPath(options?: ReadDevHostsOptions): string;
|
|
27
|
+
declare function readDevHosts(options?: ReadDevHostsOptions | string): DevHostEntry[];
|
|
28
|
+
declare function getProjectName(cwd?: string): string;
|
|
29
|
+
declare function sanitizeProjectName(value: string): string;
|
|
30
|
+
|
|
31
|
+
export { type ConfigPattern as C, type DevHostEntry as D, LOCALGHOST_CONFIG_FILE as L, type ReadDevHostsOptions as R, type ResolvedDevHostsPath as a, getDevHostsPath as b, getProjectName as c, resolveDevHostsPath as d, findLocalMdnsHosts as f, getConfigFileCandidates as g, parseDevHosts as p, readDevHosts as r, sanitizeProjectName as s };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { D as DevHostEntry } from './config-Cde1Bich.js';
|
|
2
|
+
export { C as ConfigPattern, L as LOCALGHOST_CONFIG_FILE, R as ReadDevHostsOptions, a as ResolvedDevHostsPath, f as findLocalMdnsHosts, g as getConfigFileCandidates, b as getDevHostsPath, c as getProjectName, p as parseDevHosts, r as readDevHosts, d as resolveDevHostsPath, s as sanitizeProjectName } from './config-Cde1Bich.js';
|
|
3
|
+
|
|
4
|
+
declare function getCaddyfilePath(cwd?: string): string;
|
|
5
|
+
declare function renderCaddyfile(entries: DevHostEntry[]): string;
|
|
6
|
+
declare function writeCaddyfile(entries: DevHostEntry[], cwd?: string): Promise<string>;
|
|
7
|
+
declare function validateCaddyfile(path: string): Promise<void>;
|
|
8
|
+
declare function runCaddy(path: string): Promise<void>;
|
|
9
|
+
|
|
10
|
+
type DoctorResult = {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
caddy: {
|
|
13
|
+
found: boolean;
|
|
14
|
+
version?: string;
|
|
15
|
+
installHint: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
declare function checkCaddy(): Promise<DoctorResult["caddy"]>;
|
|
19
|
+
declare function runDoctor(): Promise<DoctorResult>;
|
|
20
|
+
|
|
21
|
+
type UpdateSystemHostsResult = {
|
|
22
|
+
changed: boolean;
|
|
23
|
+
hostsPath: string;
|
|
24
|
+
tempPath?: string;
|
|
25
|
+
};
|
|
26
|
+
type RemoveSystemHostsResult = UpdateSystemHostsResult & {
|
|
27
|
+
removed: boolean;
|
|
28
|
+
};
|
|
29
|
+
declare function getSystemHostsPath(): "C:\\Windows\\System32\\drivers\\etc\\hosts" | "/etc/hosts";
|
|
30
|
+
declare function renderHostsBlock(projectName: string, entries: DevHostEntry[]): string;
|
|
31
|
+
declare function upsertManagedBlock(existing: string, projectName: string, block: string): string;
|
|
32
|
+
declare function removeManagedBlock(existing: string, projectName: string): string;
|
|
33
|
+
declare function updateSystemHosts(projectName: string, entries: DevHostEntry[]): Promise<UpdateSystemHostsResult>;
|
|
34
|
+
declare function removeSystemHosts(projectName: string): Promise<RemoveSystemHostsResult>;
|
|
35
|
+
|
|
36
|
+
type PackageManager = "npm" | "yarn" | "pnpm";
|
|
37
|
+
type InitOptions = {
|
|
38
|
+
cwd?: string;
|
|
39
|
+
host?: string;
|
|
40
|
+
port?: number;
|
|
41
|
+
apiHost?: string;
|
|
42
|
+
apiPort?: number;
|
|
43
|
+
force?: boolean;
|
|
44
|
+
packageManager?: PackageManager;
|
|
45
|
+
writeScripts?: boolean;
|
|
46
|
+
configFile?: string;
|
|
47
|
+
};
|
|
48
|
+
type InitResult = {
|
|
49
|
+
configPath: string;
|
|
50
|
+
configCreated: boolean;
|
|
51
|
+
packageJsonPath?: string;
|
|
52
|
+
packageJsonChanged: boolean;
|
|
53
|
+
packageManager: PackageManager;
|
|
54
|
+
nextSteps: string[];
|
|
55
|
+
};
|
|
56
|
+
declare function detectPackageManager(cwd?: string): PackageManager;
|
|
57
|
+
declare function packageRunCommand(packageManager: PackageManager, script: string): string;
|
|
58
|
+
declare function packageAddCommand(packageManager: PackageManager, packageName?: string): string;
|
|
59
|
+
declare function initLocalghost(options?: InitOptions): InitResult;
|
|
60
|
+
|
|
61
|
+
type DomainRoute = {
|
|
62
|
+
host: string;
|
|
63
|
+
port: number;
|
|
64
|
+
url: string;
|
|
65
|
+
upstream: string;
|
|
66
|
+
};
|
|
67
|
+
type DomainRouteOptions = {
|
|
68
|
+
https?: boolean;
|
|
69
|
+
};
|
|
70
|
+
declare function getDomainRoutes(entries: DevHostEntry[], options?: DomainRouteOptions): DomainRoute[];
|
|
71
|
+
declare function formatDomainRoutes(entries: DevHostEntry[], options?: DomainRouteOptions): string;
|
|
72
|
+
|
|
73
|
+
declare const LOCALGHOST_STATE_FILE = "ops/local/localghost-state.json";
|
|
74
|
+
type LocalghostStateAction = "setup" | "teardown";
|
|
75
|
+
type LocalghostState = {
|
|
76
|
+
version: 1;
|
|
77
|
+
action: LocalghostStateAction;
|
|
78
|
+
updatedAt: string;
|
|
79
|
+
projectName: string;
|
|
80
|
+
cwd: string;
|
|
81
|
+
configPath?: string;
|
|
82
|
+
hostsPath?: string;
|
|
83
|
+
hostsChanged?: boolean;
|
|
84
|
+
hostsTempPath?: string;
|
|
85
|
+
caddyfilePath?: string;
|
|
86
|
+
caddyfileRemoved?: boolean;
|
|
87
|
+
entries?: DevHostEntry[];
|
|
88
|
+
};
|
|
89
|
+
type WriteLocalghostStateInput = Omit<LocalghostState, "version" | "updatedAt">;
|
|
90
|
+
declare function getLocalghostStatePath(cwd?: string): string;
|
|
91
|
+
declare function readLocalghostState(cwd?: string): LocalghostState | null;
|
|
92
|
+
declare function writeLocalghostState(cwd: string, state: WriteLocalghostStateInput): string;
|
|
93
|
+
|
|
94
|
+
declare const LOCALGHOST_PACKAGE_NAME = "@hamedb89/localghost";
|
|
95
|
+
declare const LOCALGHOST_VERSION = "0.1.0";
|
|
96
|
+
declare const UPDATE_CHECK_CACHE_TTL_MS: number;
|
|
97
|
+
declare const UPDATE_CHECK_NOTIFY_TTL_MS: number;
|
|
98
|
+
declare const UPDATE_CHECK_TIMEOUT_MS = 900;
|
|
99
|
+
type UpdateCheckCache = {
|
|
100
|
+
checkedAt: string;
|
|
101
|
+
latestVersion?: string;
|
|
102
|
+
notifiedVersion?: string;
|
|
103
|
+
notifiedAt?: string;
|
|
104
|
+
};
|
|
105
|
+
type UpdateCheckResult = {
|
|
106
|
+
currentVersion: string;
|
|
107
|
+
packageName: string;
|
|
108
|
+
latestVersion?: string;
|
|
109
|
+
updateAvailable: boolean;
|
|
110
|
+
source: "cache" | "registry" | "disabled" | "error";
|
|
111
|
+
error?: string;
|
|
112
|
+
};
|
|
113
|
+
declare function isUpdateCheckDisabled(env?: NodeJS.ProcessEnv): boolean;
|
|
114
|
+
declare function getUpdateCheckCachePath(env?: NodeJS.ProcessEnv): string;
|
|
115
|
+
declare function compareVersions(a: string, b: string): number;
|
|
116
|
+
declare function isNewerVersion(candidate: string | undefined, current?: string): boolean;
|
|
117
|
+
declare function checkForUpdate(options?: {
|
|
118
|
+
force?: boolean;
|
|
119
|
+
packageName?: string;
|
|
120
|
+
currentVersion?: string;
|
|
121
|
+
timeoutMs?: number;
|
|
122
|
+
cachePath?: string;
|
|
123
|
+
env?: NodeJS.ProcessEnv;
|
|
124
|
+
}): Promise<UpdateCheckResult>;
|
|
125
|
+
declare function formatUpdateMessage(result: UpdateCheckResult): string | null;
|
|
126
|
+
declare function shouldNotifyAboutUpdate(result: UpdateCheckResult, cachePath?: string, now?: number): boolean;
|
|
127
|
+
declare function markUpdateNotified(result: UpdateCheckResult, cachePath?: string): void;
|
|
128
|
+
declare function maybeNotifyAboutUpdate(options?: {
|
|
129
|
+
disabled?: boolean;
|
|
130
|
+
}): Promise<void>;
|
|
131
|
+
|
|
132
|
+
export { DevHostEntry, type DoctorResult, type DomainRoute, type DomainRouteOptions, type InitOptions, type InitResult, LOCALGHOST_PACKAGE_NAME, LOCALGHOST_STATE_FILE, LOCALGHOST_VERSION, type LocalghostState, type LocalghostStateAction, type PackageManager, type RemoveSystemHostsResult, UPDATE_CHECK_CACHE_TTL_MS, UPDATE_CHECK_NOTIFY_TTL_MS, UPDATE_CHECK_TIMEOUT_MS, type UpdateCheckCache, type UpdateCheckResult, type UpdateSystemHostsResult, type WriteLocalghostStateInput, checkCaddy, checkForUpdate, compareVersions, detectPackageManager, formatDomainRoutes, formatUpdateMessage, getCaddyfilePath, getDomainRoutes, getLocalghostStatePath, getSystemHostsPath, getUpdateCheckCachePath, initLocalghost, isNewerVersion, isUpdateCheckDisabled, markUpdateNotified, maybeNotifyAboutUpdate, packageAddCommand, packageRunCommand, readLocalghostState, removeManagedBlock, removeSystemHosts, renderCaddyfile, renderHostsBlock, runCaddy, runDoctor, shouldNotifyAboutUpdate, updateSystemHosts, upsertManagedBlock, validateCaddyfile, writeCaddyfile, writeLocalghostState };
|