@stacksjs/rpx 0.5.0 → 0.5.1

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
@@ -20467,7 +20467,7 @@ var quotes = collect([
20467
20467
  ]);
20468
20468
  var export_prompts = import_prompts.default;
20469
20469
  // package.json
20470
- var version = "0.5.0";
20470
+ var version = "0.5.1";
20471
20471
 
20472
20472
  // src/config.ts
20473
20473
  import { homedir } from "os";
@@ -20541,14 +20541,179 @@ var config4 = await loadConfig({
20541
20541
  });
20542
20542
 
20543
20543
  // src/hosts.ts
20544
- import { spawn } from "child_process";
20545
- import fs5 from "fs";
20546
- import os3 from "os";
20547
- import path4 from "path";
20544
+ import { exec } from "child_process";
20545
+ import fs from "fs";
20546
+ import os2 from "os";
20547
+ import path from "path";
20548
20548
  import process3 from "process";
20549
+ import { promisify } from "util";
20550
+
20551
+ // src/utils.ts
20552
+ function debugLog(category, message, verbose) {
20553
+ if (verbose) {
20554
+ console.debug(`[rpx:${category}] ${message}`);
20555
+ }
20556
+ }
20557
+ function extractHostname(options2) {
20558
+ if (isMultiProxyOptions(options2)) {
20559
+ return options2.proxies.map((proxy) => {
20560
+ const domain = proxy.to || "stacks.localhost";
20561
+ return domain.startsWith("http") ? new URL(domain).hostname : domain;
20562
+ });
20563
+ }
20564
+ if (isSingleProxyOptions(options2)) {
20565
+ const domain = options2.to || "stacks.localhost";
20566
+ return [domain.startsWith("http") ? new URL(domain).hostname : domain];
20567
+ }
20568
+ return ["stacks.localhost"];
20569
+ }
20570
+ function isValidRootCA(value) {
20571
+ return typeof value === "object" && value !== null && "certificate" in value && "privateKey" in value && typeof value.certificate === "string" && typeof value.privateKey === "string";
20572
+ }
20573
+ function getPrimaryDomain(options2) {
20574
+ if (!options2)
20575
+ return "stacks.localhost";
20576
+ if (isMultiProxyOptions(options2) && options2.proxies.length > 0)
20577
+ return options2.proxies[0].to || "stacks.localhost";
20578
+ if (isSingleProxyOptions(options2))
20579
+ return options2.to || "stacks.localhost";
20580
+ return "stacks.localhost";
20581
+ }
20582
+ function isMultiProxyConfig(options2) {
20583
+ return "proxies" in options2 && Array.isArray(options2.proxies);
20584
+ }
20585
+ function isMultiProxyOptions(options2) {
20586
+ return "proxies" in options2 && Array.isArray(options2.proxies);
20587
+ }
20588
+ function isSingleProxyOptions(options2) {
20589
+ return "to" in options2 && typeof options2.to === "string";
20590
+ }
20591
+
20592
+ // src/hosts.ts
20593
+ var execAsync = promisify(exec);
20594
+ var hostsFilePath = process3.platform === "win32" ? path.join(process3.env.windir || "C:\\Windows", "System32", "drivers", "etc", "hosts") : "/etc/hosts";
20595
+ async function execSudo(command) {
20596
+ if (process3.platform === "win32")
20597
+ throw new Error("Administrator privileges required on Windows");
20598
+ try {
20599
+ await execAsync(`sudo ${command}`);
20600
+ } catch (error) {
20601
+ throw new Error(`Failed to execute sudo command: ${error.message}`);
20602
+ }
20603
+ }
20604
+ async function addHosts(hosts, verbose) {
20605
+ debugLog("hosts", `Adding hosts: ${hosts.join(", ")}`, verbose);
20606
+ debugLog("hosts", `Using hosts file at: ${hostsFilePath}`, verbose);
20607
+ try {
20608
+ const existingContent = await fs.promises.readFile(hostsFilePath, "utf-8");
20609
+ const newEntries = hosts.filter((host) => {
20610
+ const ipv4Entry = `127.0.0.1 ${host}`;
20611
+ const ipv6Entry = `::1 ${host}`;
20612
+ return !existingContent.includes(ipv4Entry) && !existingContent.includes(ipv6Entry);
20613
+ });
20614
+ if (newEntries.length === 0) {
20615
+ debugLog("hosts", "All hosts already exist in hosts file", verbose);
20616
+ log.info("All hosts are already in the hosts file");
20617
+ return;
20618
+ }
20619
+ const hostEntries = newEntries.map((host) => `
20620
+ # Added by rpx
20621
+ 127.0.0.1 ${host}
20622
+ ::1 ${host}`).join(`
20623
+ `);
20624
+ const tmpFile = path.join(os2.tmpdir(), "hosts.tmp");
20625
+ await fs.promises.writeFile(tmpFile, existingContent + hostEntries, "utf8");
20626
+ try {
20627
+ await execSudo(`cp "${tmpFile}" "${hostsFilePath}"`);
20628
+ log.success(`Added new hosts: ${newEntries.join(", ")}`);
20629
+ } catch (error) {
20630
+ log.error("Failed to modify hosts file automatically");
20631
+ log.warn("Please add these entries to your hosts file manually:");
20632
+ hostEntries.split(`
20633
+ `).forEach((entry) => log.warn(entry));
20634
+ if (process3.platform === "win32") {
20635
+ log.warn(`
20636
+ On Windows:`);
20637
+ log.warn("1. Run notepad as administrator");
20638
+ log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
20639
+ } else {
20640
+ log.warn(`
20641
+ On Unix systems:`);
20642
+ log.warn(`sudo nano ${hostsFilePath}`);
20643
+ }
20644
+ throw new Error("Failed to modify hosts file: manual intervention required");
20645
+ } finally {
20646
+ fs.unlinkSync(tmpFile);
20647
+ }
20648
+ } catch (err2) {
20649
+ const error = err2;
20650
+ log.error(`Failed to manage hosts file: ${error.message}`);
20651
+ throw error;
20652
+ }
20653
+ }
20654
+ async function removeHosts(hosts, verbose) {
20655
+ debugLog("hosts", `Removing hosts: ${hosts.join(", ")}`, verbose);
20656
+ try {
20657
+ const content = await fs.promises.readFile(hostsFilePath, "utf-8");
20658
+ const lines = content.split(`
20659
+ `);
20660
+ const filteredLines = lines.filter((line, index) => {
20661
+ if (line.trim() === "# Added by rpx") {
20662
+ lines.splice(index + 1, 2);
20663
+ return false;
20664
+ }
20665
+ return true;
20666
+ });
20667
+ while (filteredLines[filteredLines.length - 1]?.trim() === "")
20668
+ filteredLines.pop();
20669
+ const newContent = `${filteredLines.join(`
20670
+ `)}
20671
+ `;
20672
+ const tmpFile = path.join(os2.tmpdir(), "hosts.tmp");
20673
+ await fs.promises.writeFile(tmpFile, newContent, "utf8");
20674
+ try {
20675
+ await execSudo(`cp "${tmpFile}" "${hostsFilePath}"`);
20676
+ log.success("Hosts removed successfully");
20677
+ } catch (error) {
20678
+ log.error("Failed to modify hosts file automatically");
20679
+ log.warn("Please remove these entries from your hosts file manually:");
20680
+ hosts.forEach((host) => {
20681
+ log.warn("# Added by rpx");
20682
+ log.warn(`127.0.0.1 ${host}`);
20683
+ log.warn(`::1 ${host}`);
20684
+ });
20685
+ if (process3.platform === "win32") {
20686
+ log.warn(`
20687
+ On Windows:`);
20688
+ log.warn("1. Run notepad as administrator");
20689
+ log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
20690
+ } else {
20691
+ log.warn(`
20692
+ On Unix systems:`);
20693
+ log.warn(`sudo nano ${hostsFilePath}`);
20694
+ }
20695
+ throw new Error("Failed to modify hosts file: manual intervention required");
20696
+ } finally {
20697
+ fs.unlinkSync(tmpFile);
20698
+ }
20699
+ } catch (err2) {
20700
+ const error = err2;
20701
+ log.error(`Failed to remove hosts: ${error.message}`);
20702
+ throw error;
20703
+ }
20704
+ }
20705
+ async function checkHosts(hosts, verbose) {
20706
+ debugLog("hosts", `Checking hosts: ${hosts}`, verbose);
20707
+ const content = await fs.promises.readFile(hostsFilePath, "utf-8");
20708
+ return hosts.map((host) => {
20709
+ const ipv4Entry = `127.0.0.1 ${host}`;
20710
+ const ipv6Entry = `::1 ${host}`;
20711
+ return content.includes(ipv4Entry) || content.includes(ipv6Entry);
20712
+ });
20713
+ }
20549
20714
 
20550
20715
  // src/https.ts
20551
- import fs3 from "fs/promises";
20716
+ import fs5 from "fs/promises";
20552
20717
  import { homedir as homedir2 } from "os";
20553
20718
  import { join as join4 } from "path";
20554
20719
 
@@ -20589,7 +20754,7 @@ import process8 from "process";
20589
20754
  import process102 from "process";
20590
20755
  import process182 from "process";
20591
20756
  import process112 from "process";
20592
- import os2 from "os";
20757
+ import os3 from "os";
20593
20758
  import tty32 from "tty";
20594
20759
  import process142 from "process";
20595
20760
  import process132 from "process";
@@ -20598,11 +20763,11 @@ import process162 from "process";
20598
20763
  import process172 from "process";
20599
20764
  import process192 from "process";
20600
20765
  import os22 from "os";
20601
- import path from "path";
20766
+ import path2 from "path";
20602
20767
  import { resolve as resolve3 } from "path";
20603
20768
  import process22 from "process";
20604
- import fs from "fs";
20605
- import path2 from "path";
20769
+ import fs3 from "fs";
20770
+ import path22 from "path";
20606
20771
  var __create3 = Object.create;
20607
20772
  var __getProtoOf3 = Object.getPrototypeOf;
20608
20773
  var __defProp3 = Object.defineProperty;
@@ -48126,29 +48291,29 @@ var log2 = {
48126
48291
  },
48127
48292
  echo: (...args) => console.log(...args)
48128
48293
  };
48129
- function userDatabasePath2(path22) {
48130
- return projectPath2(`database/${path22 || ""}`);
48294
+ function userDatabasePath2(path23) {
48295
+ return projectPath2(`database/${path23 || ""}`);
48131
48296
  }
48132
- function appPath2(path22) {
48133
- return projectPath2(`app/${path22 || ""}`);
48297
+ function appPath2(path23) {
48298
+ return projectPath2(`app/${path23 || ""}`);
48134
48299
  }
48135
- function commandsPath2(path22) {
48136
- return appPath2(`Commands/${path22 || ""}`);
48300
+ function commandsPath2(path23) {
48301
+ return appPath2(`Commands/${path23 || ""}`);
48137
48302
  }
48138
- function logsPath2(path22) {
48139
- return storagePath2(`logs/${path22 || ""}`);
48303
+ function logsPath2(path23) {
48304
+ return storagePath2(`logs/${path23 || ""}`);
48140
48305
  }
48141
48306
  function projectPath2(filePath = "", options2) {
48142
- let path22 = process52.cwd();
48143
- while (path22.includes("storage"))
48144
- path22 = resolve22(path22, "..");
48145
- const finalPath = resolve22(path22, filePath);
48307
+ let path23 = process52.cwd();
48308
+ while (path23.includes("storage"))
48309
+ path23 = resolve22(path23, "..");
48310
+ const finalPath = resolve22(path23, filePath);
48146
48311
  if (options2?.relative)
48147
48312
  return relative2(process52.cwd(), finalPath);
48148
48313
  return finalPath;
48149
48314
  }
48150
- function storagePath2(path22) {
48151
- return projectPath2(`storage/${path22 || ""}`);
48315
+ function storagePath2(path23) {
48316
+ return projectPath2(`storage/${path23 || ""}`);
48152
48317
  }
48153
48318
  var config6 = {
48154
48319
  ai: {
@@ -53763,7 +53928,7 @@ class Err2 {
53763
53928
  }
53764
53929
  var fromThrowable2 = Result2.fromThrowable;
53765
53930
  var import_prompts2 = __toESM22(require_prompts32(), 1);
53766
- async function exec(command, options2) {
53931
+ async function exec2(command, options2) {
53767
53932
  const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]|"[^"]*")+/g);
53768
53933
  log2.debug("exec:", Array.isArray(command) ? command.join(" ") : command, options2);
53769
53934
  log2.debug("cmd:", cmd);
@@ -53809,7 +53974,7 @@ async function runCommand(command, options2) {
53809
53974
  stdio: options2?.stdio ?? [options2?.stdin ?? "inherit", "pipe", "pipe"],
53810
53975
  verbose: options2?.verbose ?? false
53811
53976
  };
53812
- return await exec(command, opts);
53977
+ return await exec2(command, opts);
53813
53978
  }
53814
53979
  var exports_esm2 = {};
53815
53980
  __export3(exports_esm2, {
@@ -54235,7 +54400,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
54235
54400
  return min;
54236
54401
  }
54237
54402
  if (process112.platform === "win32") {
54238
- const osRelease = os2.release().split(".");
54403
+ const osRelease = os3.release().split(".");
54239
54404
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
54240
54405
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
54241
54406
  }
@@ -56832,9 +56997,9 @@ var defaultConfig2 = {
56832
56997
  domain: "stacks.localhost",
56833
56998
  rootCA: { certificate: "", privateKey: "" },
56834
56999
  basePath: "",
56835
- caCertPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
56836
- certPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt`),
56837
- keyPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt.key`),
57000
+ caCertPath: path2.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
57001
+ certPath: path2.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt`),
57002
+ keyPath: path2.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt.key`),
56838
57003
  verbose: false
56839
57004
  };
56840
57005
  var config42 = await loadConfig2({
@@ -56853,10 +57018,10 @@ function findFoldersWithFile(rootDir, fileName) {
56853
57018
  const result = [];
56854
57019
  function search(dir) {
56855
57020
  try {
56856
- const files = fs.readdirSync(dir);
57021
+ const files = fs3.readdirSync(dir);
56857
57022
  for (const file of files) {
56858
- const filePath = path2.join(dir, file);
56859
- const stats = fs.lstatSync(filePath);
57023
+ const filePath = path22.join(dir, file);
57024
+ const stats = fs3.lstatSync(filePath);
56860
57025
  if (stats.isDirectory()) {
56861
57026
  search(filePath);
56862
57027
  } else if (file === fileName) {
@@ -56870,26 +57035,26 @@ function findFoldersWithFile(rootDir, fileName) {
56870
57035
  search(rootDir);
56871
57036
  return result;
56872
57037
  }
56873
- function debugLog(category, message, verbose) {
57038
+ function debugLog2(category, message, verbose) {
56874
57039
  if (verbose || config42.verbose) {
56875
57040
  console.debug(`[tlsx:${category}] ${message}`);
56876
57041
  }
56877
57042
  }
56878
57043
  function generateRandomSerial(verbose) {
56879
- debugLog("cert", "Generating random serial number", verbose);
57044
+ debugLog2("cert", "Generating random serial number", verbose);
56880
57045
  const serialNumber = makeNumberPositive(import_node_forge2.default.util.bytesToHex(import_node_forge2.default.random.getBytesSync(20)));
56881
- debugLog("cert", `Generated serial number: ${serialNumber}`, verbose);
57046
+ debugLog2("cert", `Generated serial number: ${serialNumber}`, verbose);
56882
57047
  return serialNumber;
56883
57048
  }
56884
57049
  function calculateValidityDates(options22) {
56885
57050
  const notBeforeDays = options22.notBeforeDays ?? 2;
56886
57051
  const validityDays = options22.validityDays ?? (options22.validityYears ? options22.validityYears * 365 : 180);
56887
- debugLog("cert", "Calculating certificate validity dates", options22.verbose);
57052
+ debugLog2("cert", "Calculating certificate validity dates", options22.verbose);
56888
57053
  const notBefore = new Date(Date.now() - 86400 * notBeforeDays * 1000);
56889
57054
  const notAfter = new Date(notBefore.getTime() + validityDays * 24 * 60 * 60 * 1000);
56890
57055
  notBefore.setUTCHours(0, 0, 0, 0);
56891
57056
  notAfter.setUTCHours(23, 59, 59, 999);
56892
- debugLog("cert", `Validity period: ${notBefore.toISOString()} to ${notAfter.toISOString()}`, options22.verbose);
57057
+ debugLog2("cert", `Validity period: ${notBefore.toISOString()} to ${notAfter.toISOString()}`, options22.verbose);
56893
57058
  return { notBefore, notAfter };
56894
57059
  }
56895
57060
  function generateCertificateExtensions(options22) {
@@ -56922,9 +57087,9 @@ function generateCertificateExtensions(options22) {
56922
57087
  return extensions;
56923
57088
  }
56924
57089
  async function createRootCA(options22 = {}) {
56925
- debugLog("ca", "Creating new Root CA Certificate", options22.verbose);
57090
+ debugLog2("ca", "Creating new Root CA Certificate", options22.verbose);
56926
57091
  const keySize = options22.keySize || 2048;
56927
- debugLog("ca", `Generating ${keySize}-bit RSA key pair`, options22.verbose);
57092
+ debugLog2("ca", `Generating ${keySize}-bit RSA key pair`, options22.verbose);
56928
57093
  const { privateKey, publicKey } = import_node_forge2.pki.rsa.generateKeyPair(keySize);
56929
57094
  const attributes = [
56930
57095
  { shortName: "C", value: options22.countryName || config42.countryName },
@@ -56971,14 +57136,14 @@ async function createRootCA(options22 = {}) {
56971
57136
  };
56972
57137
  }
56973
57138
  async function generateCertificate(options22) {
56974
- debugLog("cert", "Generating new certificate", options22.verbose);
56975
- debugLog("cert", `Options: ${JSON.stringify(options22)}`, options22.verbose);
57139
+ debugLog2("cert", "Generating new certificate", options22.verbose);
57140
+ debugLog2("cert", `Options: ${JSON.stringify(options22)}`, options22.verbose);
56976
57141
  if (!options22.rootCA?.certificate || !options22.rootCA?.privateKey) {
56977
57142
  throw new Error("Root CA certificate and private key are required");
56978
57143
  }
56979
57144
  const caCert = import_node_forge2.pki.certificateFromPem(options22.rootCA.certificate);
56980
57145
  const caKey = import_node_forge2.pki.privateKeyFromPem(options22.rootCA.privateKey);
56981
- debugLog("cert", "Generating 2048-bit RSA key pair for host certificate", options22.verbose);
57146
+ debugLog2("cert", "Generating 2048-bit RSA key pair for host certificate", options22.verbose);
56982
57147
  const keySize = 2048;
56983
57148
  const { privateKey, publicKey } = import_node_forge2.pki.rsa.generateKeyPair(keySize);
56984
57149
  const attributes = options22.certificateAttributes || [
@@ -57009,81 +57174,81 @@ async function generateCertificate(options22) {
57009
57174
  };
57010
57175
  }
57011
57176
  async function addCertToSystemTrustStoreAndSaveCert(cert, caCert, options22) {
57012
- debugLog("trust", `Adding certificate to system trust store with options: ${JSON.stringify(options22)}`, options22?.verbose);
57013
- debugLog("trust", "Storing certificate and private key", options22?.verbose);
57177
+ debugLog2("trust", `Adding certificate to system trust store with options: ${JSON.stringify(options22)}`, options22?.verbose);
57178
+ debugLog2("trust", "Storing certificate and private key", options22?.verbose);
57014
57179
  const certPath = storeCertificate(cert, options22);
57015
- debugLog("trust", "Storing CA certificate", options22?.verbose);
57180
+ debugLog2("trust", "Storing CA certificate", options22?.verbose);
57016
57181
  const caCertPath = storeCACertificate(caCert, options22);
57017
57182
  const platform22 = os4.platform();
57018
- debugLog("trust", `Detected platform: ${platform22}`, options22?.verbose);
57183
+ debugLog2("trust", `Detected platform: ${platform22}`, options22?.verbose);
57019
57184
  const args = "TC, C, C";
57020
57185
  if (platform22 === "darwin") {
57021
- debugLog("trust", "Adding certificate to macOS keychain", options22?.verbose);
57186
+ debugLog2("trust", "Adding certificate to macOS keychain", options22?.verbose);
57022
57187
  await runCommand(`sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${caCertPath}`);
57023
57188
  } else if (platform22 === "win32") {
57024
- debugLog("trust", "Adding certificate to Windows certificate store", options22?.verbose);
57189
+ debugLog2("trust", "Adding certificate to Windows certificate store", options22?.verbose);
57025
57190
  await runCommand(`certutil -f -v -addstore -enterprise Root ${caCertPath}`);
57026
57191
  } else if (platform22 === "linux") {
57027
- debugLog("trust", "Adding certificate to Linux certificate store", options22?.verbose);
57192
+ debugLog2("trust", "Adding certificate to Linux certificate store", options22?.verbose);
57028
57193
  const rootDirectory = os4.homedir();
57029
57194
  const targetFileName = "cert9.db";
57030
- debugLog("trust", `Searching for certificate databases in ${rootDirectory}`, options22?.verbose);
57195
+ debugLog2("trust", `Searching for certificate databases in ${rootDirectory}`, options22?.verbose);
57031
57196
  const foldersWithFile = findFoldersWithFile(rootDirectory, targetFileName);
57032
57197
  for (const folder of foldersWithFile) {
57033
- debugLog("trust", `Processing certificate database in ${folder}`, options22?.verbose);
57198
+ debugLog2("trust", `Processing certificate database in ${folder}`, options22?.verbose);
57034
57199
  try {
57035
- debugLog("trust", `Attempting to delete existing cert for ${config42.commonName}`, options22?.verbose);
57200
+ debugLog2("trust", `Attempting to delete existing cert for ${config42.commonName}`, options22?.verbose);
57036
57201
  await runCommand(`certutil -d sql:${folder} -D -n ${config42.commonName}`);
57037
57202
  } catch (error) {
57038
- debugLog("trust", `Warning: Error deleting existing cert: ${error}`, options22?.verbose);
57203
+ debugLog2("trust", `Warning: Error deleting existing cert: ${error}`, options22?.verbose);
57039
57204
  console.warn(`Error deleting existing cert: ${error}`);
57040
57205
  }
57041
- debugLog("trust", `Adding new certificate to ${folder}`, options22?.verbose);
57206
+ debugLog2("trust", `Adding new certificate to ${folder}`, options22?.verbose);
57042
57207
  await runCommand(`certutil -d sql:${folder} -A -t ${args} -n ${config42.commonName} -i ${caCertPath}`);
57043
57208
  log2.info(`Cert added to ${folder}`);
57044
57209
  }
57045
57210
  } else {
57046
- debugLog("trust", `Error: Unsupported platform ${platform22}`, options22?.verbose);
57211
+ debugLog2("trust", `Error: Unsupported platform ${platform22}`, options22?.verbose);
57047
57212
  throw new Error(`Unsupported platform: ${platform22}`);
57048
57213
  }
57049
- debugLog("trust", "Certificate successfully added to system trust store", options22?.verbose);
57214
+ debugLog2("trust", "Certificate successfully added to system trust store", options22?.verbose);
57050
57215
  return certPath;
57051
57216
  }
57052
57217
  function storeCertificate(cert, options22) {
57053
- debugLog("storage", `Storing certificate and private key with options: ${JSON.stringify(options22)}`, options22?.verbose);
57218
+ debugLog2("storage", `Storing certificate and private key with options: ${JSON.stringify(options22)}`, options22?.verbose);
57054
57219
  const certPath = path3.join(options22?.basePath || config42.basePath, options22?.certPath || config42.certPath);
57055
57220
  const certKeyPath = path3.join(options22?.basePath || config42.basePath, options22?.keyPath || config42.keyPath);
57056
- debugLog("storage", `Certificate path: ${certPath}`, options22?.verbose);
57057
- debugLog("storage", `Private key path: ${certKeyPath}`, options22?.verbose);
57221
+ debugLog2("storage", `Certificate path: ${certPath}`, options22?.verbose);
57222
+ debugLog2("storage", `Private key path: ${certKeyPath}`, options22?.verbose);
57058
57223
  const certDir = path3.dirname(certPath);
57059
57224
  if (!fs2.existsSync(certDir)) {
57060
- debugLog("storage", `Creating certificate directory: ${certDir}`, options22?.verbose);
57225
+ debugLog2("storage", `Creating certificate directory: ${certDir}`, options22?.verbose);
57061
57226
  fs2.mkdirSync(certDir, { recursive: true });
57062
57227
  }
57063
- debugLog("storage", "Writing certificate file", options22?.verbose);
57228
+ debugLog2("storage", "Writing certificate file", options22?.verbose);
57064
57229
  fs2.writeFileSync(certPath, cert.certificate);
57065
57230
  const certKeyDir = path3.dirname(certKeyPath);
57066
57231
  if (!fs2.existsSync(certKeyDir)) {
57067
- debugLog("storage", `Creating private key directory: ${certKeyDir}`, options22?.verbose);
57232
+ debugLog2("storage", `Creating private key directory: ${certKeyDir}`, options22?.verbose);
57068
57233
  fs2.mkdirSync(certKeyDir, { recursive: true });
57069
57234
  }
57070
- debugLog("storage", "Writing private key file", options22?.verbose);
57235
+ debugLog2("storage", "Writing private key file", options22?.verbose);
57071
57236
  fs2.writeFileSync(certKeyPath, cert.privateKey);
57072
- debugLog("storage", "Certificate and private key stored successfully", options22?.verbose);
57237
+ debugLog2("storage", "Certificate and private key stored successfully", options22?.verbose);
57073
57238
  return certPath;
57074
57239
  }
57075
57240
  function storeCACertificate(caCert, options22) {
57076
- debugLog("storage", "Storing CA certificate", options22?.verbose);
57241
+ debugLog2("storage", "Storing CA certificate", options22?.verbose);
57077
57242
  const caCertPath = path3.join(options22?.basePath || config42.basePath, options22?.caCertPath || config42.caCertPath);
57078
- debugLog("storage", `CA certificate path: ${caCertPath}`, options22?.verbose);
57243
+ debugLog2("storage", `CA certificate path: ${caCertPath}`, options22?.verbose);
57079
57244
  const caCertDir = path3.dirname(caCertPath);
57080
57245
  if (!fs2.existsSync(caCertDir)) {
57081
- debugLog("storage", `Creating CA certificate directory: ${caCertDir}`, options22?.verbose);
57246
+ debugLog2("storage", `Creating CA certificate directory: ${caCertDir}`, options22?.verbose);
57082
57247
  fs2.mkdirSync(caCertDir, { recursive: true });
57083
57248
  }
57084
- debugLog("storage", "Writing CA certificate file", options22?.verbose);
57249
+ debugLog2("storage", "Writing CA certificate file", options22?.verbose);
57085
57250
  fs2.writeFileSync(caCertPath, caCert);
57086
- debugLog("storage", "CA certificate stored successfully", options22?.verbose);
57251
+ debugLog2("storage", "CA certificate stored successfully", options22?.verbose);
57087
57252
  return caCertPath;
57088
57253
  }
57089
57254
  var export_tls = import_node_forge2.tls;
@@ -57092,15 +57257,6 @@ var export_forge = import_node_forge2.default;
57092
57257
 
57093
57258
  // src/https.ts
57094
57259
  var cachedSSLConfig = null;
57095
- function isMultiProxyConfig(options3) {
57096
- return "proxies" in options3 && Array.isArray(options3.proxies);
57097
- }
57098
- function isMultiProxyOptions(options3) {
57099
- return "proxies" in options3 && Array.isArray(options3.proxies);
57100
- }
57101
- function isSingleProxyOptions(options3) {
57102
- return "to" in options3 && typeof options3.to === "string";
57103
- }
57104
57260
  function resolveSSLPaths(options3, defaultConfig3) {
57105
57261
  const domain = isMultiProxyConfig(options3) ? options3.proxies[0].to || "stacks.localhost" : options3.to || "stacks.localhost";
57106
57262
  if (typeof options3.https === "object" && typeof defaultConfig3.https === "object") {
@@ -57144,15 +57300,6 @@ function generateWildcardPatterns(domain) {
57144
57300
  patterns.add(`*.${parts.slice(1).join(".")}`);
57145
57301
  return Array.from(patterns);
57146
57302
  }
57147
- function getPrimaryDomain(options3) {
57148
- if (!options3)
57149
- return "stacks.localhost";
57150
- if (isMultiProxyOptions(options3) && options3.proxies.length > 0)
57151
- return options3.proxies[0].to || "stacks.localhost";
57152
- if (isSingleProxyOptions(options3))
57153
- return options3.to || "stacks.localhost";
57154
- return "stacks.localhost";
57155
- }
57156
57303
  function generateSSLPaths(options3) {
57157
57304
  const domain = getPrimaryDomain(options3);
57158
57305
  let basePath = "";
@@ -57190,51 +57337,50 @@ function getAllDomains(options3) {
57190
57337
  return domains;
57191
57338
  }
57192
57339
  async function loadSSLConfig(options3) {
57193
- debugLog2("ssl", `Loading SSL configuration`, options3.verbose);
57340
+ debugLog("ssl", `Loading SSL configuration`, options3.verbose);
57194
57341
  const mergedOptions = {
57195
57342
  ...config4,
57196
57343
  ...options3
57197
57344
  };
57198
57345
  options3.https = httpsConfig(mergedOptions);
57199
57346
  if (!options3.https?.keyPath && !options3.https?.certPath) {
57200
- debugLog2("ssl", "No SSL configuration provided", options3.verbose);
57347
+ debugLog("ssl", "No SSL configuration provided", options3.verbose);
57201
57348
  return null;
57202
57349
  }
57203
57350
  if (options3.https?.keyPath && !options3.https?.certPath || !options3.https?.keyPath && options3.https?.certPath) {
57204
57351
  const missing = !options3.https?.keyPath ? "keyPath" : "certPath";
57205
- debugLog2("ssl", `Invalid SSL configuration - missing ${missing}`, options3.verbose);
57352
+ debugLog("ssl", `Invalid SSL configuration - missing ${missing}`, options3.verbose);
57206
57353
  throw new Error(`SSL Configuration requires both keyPath and certPath. Missing: ${missing}`);
57207
57354
  }
57208
57355
  try {
57209
57356
  if (!options3.https?.keyPath || !options3.https?.certPath)
57210
57357
  return null;
57211
57358
  try {
57212
- debugLog2("ssl", "Reading SSL certificate files", options3.verbose);
57213
- const key = await fs3.readFile(options3.https?.keyPath, "utf8");
57214
- const cert = await fs3.readFile(options3.https?.certPath, "utf8");
57215
- debugLog2("ssl", "SSL configuration loaded successfully", options3.verbose);
57359
+ debugLog("ssl", "Reading SSL certificate files", options3.verbose);
57360
+ const key = await fs5.readFile(options3.https?.keyPath, "utf8");
57361
+ const cert = await fs5.readFile(options3.https?.certPath, "utf8");
57362
+ debugLog("ssl", "SSL configuration loaded successfully", options3.verbose);
57216
57363
  return { key, cert };
57217
57364
  } catch (error) {
57218
- debugLog2("ssl", `Failed to read certificates: ${error}`, options3.verbose);
57365
+ debugLog("ssl", `Failed to read certificates: ${error}`, options3.verbose);
57219
57366
  return null;
57220
57367
  }
57221
57368
  } catch (err3) {
57222
- debugLog2("ssl", `SSL configuration error: ${err3}`, options3.verbose);
57369
+ debugLog("ssl", `SSL configuration error: ${err3}`, options3.verbose);
57223
57370
  throw err3;
57224
57371
  }
57225
57372
  }
57226
57373
  async function generateCertificate2(options3) {
57227
57374
  if (cachedSSLConfig) {
57228
- debugLog2("ssl", "Using cached SSL configuration", options3.verbose);
57375
+ debugLog("ssl", "Using cached SSL configuration", options3.verbose);
57229
57376
  return;
57230
57377
  }
57231
57378
  const domains = isMultiProxyOptions(options3) ? options3.proxies.map((proxy) => proxy.to) : [options3.to];
57232
- debugLog2("ssl", `Generating certificate for domains: ${domains.join(", ")}`, options3.verbose);
57379
+ debugLog("ssl", `Generating certificate for domains: ${domains.join(", ")}`, options3.verbose);
57233
57380
  const rootCAConfig = httpsConfig(options3, options3.verbose);
57234
57381
  log.info("Generating Root CA certificate...");
57235
57382
  const caCert = await createRootCA(rootCAConfig);
57236
57383
  const hostConfig = httpsConfig(options3, options3.verbose);
57237
- console.log("hostConfig", hostConfig);
57238
57384
  log.info(`Generating host certificate for: ${domains.join(", ")}`);
57239
57385
  const hostCert = await generateCertificate({
57240
57386
  ...hostConfig,
@@ -57250,7 +57396,7 @@ async function generateCertificate2(options3) {
57250
57396
  ca: caCert.certificate
57251
57397
  };
57252
57398
  log.success(`Certificate generated successfully for ${domains.length} domain${domains.length > 1 ? "s" : ""}`);
57253
- debugLog2("ssl", `Certificate includes domains: ${domains.join(", ")}`, options3.verbose);
57399
+ debugLog("ssl", `Certificate includes domains: ${domains.join(", ")}`, options3.verbose);
57254
57400
  }
57255
57401
  function getSSLConfig() {
57256
57402
  return cachedSSLConfig;
@@ -57259,29 +57405,29 @@ async function checkExistingCertificates(options3) {
57259
57405
  const name = getPrimaryDomain(options3);
57260
57406
  const paths = generateSSLPaths(options3);
57261
57407
  try {
57262
- debugLog2("ssl", `Checking certificates for ${name} at paths:`, options3?.verbose);
57263
- debugLog2("ssl", `CA: ${paths.caCertPath}`, options3?.verbose);
57264
- debugLog2("ssl", `Cert: ${paths.certPath}`, options3?.verbose);
57265
- debugLog2("ssl", `Key: ${paths.keyPath}`, options3?.verbose);
57266
- const key = await fs3.readFile(paths.keyPath, "utf8");
57267
- const cert = await fs3.readFile(paths.certPath, "utf8");
57408
+ debugLog("ssl", `Checking certificates for ${name} at paths:`, options3?.verbose);
57409
+ debugLog("ssl", `CA: ${paths.caCertPath}`, options3?.verbose);
57410
+ debugLog("ssl", `Cert: ${paths.certPath}`, options3?.verbose);
57411
+ debugLog("ssl", `Key: ${paths.keyPath}`, options3?.verbose);
57412
+ const key = await fs5.readFile(paths.keyPath, "utf8");
57413
+ const cert = await fs5.readFile(paths.certPath, "utf8");
57268
57414
  let ca;
57269
57415
  if (paths.caCertPath) {
57270
57416
  try {
57271
- ca = await fs3.readFile(paths.caCertPath, "utf8");
57417
+ ca = await fs5.readFile(paths.caCertPath, "utf8");
57272
57418
  } catch (err3) {
57273
- debugLog2("ssl", `Failed to read CA cert: ${err3}`, options3?.verbose);
57419
+ debugLog("ssl", `Failed to read CA cert: ${err3}`, options3?.verbose);
57274
57420
  }
57275
57421
  }
57276
57422
  return { key, cert, ca };
57277
57423
  } catch (err3) {
57278
- debugLog2("ssl", `Failed to read certificates: ${err3}`, options3?.verbose);
57424
+ debugLog("ssl", `Failed to read certificates: ${err3}`, options3?.verbose);
57279
57425
  return null;
57280
57426
  }
57281
57427
  }
57282
57428
  function httpsConfig(options3, verbose) {
57283
57429
  const primaryDomain = getPrimaryDomain(options3);
57284
- debugLog2("ssl", `Primary domain: ${primaryDomain}`, verbose);
57430
+ debugLog("ssl", `Primary domain: ${primaryDomain}`, verbose);
57285
57431
  const defaultPaths = generateSSLPaths(options3);
57286
57432
  if (typeof options3.https === "object") {
57287
57433
  const config5 = {
@@ -57331,227 +57477,41 @@ function httpsConfig(options3, verbose) {
57331
57477
  };
57332
57478
  }
57333
57479
 
57334
- // src/utils.ts
57335
- function debugLog2(category, message, verbose) {
57336
- if (verbose) {
57337
- console.debug(`[rpx:${category}] ${message}`);
57338
- }
57339
- }
57340
- function extractHostname(options3) {
57341
- if (isMultiProxyOptions(options3)) {
57342
- return options3.proxies.map((proxy) => {
57343
- const domain = proxy.to || "stacks.localhost";
57344
- return domain.startsWith("http") ? new URL(domain).hostname : domain;
57345
- });
57346
- }
57347
- if (isSingleProxyOptions(options3)) {
57348
- const domain = options3.to || "stacks.localhost";
57349
- return [domain.startsWith("http") ? new URL(domain).hostname : domain];
57350
- }
57351
- return ["stacks.localhost"];
57352
- }
57353
- function isValidRootCA(value) {
57354
- return typeof value === "object" && value !== null && "certificate" in value && "privateKey" in value && typeof value.certificate === "string" && typeof value.privateKey === "string";
57355
- }
57356
-
57357
- // src/hosts.ts
57358
- var hostsFilePath = process3.platform === "win32" ? path4.join(process3.env.windir || "C:\\Windows", "System32", "drivers", "etc", "hosts") : "/etc/hosts";
57359
- async function sudoWrite(operation, content) {
57360
- return new Promise((resolve4, reject) => {
57361
- if (process3.platform === "win32") {
57362
- reject(new Error("Administrator privileges required on Windows"));
57363
- return;
57364
- }
57365
- const tmpFile = path4.join(os3.tmpdir(), "hosts.tmp");
57366
- try {
57367
- if (operation === "append") {
57368
- const currentContent = fs5.readFileSync(hostsFilePath, "utf8");
57369
- fs5.writeFileSync(tmpFile, currentContent + content, "utf8");
57370
- } else {
57371
- fs5.writeFileSync(tmpFile, content, "utf8");
57372
- }
57373
- const sudo = spawn("sudo", ["cp", tmpFile, hostsFilePath]);
57374
- sudo.on("close", (code) => {
57375
- try {
57376
- fs5.unlinkSync(tmpFile);
57377
- if (code === 0)
57378
- resolve4();
57379
- else
57380
- reject(new Error(`sudo process exited with code ${code}`));
57381
- } catch (err3) {
57382
- reject(err3);
57383
- }
57384
- });
57385
- sudo.on("error", (err3) => {
57386
- try {
57387
- fs5.unlinkSync(tmpFile);
57388
- } catch {
57389
- }
57390
- reject(err3);
57391
- });
57392
- } catch (err3) {
57393
- reject(err3);
57394
- }
57395
- });
57396
- }
57397
- async function addHosts(hosts, verbose) {
57398
- debugLog2("hosts", `Adding hosts: ${hosts.join(", ")}`, verbose);
57399
- debugLog2("hosts", `Using hosts file at: ${hostsFilePath}`, verbose);
57400
- try {
57401
- const existingContent = await fs5.promises.readFile(hostsFilePath, "utf-8");
57402
- const newEntries = hosts.filter((host) => {
57403
- const ipv4Entry = `127.0.0.1 ${host}`;
57404
- const ipv6Entry = `::1 ${host}`;
57405
- return !existingContent.includes(ipv4Entry) && !existingContent.includes(ipv6Entry);
57406
- });
57407
- if (newEntries.length === 0) {
57408
- debugLog2("hosts", "All hosts already exist in hosts file", verbose);
57409
- log.info("All hosts are already in the hosts file");
57410
- return;
57411
- }
57412
- const hostEntries = newEntries.map((host) => `
57413
- # Added by rpx
57414
- 127.0.0.1 ${host}
57415
- ::1 ${host}`).join(`
57416
- `);
57417
- try {
57418
- await fs5.promises.appendFile(hostsFilePath, hostEntries, { flag: "a" });
57419
- log.success(`Added new hosts: ${newEntries.join(", ")}`);
57420
- } catch (writeErr) {
57421
- if (writeErr.code === "EACCES") {
57422
- debugLog2("hosts", "Permission denied, attempting with sudo", verbose);
57423
- try {
57424
- await sudoWrite("append", hostEntries);
57425
- log.success(`Added new hosts with sudo: ${newEntries.join(", ")}`);
57426
- } catch (sudoErr) {
57427
- log.error("Failed to modify hosts file automatically");
57428
- log.warn("Please add these entries to your hosts file manually:");
57429
- hostEntries.split(`
57430
- `).forEach((entry) => log.warn(entry));
57431
- if (process3.platform === "win32") {
57432
- log.warn(`
57433
- On Windows:`);
57434
- log.warn("1. Run notepad as administrator");
57435
- log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
57436
- } else {
57437
- log.warn(`
57438
- On Unix systems:`);
57439
- log.warn(`sudo nano ${hostsFilePath}`);
57440
- }
57441
- throw new Error("Failed to modify hosts file: manual intervention required");
57442
- }
57443
- } else {
57444
- throw writeErr;
57445
- }
57446
- }
57447
- } catch (err3) {
57448
- const error = err3;
57449
- log.error(`Failed to manage hosts file: ${error.message}`);
57450
- throw error;
57451
- }
57452
- }
57453
- async function removeHosts(hosts, verbose) {
57454
- debugLog2("hosts", `Removing hosts: ${hosts.join(", ")}`, verbose);
57455
- try {
57456
- const content = await fs5.promises.readFile(hostsFilePath, "utf-8");
57457
- const lines = content.split(`
57458
- `);
57459
- const filteredLines = lines.filter((line, index) => {
57460
- if (line.trim() === "# Added by rpx") {
57461
- lines.splice(index + 1, 2);
57462
- return false;
57463
- }
57464
- return true;
57465
- });
57466
- while (filteredLines[filteredLines.length - 1]?.trim() === "")
57467
- filteredLines.pop();
57468
- const newContent = `${filteredLines.join(`
57469
- `)}
57470
- `;
57471
- try {
57472
- await fs5.promises.writeFile(hostsFilePath, newContent);
57473
- log.success("Hosts removed successfully");
57474
- } catch (writeErr) {
57475
- if (writeErr.code === "EACCES") {
57476
- debugLog2("hosts", "Permission denied, attempting with sudo", verbose);
57477
- try {
57478
- await sudoWrite("write", newContent);
57479
- log.success("Hosts removed successfully with sudo");
57480
- } catch (sudoErr) {
57481
- log.error("Failed to modify hosts file automatically");
57482
- log.warn("Please remove these entries from your hosts file manually:");
57483
- hosts.forEach((host) => {
57484
- log.warn("# Added by rpx");
57485
- log.warn(`127.0.0.1 ${host}`);
57486
- log.warn(`::1 ${host}`);
57487
- });
57488
- if (process3.platform === "win32") {
57489
- log.warn(`
57490
- On Windows:`);
57491
- log.warn("1. Run notepad as administrator");
57492
- log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
57493
- } else {
57494
- log.warn(`
57495
- On Unix systems:`);
57496
- log.warn(`sudo nano ${hostsFilePath}`);
57497
- }
57498
- throw new Error("Failed to modify hosts file: manual intervention required");
57499
- }
57500
- } else {
57501
- throw writeErr;
57502
- }
57503
- }
57504
- } catch (err3) {
57505
- const error = err3;
57506
- log.error(`Failed to remove hosts: ${error.message}`);
57507
- throw error;
57508
- }
57509
- }
57510
- async function checkHosts(hosts, verbose) {
57511
- debugLog2("hosts", `Checking hosts: ${hosts}`, verbose);
57512
- const content = await fs5.promises.readFile(hostsFilePath, "utf-8");
57513
- return hosts.map((host) => {
57514
- const ipv4Entry = `127.0.0.1 ${host}`;
57515
- const ipv6Entry = `::1 ${host}`;
57516
- return content.includes(ipv4Entry) || content.includes(ipv6Entry);
57517
- });
57518
- }
57519
-
57520
57480
  // src/start.ts
57521
57481
  var activeServers = new Set;
57522
57482
  async function cleanup(options3) {
57523
- debugLog2("cleanup", "Starting cleanup process", options3?.verbose);
57483
+ debugLog("cleanup", "Starting cleanup process", options3?.verbose);
57524
57484
  console.log(`
57525
57485
  `);
57526
57486
  log.info("Shutting down proxy servers...");
57527
57487
  const cleanupPromises = [];
57528
57488
  const serverClosePromises = Array.from(activeServers).map((server) => new Promise((resolve4) => {
57529
57489
  server.close(() => {
57530
- debugLog2("cleanup", "Server closed successfully", options3?.verbose);
57490
+ debugLog("cleanup", "Server closed successfully", options3?.verbose);
57531
57491
  resolve4();
57532
57492
  });
57533
57493
  }));
57534
57494
  cleanupPromises.push(...serverClosePromises);
57535
57495
  if (options3?.etcHostsCleanup && options3.domains?.length) {
57536
- debugLog2("cleanup", "Cleaning up hosts file entries", options3?.verbose);
57496
+ debugLog("cleanup", "Cleaning up hosts file entries", options3?.verbose);
57537
57497
  const domainsToClean = options3.domains.filter((domain) => !domain.includes("localhost"));
57538
57498
  if (domainsToClean.length > 0) {
57539
57499
  log.info("Cleaning up hosts file entries...");
57540
57500
  cleanupPromises.push(removeHosts(domainsToClean, options3?.verbose).then(() => {
57541
- debugLog2("cleanup", `Removed hosts entries for ${domainsToClean.join(", ")}`, options3?.verbose);
57501
+ debugLog("cleanup", `Removed hosts entries for ${domainsToClean.join(", ")}`, options3?.verbose);
57542
57502
  }).catch((err3) => {
57543
- debugLog2("cleanup", `Failed to remove hosts entries: ${err3}`, options3?.verbose);
57503
+ debugLog("cleanup", `Failed to remove hosts entries: ${err3}`, options3?.verbose);
57544
57504
  log.warn(`Failed to clean up hosts file entries for ${domainsToClean.join(", ")}:`, err3);
57545
57505
  }));
57546
57506
  }
57547
57507
  }
57548
57508
  try {
57549
57509
  await Promise.all(cleanupPromises);
57550
- debugLog2("cleanup", "All cleanup tasks completed successfully", options3?.verbose);
57510
+ debugLog("cleanup", "All cleanup tasks completed successfully", options3?.verbose);
57551
57511
  log.success("All cleanup tasks completed successfully");
57552
57512
  process9.exit(0);
57553
57513
  } catch (err3) {
57554
- debugLog2("cleanup", `Error during cleanup: ${err3}`, options3?.verbose);
57514
+ debugLog("cleanup", `Error during cleanup: ${err3}`, options3?.verbose);
57555
57515
  log.error("Error during cleanup:", err3);
57556
57516
  process9.exit(1);
57557
57517
  }
@@ -57559,22 +57519,22 @@ async function cleanup(options3) {
57559
57519
  process9.on("SIGINT", cleanup);
57560
57520
  process9.on("SIGTERM", cleanup);
57561
57521
  process9.on("uncaughtException", (err3) => {
57562
- debugLog2("process", `Uncaught exception: ${err3}`, true);
57522
+ debugLog("process", `Uncaught exception: ${err3}`, true);
57563
57523
  log.error("Uncaught exception:", err3);
57564
57524
  cleanup();
57565
57525
  });
57566
57526
  function isPortInUse(port, hostname, verbose) {
57567
- debugLog2("port", `Checking if port ${port} is in use on ${hostname}`, verbose);
57527
+ debugLog("port", `Checking if port ${port} is in use on ${hostname}`, verbose);
57568
57528
  return new Promise((resolve4) => {
57569
57529
  const server = net.createServer();
57570
57530
  server.once("error", (err3) => {
57571
57531
  if (err3.code === "EADDRINUSE") {
57572
- debugLog2("port", `Port ${port} is in use`, verbose);
57532
+ debugLog("port", `Port ${port} is in use`, verbose);
57573
57533
  resolve4(true);
57574
57534
  }
57575
57535
  });
57576
57536
  server.once("listening", () => {
57577
- debugLog2("port", `Port ${port} is available`, verbose);
57537
+ debugLog("port", `Port ${port} is available`, verbose);
57578
57538
  server.close();
57579
57539
  resolve4(false);
57580
57540
  });
@@ -57582,17 +57542,17 @@ function isPortInUse(port, hostname, verbose) {
57582
57542
  });
57583
57543
  }
57584
57544
  async function findAvailablePort(startPort, hostname, verbose) {
57585
- debugLog2("port", `Finding available port starting from ${startPort}`, verbose);
57545
+ debugLog("port", `Finding available port starting from ${startPort}`, verbose);
57586
57546
  let port = startPort;
57587
57547
  while (await isPortInUse(port, hostname, verbose)) {
57588
- debugLog2("port", `Port ${port} is in use, trying ${port + 1}`, verbose);
57548
+ debugLog("port", `Port ${port} is in use, trying ${port + 1}`, verbose);
57589
57549
  port++;
57590
57550
  }
57591
- debugLog2("port", `Found available port: ${port}`, verbose);
57551
+ debugLog("port", `Found available port: ${port}`, verbose);
57592
57552
  return port;
57593
57553
  }
57594
57554
  async function testConnection(hostname, port, verbose) {
57595
- debugLog2("connection", `Testing connection to ${hostname}:${port}`, verbose);
57555
+ debugLog("connection", `Testing connection to ${hostname}:${port}`, verbose);
57596
57556
  return new Promise((resolve4, reject) => {
57597
57557
  const socket = net.connect({
57598
57558
  host: hostname,
@@ -57600,30 +57560,30 @@ async function testConnection(hostname, port, verbose) {
57600
57560
  timeout: 5000
57601
57561
  });
57602
57562
  socket.once("connect", () => {
57603
- debugLog2("connection", `Successfully connected to ${hostname}:${port}`, verbose);
57563
+ debugLog("connection", `Successfully connected to ${hostname}:${port}`, verbose);
57604
57564
  socket.end();
57605
57565
  resolve4();
57606
57566
  });
57607
57567
  socket.once("timeout", () => {
57608
- debugLog2("connection", `Connection to ${hostname}:${port} timed out`, verbose);
57568
+ debugLog("connection", `Connection to ${hostname}:${port} timed out`, verbose);
57609
57569
  socket.destroy();
57610
57570
  reject(new Error(`Connection to ${hostname}:${port} timed out`));
57611
57571
  });
57612
57572
  socket.once("error", (err3) => {
57613
- debugLog2("connection", `Failed to connect to ${hostname}:${port}: ${err3}`, verbose);
57573
+ debugLog("connection", `Failed to connect to ${hostname}:${port}: ${err3}`, verbose);
57614
57574
  socket.destroy();
57615
57575
  reject(new Error(`Failed to connect to ${hostname}:${port}: ${err3.message}`));
57616
57576
  });
57617
57577
  });
57618
57578
  }
57619
57579
  async function startServer(options3) {
57620
- debugLog2("server", `Starting server with options: ${JSON.stringify(options3)}`, options3.verbose);
57580
+ debugLog("server", `Starting server with options: ${JSON.stringify(options3)}`, options3.verbose);
57621
57581
  const fromUrl = new URL((options3.from?.startsWith("http") ? options3.from : `http://${options3.from}`) || "localhost:5173");
57622
57582
  const toUrl = new URL((options3.to?.startsWith("http") ? options3.to : `http://${options3.to}`) || "stacks.localhost");
57623
57583
  const fromPort = Number.parseInt(fromUrl.port) || (fromUrl.protocol.includes("https:") ? 443 : 80);
57624
57584
  const hostsToCheck = [toUrl.hostname];
57625
57585
  if (!toUrl.hostname.includes("localhost") && !toUrl.hostname.includes("127.0.0.1")) {
57626
- debugLog2("hosts", `Checking if hosts file entry exists for: ${toUrl.hostname}`, options3?.verbose);
57586
+ debugLog("hosts", `Checking if hosts file entry exists for: ${toUrl.hostname}`, options3?.verbose);
57627
57587
  try {
57628
57588
  const hostsExist = await checkHosts(hostsToCheck, options3.verbose);
57629
57589
  if (!hostsExist[0]) {
@@ -57646,7 +57606,7 @@ async function startServer(options3) {
57646
57606
  }
57647
57607
  }
57648
57608
  } else {
57649
- debugLog2("hosts", `Host entry already exists for ${toUrl.hostname}`, options3.verbose);
57609
+ debugLog("hosts", `Host entry already exists for ${toUrl.hostname}`, options3.verbose);
57650
57610
  }
57651
57611
  } catch (checkError) {
57652
57612
  log.error("Failed to check hosts file:", checkError.message);
@@ -57655,7 +57615,7 @@ async function startServer(options3) {
57655
57615
  try {
57656
57616
  await testConnection(fromUrl.hostname, fromPort, options3.verbose);
57657
57617
  } catch (err3) {
57658
- debugLog2("server", `Connection test failed: ${err3}`, options3.verbose);
57618
+ debugLog("server", `Connection test failed: ${err3}`, options3.verbose);
57659
57619
  log.error(err3.message);
57660
57620
  process9.exit(1);
57661
57621
  }
@@ -57669,17 +57629,17 @@ async function startServer(options3) {
57669
57629
  });
57670
57630
  }
57671
57631
  try {
57672
- debugLog2("ssl", `Attempting to load SSL configuration for ${toUrl.hostname}`, options3.verbose);
57632
+ debugLog("ssl", `Attempting to load SSL configuration for ${toUrl.hostname}`, options3.verbose);
57673
57633
  sslConfig = await loadSSLConfig({
57674
57634
  ...options3,
57675
57635
  to: toUrl.hostname,
57676
57636
  https: options3.https
57677
57637
  });
57678
57638
  } catch (loadError) {
57679
- debugLog2("ssl", `Failed to load certificates, will generate new ones: ${loadError}`, options3.verbose);
57639
+ debugLog("ssl", `Failed to load certificates, will generate new ones: ${loadError}`, options3.verbose);
57680
57640
  }
57681
57641
  if (!sslConfig) {
57682
- debugLog2("ssl", `Generating new certificates for ${toUrl.hostname}`, options3.verbose);
57642
+ debugLog("ssl", `Generating new certificates for ${toUrl.hostname}`, options3.verbose);
57683
57643
  await generateCertificate2({
57684
57644
  ...options3,
57685
57645
  from: fromUrl.toString(),
@@ -57696,11 +57656,11 @@ async function startServer(options3) {
57696
57656
  }
57697
57657
  }
57698
57658
  } catch (err3) {
57699
- debugLog2("server", `SSL setup failed: ${err3}`, options3.verbose);
57659
+ debugLog("server", `SSL setup failed: ${err3}`, options3.verbose);
57700
57660
  throw err3;
57701
57661
  }
57702
57662
  }
57703
- debugLog2("server", `Setting up reverse proxy with SSL config for ${toUrl.hostname}`, options3.verbose);
57663
+ debugLog("server", `Setting up reverse proxy with SSL config for ${toUrl.hostname}`, options3.verbose);
57704
57664
  await setupReverseProxy({
57705
57665
  ...options3,
57706
57666
  from: options3.from || "localhost:5173",
@@ -57714,9 +57674,9 @@ async function startServer(options3) {
57714
57674
  });
57715
57675
  }
57716
57676
  async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose) {
57717
- debugLog2("proxy", `Creating proxy server ${from} -> ${to}`, verbose);
57677
+ debugLog("proxy", `Creating proxy server ${from} -> ${to}`, verbose);
57718
57678
  const requestHandler = (req, res) => {
57719
- debugLog2("request", `Incoming request: ${req.method} ${req.url}`, verbose);
57679
+ debugLog("request", `Incoming request: ${req.method} ${req.url}`, verbose);
57720
57680
  const proxyOptions = {
57721
57681
  hostname: sourceUrl.hostname,
57722
57682
  port: fromPort,
@@ -57727,9 +57687,9 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57727
57687
  host: sourceUrl.host
57728
57688
  }
57729
57689
  };
57730
- debugLog2("request", `Proxy request options: ${JSON.stringify(proxyOptions)}`, verbose);
57690
+ debugLog("request", `Proxy request options: ${JSON.stringify(proxyOptions)}`, verbose);
57731
57691
  const proxyReq = http.request(proxyOptions, (proxyRes) => {
57732
- debugLog2("response", `Proxy response received with status ${proxyRes.statusCode}`, verbose);
57692
+ debugLog("response", `Proxy response received with status ${proxyRes.statusCode}`, verbose);
57733
57693
  const headers = {
57734
57694
  ...proxyRes.headers,
57735
57695
  "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
@@ -57739,7 +57699,7 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57739
57699
  proxyRes.pipe(res);
57740
57700
  });
57741
57701
  proxyReq.on("error", (err3) => {
57742
- debugLog2("request", `Proxy request failed: ${err3}`, verbose);
57702
+ debugLog("request", `Proxy request failed: ${err3}`, verbose);
57743
57703
  log.error("Proxy request failed:", err3);
57744
57704
  res.writeHead(502);
57745
57705
  res.end(`Proxy Error: ${err3.message}`);
@@ -57766,11 +57726,11 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57766
57726
  allowHTTP1: true,
57767
57727
  ALPNProtocols: ["h2", "http/1.1"]
57768
57728
  } : undefined;
57769
- debugLog2("server", `Creating server with SSL config: ${!!ssl}`, verbose);
57729
+ debugLog("server", `Creating server with SSL config: ${!!ssl}`, verbose);
57770
57730
  const server = ssl && serverOptions ? https.createServer(serverOptions, requestHandler) : http.createServer(requestHandler);
57771
57731
  if (ssl) {
57772
57732
  server.on("secureConnection", (tlsSocket) => {
57773
- debugLog2("tls", `TLS Connection established: ${JSON.stringify({
57733
+ debugLog("tls", `TLS Connection established: ${JSON.stringify({
57774
57734
  protocol: tlsSocket.getProtocol?.(),
57775
57735
  cipher: tlsSocket.getCipher?.(),
57776
57736
  authorized: tlsSocket.authorized,
@@ -57781,7 +57741,7 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57781
57741
  activeServers.add(server);
57782
57742
  return new Promise((resolve4, reject) => {
57783
57743
  server.listen(listenPort, hostname, () => {
57784
- debugLog2("server", `Server listening on port ${listenPort}`, verbose);
57744
+ debugLog("server", `Server listening on port ${listenPort}`, verbose);
57785
57745
  console.log("");
57786
57746
  console.log(` ${green(bold("reverse-proxy"))} ${green(`v${version}`)}`);
57787
57747
  console.log("");
@@ -57798,13 +57758,13 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
57798
57758
  resolve4();
57799
57759
  });
57800
57760
  server.on("error", (err3) => {
57801
- debugLog2("server", `Server error: ${err3}`, verbose);
57761
+ debugLog("server", `Server error: ${err3}`, verbose);
57802
57762
  reject(err3);
57803
57763
  });
57804
57764
  });
57805
57765
  }
57806
57766
  async function setupReverseProxy(options3) {
57807
- debugLog2("setup", `Setting up reverse proxy: ${JSON.stringify(options3)}`, options3.verbose);
57767
+ debugLog("setup", `Setting up reverse proxy: ${JSON.stringify(options3)}`, options3.verbose);
57808
57768
  const { from, to, fromPort, sourceUrl, ssl, verbose, etcHostsCleanup, portManager } = options3;
57809
57769
  const httpPort = 80;
57810
57770
  const httpsPort = 443;
@@ -57813,11 +57773,11 @@ async function setupReverseProxy(options3) {
57813
57773
  if (ssl && !portManager?.usedPorts.has(httpPort)) {
57814
57774
  const isHttpPortBusy = await isPortInUse(httpPort, hostname, verbose);
57815
57775
  if (!isHttpPortBusy) {
57816
- debugLog2("setup", "Starting HTTP redirect server", verbose);
57776
+ debugLog("setup", "Starting HTTP redirect server", verbose);
57817
57777
  startHttpRedirectServer(verbose);
57818
57778
  portManager?.usedPorts.add(httpPort);
57819
57779
  } else {
57820
- debugLog2("setup", "Port 80 is in use, skipping HTTP redirect", verbose);
57780
+ debugLog("setup", "Port 80 is in use, skipping HTTP redirect", verbose);
57821
57781
  log.warn("Port 80 is in use, HTTP to HTTPS redirect will not be available");
57822
57782
  }
57823
57783
  }
@@ -57835,7 +57795,7 @@ async function setupReverseProxy(options3) {
57835
57795
  }
57836
57796
  await createProxyServer(from, to, fromPort, finalPort, hostname, sourceUrl, ssl, verbose);
57837
57797
  } catch (err3) {
57838
- debugLog2("setup", `Setup failed: ${err3}`, verbose);
57798
+ debugLog("setup", `Setup failed: ${err3}`, verbose);
57839
57799
  log.error(`Failed to setup reverse proxy: ${err3.message}`);
57840
57800
  cleanup({
57841
57801
  domains: [to],
@@ -57845,24 +57805,24 @@ async function setupReverseProxy(options3) {
57845
57805
  }
57846
57806
  }
57847
57807
  function startHttpRedirectServer(verbose) {
57848
- debugLog2("redirect", "Starting HTTP redirect server", verbose);
57808
+ debugLog("redirect", "Starting HTTP redirect server", verbose);
57849
57809
  const server = http.createServer((req, res) => {
57850
57810
  const host = req.headers.host || "";
57851
- debugLog2("redirect", `Redirecting request from ${host}${req.url} to HTTPS`, verbose);
57811
+ debugLog("redirect", `Redirecting request from ${host}${req.url} to HTTPS`, verbose);
57852
57812
  res.writeHead(301, {
57853
57813
  Location: `https://${host}${req.url}`
57854
57814
  });
57855
57815
  res.end();
57856
57816
  }).listen(80);
57857
57817
  activeServers.add(server);
57858
- debugLog2("redirect", "HTTP redirect server started", verbose);
57818
+ debugLog("redirect", "HTTP redirect server started", verbose);
57859
57819
  }
57860
57820
  function startProxy(options3) {
57861
57821
  const mergedOptions = {
57862
57822
  ...config4,
57863
57823
  ...options3
57864
57824
  };
57865
- debugLog2("proxy", `Starting proxy with options: ${JSON.stringify(mergedOptions)}`, mergedOptions?.verbose);
57825
+ debugLog("proxy", `Starting proxy with options: ${JSON.stringify(mergedOptions)}`, mergedOptions?.verbose);
57866
57826
  const serverOptions = {
57867
57827
  from: mergedOptions.from,
57868
57828
  to: mergedOptions.to,
@@ -57872,7 +57832,7 @@ function startProxy(options3) {
57872
57832
  };
57873
57833
  console.log("serverOptions", serverOptions);
57874
57834
  startServer(serverOptions).catch((err3) => {
57875
- debugLog2("proxy", `Failed to start proxy: ${err3}`, mergedOptions.verbose);
57835
+ debugLog("proxy", `Failed to start proxy: ${err3}`, mergedOptions.verbose);
57876
57836
  log.error(`Failed to start proxy: ${err3.message}`);
57877
57837
  cleanup({
57878
57838
  domains: [mergedOptions.to],
@@ -57882,7 +57842,7 @@ function startProxy(options3) {
57882
57842
  });
57883
57843
  }
57884
57844
  async function startProxies(options3) {
57885
- debugLog2("proxies", "Starting proxy setup", options3?.verbose);
57845
+ debugLog("proxies", "Starting proxy setup", options3?.verbose);
57886
57846
  const mergedOptions = {
57887
57847
  ...config4,
57888
57848
  ...options3
@@ -57891,10 +57851,10 @@ async function startProxies(options3) {
57891
57851
  if (mergedOptions.https) {
57892
57852
  const existingSSLConfig = await checkExistingCertificates(mergedOptions);
57893
57853
  if (existingSSLConfig) {
57894
- debugLog2("ssl", `Using existing certificates for ${primaryDomain}`, mergedOptions.verbose);
57854
+ debugLog("ssl", `Using existing certificates for ${primaryDomain}`, mergedOptions.verbose);
57895
57855
  mergedOptions._cachedSSLConfig = existingSSLConfig;
57896
57856
  } else {
57897
- debugLog2("ssl", `No valid certificates found for ${primaryDomain}, generating new ones`, mergedOptions.verbose);
57857
+ debugLog("ssl", `No valid certificates found for ${primaryDomain}, generating new ones`, mergedOptions.verbose);
57898
57858
  await generateCertificate2(mergedOptions);
57899
57859
  const sslConfig2 = await checkExistingCertificates(mergedOptions);
57900
57860
  if (!sslConfig2) {
@@ -57927,14 +57887,14 @@ async function startProxies(options3) {
57927
57887
  process9.on("SIGINT", cleanupHandler);
57928
57888
  process9.on("SIGTERM", cleanupHandler);
57929
57889
  process9.on("uncaughtException", (err3) => {
57930
- debugLog2("process", `Uncaught exception: ${err3}`, true);
57890
+ debugLog("process", `Uncaught exception: ${err3}`, true);
57931
57891
  console.error("Uncaught exception:", err3);
57932
57892
  cleanupHandler();
57933
57893
  });
57934
57894
  for (const option of proxyOptions) {
57935
57895
  try {
57936
57896
  const domain = option.to || "stacks.localhost";
57937
- debugLog2("proxy", `Starting proxy for ${domain} with SSL config: ${!!sslConfig}`, option.verbose);
57897
+ debugLog("proxy", `Starting proxy for ${domain} with SSL config: ${!!sslConfig}`, option.verbose);
57938
57898
  await startServer({
57939
57899
  from: option.from || "localhost:5173",
57940
57900
  to: domain,
@@ -57944,7 +57904,7 @@ async function startProxies(options3) {
57944
57904
  _cachedSSLConfig: sslConfig
57945
57905
  });
57946
57906
  } catch (err3) {
57947
- debugLog2("proxies", `Failed to start proxy for ${option.to}: ${err3}`, option.verbose);
57907
+ debugLog("proxies", `Failed to start proxy for ${option.to}: ${err3}`, option.verbose);
57948
57908
  console.error(`Failed to start proxy for ${option.to}:`, err3);
57949
57909
  cleanupHandler();
57950
57910
  }
@@ -57976,7 +57936,7 @@ export {
57976
57936
  generateCertificate2 as generateCertificate,
57977
57937
  extractHostname,
57978
57938
  src_default as default,
57979
- debugLog2 as debugLog,
57939
+ debugLog,
57980
57940
  config4 as config,
57981
57941
  cleanup,
57982
57942
  checkHosts,