@hamedb89/localghost 0.1.3 → 0.1.6

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/dist/index.js CHANGED
@@ -1,6 +1,100 @@
1
+ // src/activity.ts
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3
+ import { homedir } from "os";
4
+ import { dirname, join } from "path";
5
+ var LOCALGHOST_ACTIVITY_VERSION = 1;
6
+ function getLocalghostActivityPath(env = process.env) {
7
+ if (env.LOCALGHOST_ACTIVITY_PATH) return env.LOCALGHOST_ACTIVITY_PATH;
8
+ const stateRoot = env.XDG_STATE_HOME || join(homedir(), ".local/state");
9
+ return join(stateRoot, "localghost", "activity.json");
10
+ }
11
+ function isProcessRunning(pid) {
12
+ if (!Number.isInteger(pid) || pid < 1) return false;
13
+ try {
14
+ process.kill(pid, 0);
15
+ return true;
16
+ } catch (error) {
17
+ const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
18
+ return code === "EPERM";
19
+ }
20
+ }
21
+ function emptyActivity() {
22
+ return { version: LOCALGHOST_ACTIVITY_VERSION, runs: [] };
23
+ }
24
+ function readLocalghostActivity(path = getLocalghostActivityPath()) {
25
+ if (!existsSync(path)) return emptyActivity();
26
+ try {
27
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
28
+ return {
29
+ version: LOCALGHOST_ACTIVITY_VERSION,
30
+ runs: Array.isArray(parsed.runs) ? parsed.runs : []
31
+ };
32
+ } catch {
33
+ return emptyActivity();
34
+ }
35
+ }
36
+ function writeLocalghostActivity(activity, path = getLocalghostActivityPath()) {
37
+ mkdirSync(dirname(path), { recursive: true });
38
+ writeFileSync(path, `${JSON.stringify(activity, null, 2)}
39
+ `, "utf8");
40
+ return path;
41
+ }
42
+ function createRunId(input, pid) {
43
+ return `${input.projectName}:${input.mode}:${pid}:${Date.now()}`;
44
+ }
45
+ function pruneLocalghostActivity(path = getLocalghostActivityPath()) {
46
+ const activity = readLocalghostActivity(path);
47
+ const activeRuns = activity.runs.filter((run) => isProcessRunning(run.pid));
48
+ const pruned = activeRuns.length !== activity.runs.length;
49
+ if (pruned) {
50
+ writeLocalghostActivity({ version: LOCALGHOST_ACTIVITY_VERSION, runs: activeRuns }, path);
51
+ }
52
+ return {
53
+ path,
54
+ pruned,
55
+ runs: activeRuns
56
+ };
57
+ }
58
+ function listLocalghostRuns(path = getLocalghostActivityPath()) {
59
+ return pruneLocalghostActivity(path).runs;
60
+ }
61
+ function registerLocalghostRun(input, path = getLocalghostActivityPath()) {
62
+ const now = (/* @__PURE__ */ new Date()).toISOString();
63
+ const pid = input.pid ?? process.pid;
64
+ const record = {
65
+ id: input.id ?? createRunId(input, pid),
66
+ mode: input.mode,
67
+ pid,
68
+ cwd: input.cwd,
69
+ projectName: input.projectName,
70
+ startedAt: input.startedAt ?? now,
71
+ updatedAt: now,
72
+ ...input.configPath ? { configPath: input.configPath } : {},
73
+ ...input.caddyfilePath ? { caddyfilePath: input.caddyfilePath } : {},
74
+ ...input.caddyPid ? { caddyPid: input.caddyPid } : {},
75
+ ...input.childPid ? { childPid: input.childPid } : {},
76
+ ...input.childCommand ? { childCommand: input.childCommand } : {},
77
+ ...typeof input.https === "boolean" ? { https: input.https } : {},
78
+ ...input.requestedPort ? { requestedPort: input.requestedPort } : {},
79
+ ...input.port ? { port: input.port } : {},
80
+ ...typeof input.dynamicPort === "boolean" ? { dynamicPort: input.dynamicPort } : {},
81
+ entries: input.entries
82
+ };
83
+ const current = pruneLocalghostActivity(path).runs.filter((run) => run.id !== record.id);
84
+ writeLocalghostActivity({ version: LOCALGHOST_ACTIVITY_VERSION, runs: [...current, record] }, path);
85
+ return record;
86
+ }
87
+ function unregisterLocalghostRun(id, path = getLocalghostActivityPath()) {
88
+ const activity = readLocalghostActivity(path);
89
+ const runs = activity.runs.filter((run) => run.id !== id);
90
+ if (runs.length !== activity.runs.length) {
91
+ writeLocalghostActivity({ version: LOCALGHOST_ACTIVITY_VERSION, runs }, path);
92
+ }
93
+ }
94
+
1
95
  // src/config.ts
2
- import { existsSync, readFileSync, readdirSync } from "fs";
3
- import { basename, join, resolve } from "path";
96
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync } from "fs";
97
+ import { basename, join as join2, resolve } from "path";
4
98
 
5
99
  // src/parse.ts
6
100
  var HOST_PATTERN = /^(?=.{1,253}$)(?!-)[a-z0-9-]+(\.[a-z0-9-]+)*\.?$/i;
@@ -68,7 +162,7 @@ function resolveDevHostsPath(options = {}) {
68
162
  const searchedFiles = getConfigFileCandidates(options);
69
163
  for (const fileName2 of searchedFiles) {
70
164
  const path = resolve(cwd, fileName2);
71
- if (existsSync(path)) {
165
+ if (existsSync2(path)) {
72
166
  return {
73
167
  path,
74
168
  fileName: basename(fileName2),
@@ -104,11 +198,11 @@ function readDevHosts(options = {}) {
104
198
  `Missing Localghost config in ${cwd}. Looked for ${formatSearchedFiles(resolvedPath.searchedFiles, resolvedPath.configPattern)}. Run \`localghost init\` or pass --config/--config-pattern.`
105
199
  );
106
200
  }
107
- return parseDevHosts(readFileSync(resolvedPath.path, "utf8"), resolvedPath.fileName);
201
+ return parseDevHosts(readFileSync2(resolvedPath.path, "utf8"), resolvedPath.fileName);
108
202
  }
109
203
  function getProjectName(cwd = process.cwd()) {
110
204
  try {
111
- const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
205
+ const pkg = JSON.parse(readFileSync2(join2(cwd, "package.json"), "utf8"));
112
206
  const name = typeof pkg.name === "string" && pkg.name ? pkg.name : "app";
113
207
  return sanitizeProjectName(name.replace(/^@/, ""));
114
208
  } catch {
@@ -121,18 +215,18 @@ function sanitizeProjectName(value) {
121
215
  }
122
216
 
123
217
  // src/caddy.ts
124
- import { dirname as dirname2, join as join2 } from "path";
218
+ import { dirname as dirname3, join as join3 } from "path";
125
219
  import { execa } from "execa";
126
220
 
127
221
  // src/fs.ts
128
- import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
129
- import { dirname } from "path";
222
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
223
+ import { dirname as dirname2 } from "path";
130
224
  function readTextFile(path) {
131
- return readFileSync2(path, "utf8");
225
+ return readFileSync3(path, "utf8");
132
226
  }
133
227
  function writeTextFile(path, value) {
134
- mkdirSync(dirname(path), { recursive: true });
135
- writeFileSync(path, value, "utf8");
228
+ mkdirSync2(dirname2(path), { recursive: true });
229
+ writeFileSync2(path, value, "utf8");
136
230
  return path;
137
231
  }
138
232
 
@@ -147,41 +241,140 @@ function groupByPort(entries) {
147
241
  return groups;
148
242
  }
149
243
  function getCaddyfilePath(cwd = process.cwd()) {
150
- return join2(cwd, "ops/local/Caddyfile");
244
+ return join3(cwd, "ops/local/Caddyfile");
151
245
  }
152
- function renderCaddyfile(entries) {
246
+ function renderCaddyfile(entries, options = {}) {
153
247
  const groups = groupByPort(entries);
248
+ const https = options.https === true;
154
249
  const blocks = [...groups.entries()].sort(([leftPort], [rightPort]) => leftPort - rightPort).map(([port, group]) => {
155
- const hosts = group.map((entry) => entry.host).sort().join(", ");
250
+ const hosts = group.map((entry) => https ? entry.host : `http://${entry.host}`).sort().join(", ");
156
251
  return `${hosts} {
157
252
  reverse_proxy 127.0.0.1:${port}
158
253
  }`;
159
254
  });
160
- return `{
255
+ const globalOptions = https ? `{
161
256
  local_certs
162
257
  }
163
258
 
164
- ${blocks.join("\n\n")}
259
+ ` : "";
260
+ return `${globalOptions}${blocks.join("\n\n")}
165
261
  `;
166
262
  }
167
- async function writeCaddyfile(entries, cwd = process.cwd()) {
263
+ async function writeCaddyfile(entries, cwd = process.cwd(), options = {}) {
168
264
  const path = getCaddyfilePath(cwd);
169
- writeTextFile(path, renderCaddyfile(entries));
265
+ writeTextFile(path, renderCaddyfile(entries, options));
170
266
  return path;
171
267
  }
172
268
  async function validateCaddyfile(path) {
173
269
  await execa("caddy", ["validate", "--config", path], {
174
- cwd: dirname2(path),
270
+ cwd: dirname3(path),
175
271
  stdio: "inherit"
176
272
  });
177
273
  }
178
274
  async function runCaddy(path) {
179
275
  await execa("caddy", ["run", "--config", path], {
180
- cwd: dirname2(path),
276
+ cwd: dirname3(path),
277
+ stdio: "inherit"
278
+ });
279
+ }
280
+ function startCaddy(path) {
281
+ return execa("caddy", ["run", "--config", path], {
282
+ cwd: dirname3(path),
181
283
  stdio: "inherit"
182
284
  });
183
285
  }
184
286
 
287
+ // src/port.ts
288
+ import { createServer } from "net";
289
+ async function isPortAvailable(port, host = "127.0.0.1") {
290
+ return new Promise((resolve2) => {
291
+ const server = createServer();
292
+ server.once("error", () => {
293
+ resolve2(false);
294
+ });
295
+ server.once("listening", () => {
296
+ server.close(() => resolve2(true));
297
+ });
298
+ server.listen(port, host);
299
+ });
300
+ }
301
+ async function findAvailablePort(startPort, options = {}) {
302
+ const host = options.host ?? "127.0.0.1";
303
+ const maxAttempts = options.maxAttempts ?? 50;
304
+ for (let offset = 0; offset < maxAttempts; offset += 1) {
305
+ const port = startPort + offset;
306
+ if (await isPortAvailable(port, host)) {
307
+ return port;
308
+ }
309
+ }
310
+ throw new Error(`No available port found from ${startPort} to ${startPort + maxAttempts - 1}.`);
311
+ }
312
+
313
+ // src/context.ts
314
+ function parsePort(value) {
315
+ if (!value) return void 0;
316
+ const port = Number.parseInt(value, 10);
317
+ return Number.isInteger(port) && port > 0 && port <= 65535 ? port : void 0;
318
+ }
319
+ function envPort() {
320
+ return parsePort(process.env.LOCALGHOST_PORT) ?? parsePort(process.env.VITE_PORT);
321
+ }
322
+ function envDynamicPort() {
323
+ const value = process.env.LOCALGHOST_DYNAMIC_PORT;
324
+ if (!value) return void 0;
325
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
326
+ }
327
+ function readOptionsFromContext(options) {
328
+ return {
329
+ cwd: options.cwd ?? process.cwd(),
330
+ ...options.fileName ? { fileName: options.fileName } : {},
331
+ ...options.configFiles ? { configFiles: options.configFiles } : {},
332
+ ...options.configPattern ? { configPattern: options.configPattern } : {}
333
+ };
334
+ }
335
+ function withRuntimePort(entries, requestedPort, port) {
336
+ if (requestedPort === port) return entries;
337
+ const hasRequestedPort = entries.some((entry) => entry.port === requestedPort);
338
+ if (!hasRequestedPort) return entries;
339
+ return entries.map((entry) => entry.port === requestedPort ? { ...entry, port } : entry);
340
+ }
341
+ function uniqueHosts(entries) {
342
+ return [...new Set(entries.map((entry) => entry.host))];
343
+ }
344
+ function defineLocalghostConfig(config) {
345
+ return config;
346
+ }
347
+ async function resolveLocalghostContext(options = {}) {
348
+ const cwd = options.cwd ?? process.cwd();
349
+ const readOptions = readOptionsFromContext({ ...options, cwd });
350
+ const resolvedPath = resolveDevHostsPath(readOptions);
351
+ const configEntries = readDevHosts(readOptions);
352
+ const requestedPort = options.port ?? envPort() ?? configEntries[0]?.port ?? 5173;
353
+ const dynamicPort = options.dynamicPort ?? envDynamicPort() ?? false;
354
+ const bindHost = options.bindHost ?? "127.0.0.1";
355
+ const probeHost = typeof bindHost === "string" ? bindHost : "127.0.0.1";
356
+ const port = dynamicPort ? await findAvailablePort(requestedPort, { host: probeHost }) : requestedPort;
357
+ const entries = withRuntimePort(configEntries, requestedPort, port);
358
+ const hosts = uniqueHosts(entries);
359
+ const primaryHost = options.primaryHost ?? entries.find((entry) => entry.port === port)?.host ?? hosts[0] ?? `${sanitizeProjectName(getProjectName(cwd))}.localhost`;
360
+ return {
361
+ cwd,
362
+ projectName: sanitizeProjectName(options.project ?? getProjectName(cwd)),
363
+ readOptions,
364
+ configPath: resolvedPath.path,
365
+ configFileName: resolvedPath.fileName,
366
+ configEntries,
367
+ entries,
368
+ hosts,
369
+ requestedPort,
370
+ port,
371
+ dynamicPort,
372
+ bindHost,
373
+ primaryHost,
374
+ https: options.https === true
375
+ };
376
+ }
377
+
185
378
  // src/doctor.ts
186
379
  import { execa as execa2 } from "execa";
187
380
  async function checkCaddy() {
@@ -208,10 +401,34 @@ async function runDoctor() {
208
401
  };
209
402
  }
210
403
 
404
+ // src/env.ts
405
+ var PRODUCTION_ENV_KEYS = ["NODE_ENV", "VERCEL_ENV", "NETLIFY", "CF_PAGES_BRANCH", "LOCALGHOST_ENV"];
406
+ function getProductionReason(env = process.env) {
407
+ if (env.LOCALGHOST_ENV === "production") return "LOCALGHOST_ENV=production";
408
+ if (env.NODE_ENV === "production") return "NODE_ENV=production";
409
+ if (env.VERCEL_ENV === "production") return "VERCEL_ENV=production";
410
+ if (env.NETLIFY === "true" && env.CONTEXT === "production") return "NETLIFY=true and CONTEXT=production";
411
+ if (env.CF_PAGES_BRANCH && env.CF_PAGES_BRANCH === env.CF_PAGES_PRODUCTION_BRANCH) {
412
+ return "CF_PAGES_BRANCH matches CF_PAGES_PRODUCTION_BRANCH";
413
+ }
414
+ return null;
415
+ }
416
+ function isProductionLike(env = process.env) {
417
+ return getProductionReason(env) !== null;
418
+ }
419
+ function assertLocalDevelopment(command, env = process.env) {
420
+ const reason = getProductionReason(env);
421
+ if (!reason) return;
422
+ throw new Error(`Localghost only runs in local development. Refusing \`${command}\` because ${reason}.`);
423
+ }
424
+ function getProductionEnvKeys() {
425
+ return PRODUCTION_ENV_KEYS;
426
+ }
427
+
211
428
  // src/hosts-file.ts
212
- import { writeFileSync as writeFileSync2 } from "fs";
429
+ import { writeFileSync as writeFileSync3 } from "fs";
213
430
  import { tmpdir } from "os";
214
- import { join as join3 } from "path";
431
+ import { join as join4 } from "path";
215
432
  import { execa as execa3 } from "execa";
216
433
  function escapeRegExp(value) {
217
434
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -253,8 +470,8 @@ function removeManagedBlock(existing, projectName) {
253
470
  }
254
471
  async function writeSystemHostsFile(hostsPath, next, projectName) {
255
472
  const sanitizedProjectName = sanitizeProjectName(projectName);
256
- const tempPath = join3(tmpdir(), `localghost-${sanitizedProjectName}-hosts`);
257
- writeFileSync2(tempPath, next, "utf8");
473
+ const tempPath = join4(tmpdir(), `localghost-${sanitizedProjectName}-hosts`);
474
+ writeFileSync3(tempPath, next, "utf8");
258
475
  if (process.platform === "win32") {
259
476
  throw new Error(`Windows support: run as administrator and copy ${tempPath} to ${hostsPath}.`);
260
477
  }
@@ -286,11 +503,11 @@ async function removeSystemHosts(projectName) {
286
503
  }
287
504
 
288
505
  // src/init.ts
289
- import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
290
- import { join as join4 } from "path";
506
+ import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
507
+ import { join as join5 } from "path";
291
508
  function detectPackageManager(cwd = process.cwd()) {
292
- if (existsSync2(join4(cwd, "pnpm-lock.yaml"))) return "pnpm";
293
- if (existsSync2(join4(cwd, "yarn.lock"))) return "yarn";
509
+ if (existsSync3(join5(cwd, "pnpm-lock.yaml"))) return "pnpm";
510
+ if (existsSync3(join5(cwd, "yarn.lock"))) return "yarn";
294
511
  return "npm";
295
512
  }
296
513
  function packageRunCommand(packageManager, script) {
@@ -315,7 +532,7 @@ function renderConfig(options) {
315
532
  }
316
533
  function readPackageJson(path) {
317
534
  try {
318
- return JSON.parse(readFileSync3(path, "utf8"));
535
+ return JSON.parse(readFileSync4(path, "utf8"));
319
536
  } catch {
320
537
  return null;
321
538
  }
@@ -336,17 +553,24 @@ function updatePackageScripts(packageJsonPath, configFile) {
336
553
  ...scripts,
337
554
  "localghost:setup": scripts["localghost:setup"] ?? `localghost setup${configFlag}`,
338
555
  "localghost:proxy": scripts["localghost:proxy"] ?? `localghost dev${configFlag}`,
556
+ "localghost:proxy:https": scripts["localghost:proxy:https"] ?? `localghost dev${configFlag} --https`,
557
+ "localghost:run": scripts["localghost:run"] ?? `localghost run${configFlag} --`,
558
+ "localghost:ready": scripts["localghost:ready"] ?? `localghost status${configFlag} --ready`,
559
+ "localghost:ps": scripts["localghost:ps"] ?? "localghost ps",
339
560
  "localghost:print": scripts["localghost:print"] ?? `localghost print${configFlag}`,
340
561
  "localghost:routes": scripts["localghost:routes"] ?? `localghost routes${configFlag}`,
341
562
  "localghost:status": scripts["localghost:status"] ?? "localghost status",
563
+ "localghost:reset": scripts["localghost:reset"] ?? "localghost reset",
342
564
  "localghost:teardown": scripts["localghost:teardown"] ?? "localghost teardown",
343
565
  "localghost:doctor": scripts["localghost:doctor"] ?? "localghost doctor",
344
- "localghost:update": scripts["localghost:update"] ?? "localghost update"
566
+ "localghost:update": scripts["localghost:update"] ?? "localghost update",
567
+ "caddy:setup": scripts["caddy:setup"] ?? `localghost setup${configFlag}`,
568
+ "caddy:dev": scripts["caddy:dev"] ?? `localghost dev${configFlag}`
345
569
  };
346
570
  const changed = JSON.stringify(scripts) !== JSON.stringify(nextScripts);
347
571
  if (!changed) return false;
348
572
  pkg.scripts = nextScripts;
349
- writeFileSync3(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
573
+ writeFileSync4(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
350
574
  `, "utf8");
351
575
  return true;
352
576
  }
@@ -359,8 +583,8 @@ function initLocalghost(options = {}) {
359
583
  const apiPort = options.apiPort ?? 8787;
360
584
  const packageManager = options.packageManager ?? detectPackageManager(cwd);
361
585
  const configFile = options.configFile ?? LOCALGHOST_CONFIG_FILE;
362
- const configPath = join4(cwd, configFile);
363
- const configExists = existsSync2(configPath);
586
+ const configPath = join5(cwd, configFile);
587
+ const configExists = existsSync3(configPath);
364
588
  if (configExists && !options.force) {
365
589
  return {
366
590
  configPath,
@@ -370,22 +594,24 @@ function initLocalghost(options = {}) {
370
594
  nextSteps: [
371
595
  packageRunCommand(packageManager, "localghost:doctor"),
372
596
  packageRunCommand(packageManager, "localghost:setup"),
597
+ packageRunCommand(packageManager, "localghost:ready"),
373
598
  packageRunCommand(packageManager, "localghost:proxy")
374
599
  ]
375
600
  };
376
601
  }
377
602
  writeTextFile(configPath, renderConfig({ host, port, apiHost, apiPort }));
378
- const packageJsonPath = join4(cwd, "package.json");
603
+ const packageJsonPath = join5(cwd, "package.json");
379
604
  const packageJsonChanged = options.writeScripts ? updatePackageScripts(packageJsonPath, configFile) : false;
380
605
  return {
381
606
  configPath,
382
607
  configCreated: true,
383
- ...existsSync2(packageJsonPath) ? { packageJsonPath } : {},
608
+ ...existsSync3(packageJsonPath) ? { packageJsonPath } : {},
384
609
  packageJsonChanged,
385
610
  packageManager,
386
611
  nextSteps: [
387
612
  packageRunCommand(packageManager, "localghost:doctor"),
388
613
  packageRunCommand(packageManager, "localghost:setup"),
614
+ packageRunCommand(packageManager, "localghost:ready"),
389
615
  packageRunCommand(packageManager, "localghost:proxy")
390
616
  ]
391
617
  };
@@ -393,7 +619,7 @@ function initLocalghost(options = {}) {
393
619
 
394
620
  // src/routes.ts
395
621
  function getDomainRoutes(entries, options = {}) {
396
- const protocol = options.https === false ? "http" : "https";
622
+ const protocol = options.https === true ? "https" : "http";
397
623
  return [...entries].sort((left, right) => left.host.localeCompare(right.host) || left.port - right.port).map((entry) => ({
398
624
  host: entry.host,
399
625
  port: entry.port,
@@ -413,15 +639,15 @@ function formatDomainRoutes(entries, options = {}) {
413
639
  }
414
640
 
415
641
  // src/state.ts
416
- import { existsSync as existsSync3 } from "fs";
417
- import { join as join5 } from "path";
642
+ import { existsSync as existsSync4 } from "fs";
643
+ import { join as join6 } from "path";
418
644
  var LOCALGHOST_STATE_FILE = "ops/local/localghost-state.json";
419
645
  function getLocalghostStatePath(cwd = process.cwd()) {
420
- return join5(cwd, LOCALGHOST_STATE_FILE);
646
+ return join6(cwd, LOCALGHOST_STATE_FILE);
421
647
  }
422
648
  function readLocalghostState(cwd = process.cwd()) {
423
649
  const path = getLocalghostStatePath(cwd);
424
- if (!existsSync3(path)) return null;
650
+ if (!existsSync4(path)) return null;
425
651
  return JSON.parse(readTextFile(path));
426
652
  }
427
653
  function writeLocalghostState(cwd, state) {
@@ -432,11 +658,11 @@ function writeLocalghostState(cwd, state) {
432
658
  }
433
659
 
434
660
  // src/update-check.ts
435
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
436
- import { homedir } from "os";
437
- import { dirname as dirname3, join as join6 } from "path";
661
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
662
+ import { homedir as homedir2 } from "os";
663
+ import { dirname as dirname4, join as join7 } from "path";
438
664
  var LOCALGHOST_PACKAGE_NAME = "@hamedb89/localghost";
439
- var LOCALGHOST_VERSION = "0.1.0";
665
+ var LOCALGHOST_VERSION = "0.1.6";
440
666
  var UPDATE_CHECK_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
441
667
  var UPDATE_CHECK_NOTIFY_TTL_MS = 24 * 60 * 60 * 1e3;
442
668
  var UPDATE_CHECK_TIMEOUT_MS = 900;
@@ -448,21 +674,21 @@ function isUpdateCheckDisabled(env = process.env) {
448
674
  }
449
675
  function getUpdateCheckCachePath(env = process.env) {
450
676
  if (env.LOCALGHOST_UPDATE_CHECK_CACHE) return env.LOCALGHOST_UPDATE_CHECK_CACHE;
451
- const cacheRoot = env.XDG_CACHE_HOME || join6(homedir(), ".cache");
452
- return join6(cacheRoot, "localghost", "update-check.json");
677
+ const cacheRoot = env.XDG_CACHE_HOME || join7(homedir2(), ".cache");
678
+ return join7(cacheRoot, "localghost", "update-check.json");
453
679
  }
454
680
  function readCache(path = getUpdateCheckCachePath()) {
455
- if (!existsSync4(path)) return null;
681
+ if (!existsSync5(path)) return null;
456
682
  try {
457
- return JSON.parse(readFileSync4(path, "utf8"));
683
+ return JSON.parse(readFileSync5(path, "utf8"));
458
684
  } catch {
459
685
  return null;
460
686
  }
461
687
  }
462
688
  function writeCache(cache, path = getUpdateCheckCachePath()) {
463
689
  try {
464
- mkdirSync2(dirname3(path), { recursive: true });
465
- writeFileSync4(path, `${JSON.stringify(cache, null, 2)}
690
+ mkdirSync3(dirname4(path), { recursive: true });
691
+ writeFileSync5(path, `${JSON.stringify(cache, null, 2)}
466
692
  `, "utf8");
467
693
  } catch {
468
694
  }
@@ -598,6 +824,7 @@ ${message}`);
598
824
  markUpdateNotified(result, cachePath);
599
825
  }
600
826
  export {
827
+ LOCALGHOST_ACTIVITY_VERSION,
601
828
  LOCALGHOST_CONFIG_FILE,
602
829
  LOCALGHOST_PACKAGE_NAME,
603
830
  LOCALGHOST_STATE_FILE,
@@ -605,10 +832,13 @@ export {
605
832
  UPDATE_CHECK_CACHE_TTL_MS,
606
833
  UPDATE_CHECK_NOTIFY_TTL_MS,
607
834
  UPDATE_CHECK_TIMEOUT_MS,
835
+ assertLocalDevelopment,
608
836
  checkCaddy,
609
837
  checkForUpdate,
610
838
  compareVersions,
839
+ defineLocalghostConfig,
611
840
  detectPackageManager,
841
+ findAvailablePort,
612
842
  findLocalMdnsHosts,
613
843
  formatDomainRoutes,
614
844
  formatUpdateMessage,
@@ -616,33 +846,47 @@ export {
616
846
  getConfigFileCandidates,
617
847
  getDevHostsPath,
618
848
  getDomainRoutes,
849
+ getLocalghostActivityPath,
619
850
  getLocalghostStatePath,
851
+ getProductionEnvKeys,
852
+ getProductionReason,
620
853
  getProjectName,
621
854
  getSystemHostsPath,
622
855
  getUpdateCheckCachePath,
623
856
  initLocalghost,
624
857
  isNewerVersion,
858
+ isPortAvailable,
859
+ isProcessRunning,
860
+ isProductionLike,
625
861
  isUpdateCheckDisabled,
862
+ listLocalghostRuns,
626
863
  markUpdateNotified,
627
864
  maybeNotifyAboutUpdate,
628
865
  packageAddCommand,
629
866
  packageRunCommand,
630
867
  parseDevHosts,
868
+ pruneLocalghostActivity,
631
869
  readDevHosts,
870
+ readLocalghostActivity,
632
871
  readLocalghostState,
872
+ registerLocalghostRun,
633
873
  removeManagedBlock,
634
874
  removeSystemHosts,
635
875
  renderCaddyfile,
636
876
  renderHostsBlock,
637
877
  resolveDevHostsPath,
878
+ resolveLocalghostContext,
638
879
  runCaddy,
639
880
  runDoctor,
640
881
  sanitizeProjectName,
641
882
  shouldNotifyAboutUpdate,
883
+ startCaddy,
884
+ unregisterLocalghostRun,
642
885
  updateSystemHosts,
643
886
  upsertManagedBlock,
644
887
  validateCaddyfile,
645
888
  writeCaddyfile,
889
+ writeLocalghostActivity,
646
890
  writeLocalghostState
647
891
  };
648
892
  //# sourceMappingURL=index.js.map