@stacksjs/rpx 0.4.1 → 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/cli.js +394 -308
- package/dist/config.d.ts +3 -2
- package/dist/hosts.d.ts +2 -1
- package/dist/https.d.ts +10 -8
- package/dist/index.js +681 -584
- package/dist/start.d.ts +2 -4
- package/dist/types.d.ts +12 -18
- package/dist/utils.d.ts +11 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -17,11 +17,10 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// src/start.ts
|
|
20
|
-
import * as fs5 from "fs";
|
|
21
20
|
import * as http from "http";
|
|
22
21
|
import * as https from "https";
|
|
23
22
|
import * as net from "net";
|
|
24
|
-
import
|
|
23
|
+
import process9 from "process";
|
|
25
24
|
|
|
26
25
|
// node_modules/@stacksjs/cli/dist/index.js
|
|
27
26
|
import { formatWithOptions } from "util";
|
|
@@ -20468,18 +20467,255 @@ var quotes = collect([
|
|
|
20468
20467
|
]);
|
|
20469
20468
|
var export_prompts = import_prompts.default;
|
|
20470
20469
|
// package.json
|
|
20471
|
-
var version = "0.
|
|
20470
|
+
var version = "0.5.1";
|
|
20471
|
+
|
|
20472
|
+
// src/config.ts
|
|
20473
|
+
import { homedir } from "os";
|
|
20474
|
+
import { join as join2 } from "path";
|
|
20475
|
+
|
|
20476
|
+
// node_modules/bun-config/dist/index.js
|
|
20477
|
+
import { resolve } from "path";
|
|
20478
|
+
import process2 from "process";
|
|
20479
|
+
function deepMerge(target, source) {
|
|
20480
|
+
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
20481
|
+
return source;
|
|
20482
|
+
}
|
|
20483
|
+
if (Array.isArray(source) && Array.isArray(target)) {
|
|
20484
|
+
return source.map((sourceItem, index) => {
|
|
20485
|
+
const targetItem = target[index];
|
|
20486
|
+
if (isObject3(sourceItem) && isObject3(targetItem)) {
|
|
20487
|
+
return deepMerge(targetItem, sourceItem);
|
|
20488
|
+
}
|
|
20489
|
+
return sourceItem;
|
|
20490
|
+
});
|
|
20491
|
+
}
|
|
20492
|
+
if (!isObject3(source) || !isObject3(target)) {
|
|
20493
|
+
return source;
|
|
20494
|
+
}
|
|
20495
|
+
const merged = { ...target };
|
|
20496
|
+
for (const key in source) {
|
|
20497
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
20498
|
+
const sourceValue = source[key];
|
|
20499
|
+
const targetValue = merged[key];
|
|
20500
|
+
if (sourceValue === null || sourceValue === undefined) {
|
|
20501
|
+
merged[key] = sourceValue;
|
|
20502
|
+
} else if (isObject3(sourceValue) && isObject3(targetValue)) {
|
|
20503
|
+
merged[key] = deepMerge(targetValue, sourceValue);
|
|
20504
|
+
} else {
|
|
20505
|
+
merged[key] = sourceValue;
|
|
20506
|
+
}
|
|
20507
|
+
}
|
|
20508
|
+
}
|
|
20509
|
+
return merged;
|
|
20510
|
+
}
|
|
20511
|
+
function isObject3(item) {
|
|
20512
|
+
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
20513
|
+
}
|
|
20514
|
+
async function loadConfig({ name, cwd, defaultConfig }) {
|
|
20515
|
+
const configPath = resolve(cwd || process2.cwd(), `${name}.config`);
|
|
20516
|
+
try {
|
|
20517
|
+
const importedConfig = await import(configPath);
|
|
20518
|
+
const loadedConfig = importedConfig.default || importedConfig;
|
|
20519
|
+
return deepMerge(defaultConfig, loadedConfig);
|
|
20520
|
+
} catch (error) {
|
|
20521
|
+
return defaultConfig;
|
|
20522
|
+
}
|
|
20523
|
+
}
|
|
20524
|
+
|
|
20525
|
+
// src/config.ts
|
|
20526
|
+
var defaultConfig = {
|
|
20527
|
+
from: "localhost:5173",
|
|
20528
|
+
to: "stacks.localhost",
|
|
20529
|
+
https: {
|
|
20530
|
+
basePath: "",
|
|
20531
|
+
caCertPath: join2(homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
|
|
20532
|
+
certPath: join2(homedir(), ".stacks", "ssl", `stacks.localhost.crt`),
|
|
20533
|
+
keyPath: join2(homedir(), ".stacks", "ssl", `stacks.localhost.crt.key`)
|
|
20534
|
+
},
|
|
20535
|
+
etcHostsCleanup: true,
|
|
20536
|
+
verbose: true
|
|
20537
|
+
};
|
|
20538
|
+
var config4 = await loadConfig({
|
|
20539
|
+
name: "reverse-proxy",
|
|
20540
|
+
defaultConfig
|
|
20541
|
+
});
|
|
20472
20542
|
|
|
20473
20543
|
// src/hosts.ts
|
|
20474
|
-
import {
|
|
20475
|
-
import
|
|
20476
|
-
import
|
|
20477
|
-
import
|
|
20478
|
-
import
|
|
20544
|
+
import { exec } from "child_process";
|
|
20545
|
+
import fs from "fs";
|
|
20546
|
+
import os2 from "os";
|
|
20547
|
+
import path from "path";
|
|
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
|
+
}
|
|
20479
20714
|
|
|
20480
20715
|
// src/https.ts
|
|
20481
|
-
import
|
|
20482
|
-
import
|
|
20716
|
+
import fs5 from "fs/promises";
|
|
20717
|
+
import { homedir as homedir2 } from "os";
|
|
20718
|
+
import { join as join4 } from "path";
|
|
20483
20719
|
|
|
20484
20720
|
// node_modules/@stacksjs/tlsx/dist/index.js
|
|
20485
20721
|
import fs2 from "fs";
|
|
@@ -20503,7 +20739,7 @@ import {
|
|
|
20503
20739
|
dirname as dirname3,
|
|
20504
20740
|
extname as extname2,
|
|
20505
20741
|
isAbsolute as isAbsolute2,
|
|
20506
|
-
join as
|
|
20742
|
+
join as join3,
|
|
20507
20743
|
normalize as normalize2,
|
|
20508
20744
|
parse as parse2,
|
|
20509
20745
|
relative as relative2,
|
|
@@ -20518,7 +20754,7 @@ import process8 from "process";
|
|
|
20518
20754
|
import process102 from "process";
|
|
20519
20755
|
import process182 from "process";
|
|
20520
20756
|
import process112 from "process";
|
|
20521
|
-
import
|
|
20757
|
+
import os3 from "os";
|
|
20522
20758
|
import tty32 from "tty";
|
|
20523
20759
|
import process142 from "process";
|
|
20524
20760
|
import process132 from "process";
|
|
@@ -20527,11 +20763,11 @@ import process162 from "process";
|
|
|
20527
20763
|
import process172 from "process";
|
|
20528
20764
|
import process192 from "process";
|
|
20529
20765
|
import os22 from "os";
|
|
20530
|
-
import path from "path";
|
|
20531
|
-
import { resolve } from "path";
|
|
20532
|
-
import process2 from "process";
|
|
20533
|
-
import fs from "fs";
|
|
20534
20766
|
import path2 from "path";
|
|
20767
|
+
import { resolve as resolve3 } from "path";
|
|
20768
|
+
import process22 from "process";
|
|
20769
|
+
import fs3 from "fs";
|
|
20770
|
+
import path22 from "path";
|
|
20535
20771
|
var __create3 = Object.create;
|
|
20536
20772
|
var __getProtoOf3 = Object.getPrototypeOf;
|
|
20537
20773
|
var __defProp3 = Object.defineProperty;
|
|
@@ -36874,11 +37110,11 @@ var __export3 = (target, all) => {
|
|
|
36874
37110
|
});
|
|
36875
37111
|
};
|
|
36876
37112
|
var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
36877
|
-
function
|
|
37113
|
+
function isObject5(value) {
|
|
36878
37114
|
return value !== null && typeof value === "object";
|
|
36879
37115
|
}
|
|
36880
37116
|
function _defu2(baseObject, defaults, namespace = ".", merger) {
|
|
36881
|
-
if (!
|
|
37117
|
+
if (!isObject5(defaults)) {
|
|
36882
37118
|
return _defu2(baseObject, {}, namespace, merger);
|
|
36883
37119
|
}
|
|
36884
37120
|
const object = Object.assign({}, defaults);
|
|
@@ -36895,7 +37131,7 @@ function _defu2(baseObject, defaults, namespace = ".", merger) {
|
|
|
36895
37131
|
}
|
|
36896
37132
|
if (Array.isArray(value) && Array.isArray(object[key])) {
|
|
36897
37133
|
object[key] = [...value, ...object[key]];
|
|
36898
|
-
} else if (
|
|
37134
|
+
} else if (isObject5(value) && isObject5(object[key])) {
|
|
36899
37135
|
object[key] = _defu2(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
|
|
36900
37136
|
} else {
|
|
36901
37137
|
object[key] = value;
|
|
@@ -41302,7 +41538,7 @@ var require_prompt3 = __commonJS22((exports, module) => {
|
|
|
41302
41538
|
module.exports = Prompt;
|
|
41303
41539
|
});
|
|
41304
41540
|
var require_text3 = __commonJS22((exports, module) => {
|
|
41305
|
-
function asyncGeneratorStep(gen,
|
|
41541
|
+
function asyncGeneratorStep(gen, resolve32, reject, _next, _throw, key, arg) {
|
|
41306
41542
|
try {
|
|
41307
41543
|
var info = gen[key](arg);
|
|
41308
41544
|
var value = info.value;
|
|
@@ -41311,7 +41547,7 @@ var require_text3 = __commonJS22((exports, module) => {
|
|
|
41311
41547
|
return;
|
|
41312
41548
|
}
|
|
41313
41549
|
if (info.done) {
|
|
41314
|
-
|
|
41550
|
+
resolve32(value);
|
|
41315
41551
|
} else {
|
|
41316
41552
|
Promise.resolve(value).then(_next, _throw);
|
|
41317
41553
|
}
|
|
@@ -41319,13 +41555,13 @@ var require_text3 = __commonJS22((exports, module) => {
|
|
|
41319
41555
|
function _asyncToGenerator(fn) {
|
|
41320
41556
|
return function() {
|
|
41321
41557
|
var self2 = this, args = arguments;
|
|
41322
|
-
return new Promise(function(
|
|
41558
|
+
return new Promise(function(resolve32, reject) {
|
|
41323
41559
|
var gen = fn.apply(self2, args);
|
|
41324
41560
|
function _next(value) {
|
|
41325
|
-
asyncGeneratorStep(gen,
|
|
41561
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "next", value);
|
|
41326
41562
|
}
|
|
41327
41563
|
function _throw(err2) {
|
|
41328
|
-
asyncGeneratorStep(gen,
|
|
41564
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "throw", err2);
|
|
41329
41565
|
}
|
|
41330
41566
|
_next(undefined);
|
|
41331
41567
|
});
|
|
@@ -42017,7 +42253,7 @@ var require_dateparts3 = __commonJS22((exports, module) => {
|
|
|
42017
42253
|
};
|
|
42018
42254
|
});
|
|
42019
42255
|
var require_date3 = __commonJS22((exports, module) => {
|
|
42020
|
-
function asyncGeneratorStep(gen,
|
|
42256
|
+
function asyncGeneratorStep(gen, resolve32, reject, _next, _throw, key, arg) {
|
|
42021
42257
|
try {
|
|
42022
42258
|
var info = gen[key](arg);
|
|
42023
42259
|
var value = info.value;
|
|
@@ -42026,7 +42262,7 @@ var require_date3 = __commonJS22((exports, module) => {
|
|
|
42026
42262
|
return;
|
|
42027
42263
|
}
|
|
42028
42264
|
if (info.done) {
|
|
42029
|
-
|
|
42265
|
+
resolve32(value);
|
|
42030
42266
|
} else {
|
|
42031
42267
|
Promise.resolve(value).then(_next, _throw);
|
|
42032
42268
|
}
|
|
@@ -42034,13 +42270,13 @@ var require_date3 = __commonJS22((exports, module) => {
|
|
|
42034
42270
|
function _asyncToGenerator(fn) {
|
|
42035
42271
|
return function() {
|
|
42036
42272
|
var self2 = this, args = arguments;
|
|
42037
|
-
return new Promise(function(
|
|
42273
|
+
return new Promise(function(resolve32, reject) {
|
|
42038
42274
|
var gen = fn.apply(self2, args);
|
|
42039
42275
|
function _next(value) {
|
|
42040
|
-
asyncGeneratorStep(gen,
|
|
42276
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "next", value);
|
|
42041
42277
|
}
|
|
42042
42278
|
function _throw(err2) {
|
|
42043
|
-
asyncGeneratorStep(gen,
|
|
42279
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "throw", err2);
|
|
42044
42280
|
}
|
|
42045
42281
|
_next(undefined);
|
|
42046
42282
|
});
|
|
@@ -42242,7 +42478,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l3)}`, ``);
|
|
|
42242
42478
|
module.exports = DatePrompt;
|
|
42243
42479
|
});
|
|
42244
42480
|
var require_number3 = __commonJS22((exports, module) => {
|
|
42245
|
-
function asyncGeneratorStep(gen,
|
|
42481
|
+
function asyncGeneratorStep(gen, resolve32, reject, _next, _throw, key, arg) {
|
|
42246
42482
|
try {
|
|
42247
42483
|
var info = gen[key](arg);
|
|
42248
42484
|
var value = info.value;
|
|
@@ -42251,7 +42487,7 @@ var require_number3 = __commonJS22((exports, module) => {
|
|
|
42251
42487
|
return;
|
|
42252
42488
|
}
|
|
42253
42489
|
if (info.done) {
|
|
42254
|
-
|
|
42490
|
+
resolve32(value);
|
|
42255
42491
|
} else {
|
|
42256
42492
|
Promise.resolve(value).then(_next, _throw);
|
|
42257
42493
|
}
|
|
@@ -42259,13 +42495,13 @@ var require_number3 = __commonJS22((exports, module) => {
|
|
|
42259
42495
|
function _asyncToGenerator(fn) {
|
|
42260
42496
|
return function() {
|
|
42261
42497
|
var self2 = this, args = arguments;
|
|
42262
|
-
return new Promise(function(
|
|
42498
|
+
return new Promise(function(resolve32, reject) {
|
|
42263
42499
|
var gen = fn.apply(self2, args);
|
|
42264
42500
|
function _next(value) {
|
|
42265
|
-
asyncGeneratorStep(gen,
|
|
42501
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "next", value);
|
|
42266
42502
|
}
|
|
42267
42503
|
function _throw(err2) {
|
|
42268
|
-
asyncGeneratorStep(gen,
|
|
42504
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "throw", err2);
|
|
42269
42505
|
}
|
|
42270
42506
|
_next(undefined);
|
|
42271
42507
|
});
|
|
@@ -42697,7 +42933,7 @@ Instructions:
|
|
|
42697
42933
|
module.exports = MultiselectPrompt;
|
|
42698
42934
|
});
|
|
42699
42935
|
var require_autocomplete3 = __commonJS22((exports, module) => {
|
|
42700
|
-
function asyncGeneratorStep(gen,
|
|
42936
|
+
function asyncGeneratorStep(gen, resolve32, reject, _next, _throw, key, arg) {
|
|
42701
42937
|
try {
|
|
42702
42938
|
var info = gen[key](arg);
|
|
42703
42939
|
var value = info.value;
|
|
@@ -42706,7 +42942,7 @@ var require_autocomplete3 = __commonJS22((exports, module) => {
|
|
|
42706
42942
|
return;
|
|
42707
42943
|
}
|
|
42708
42944
|
if (info.done) {
|
|
42709
|
-
|
|
42945
|
+
resolve32(value);
|
|
42710
42946
|
} else {
|
|
42711
42947
|
Promise.resolve(value).then(_next, _throw);
|
|
42712
42948
|
}
|
|
@@ -42714,13 +42950,13 @@ var require_autocomplete3 = __commonJS22((exports, module) => {
|
|
|
42714
42950
|
function _asyncToGenerator(fn) {
|
|
42715
42951
|
return function() {
|
|
42716
42952
|
var self2 = this, args = arguments;
|
|
42717
|
-
return new Promise(function(
|
|
42953
|
+
return new Promise(function(resolve32, reject) {
|
|
42718
42954
|
var gen = fn.apply(self2, args);
|
|
42719
42955
|
function _next(value) {
|
|
42720
|
-
asyncGeneratorStep(gen,
|
|
42956
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "next", value);
|
|
42721
42957
|
}
|
|
42722
42958
|
function _throw(err2) {
|
|
42723
|
-
asyncGeneratorStep(gen,
|
|
42959
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "throw", err2);
|
|
42724
42960
|
}
|
|
42725
42961
|
_next(undefined);
|
|
42726
42962
|
});
|
|
@@ -43369,7 +43605,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
43369
43605
|
arr2[i] = arr[i];
|
|
43370
43606
|
return arr2;
|
|
43371
43607
|
}
|
|
43372
|
-
function asyncGeneratorStep(gen,
|
|
43608
|
+
function asyncGeneratorStep(gen, resolve32, reject, _next, _throw, key, arg) {
|
|
43373
43609
|
try {
|
|
43374
43610
|
var info = gen[key](arg);
|
|
43375
43611
|
var value = info.value;
|
|
@@ -43378,7 +43614,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
43378
43614
|
return;
|
|
43379
43615
|
}
|
|
43380
43616
|
if (info.done) {
|
|
43381
|
-
|
|
43617
|
+
resolve32(value);
|
|
43382
43618
|
} else {
|
|
43383
43619
|
Promise.resolve(value).then(_next, _throw);
|
|
43384
43620
|
}
|
|
@@ -43386,13 +43622,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
43386
43622
|
function _asyncToGenerator(fn) {
|
|
43387
43623
|
return function() {
|
|
43388
43624
|
var self2 = this, args = arguments;
|
|
43389
|
-
return new Promise(function(
|
|
43625
|
+
return new Promise(function(resolve32, reject) {
|
|
43390
43626
|
var gen = fn.apply(self2, args);
|
|
43391
43627
|
function _next(value) {
|
|
43392
|
-
asyncGeneratorStep(gen,
|
|
43628
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "next", value);
|
|
43393
43629
|
}
|
|
43394
43630
|
function _throw(err2) {
|
|
43395
|
-
asyncGeneratorStep(gen,
|
|
43631
|
+
asyncGeneratorStep(gen, resolve32, reject, _next, _throw, "throw", err2);
|
|
43396
43632
|
}
|
|
43397
43633
|
_next(undefined);
|
|
43398
43634
|
});
|
|
@@ -48055,31 +48291,31 @@ var log2 = {
|
|
|
48055
48291
|
},
|
|
48056
48292
|
echo: (...args) => console.log(...args)
|
|
48057
48293
|
};
|
|
48058
|
-
function userDatabasePath2(
|
|
48059
|
-
return projectPath2(`database/${
|
|
48294
|
+
function userDatabasePath2(path23) {
|
|
48295
|
+
return projectPath2(`database/${path23 || ""}`);
|
|
48060
48296
|
}
|
|
48061
|
-
function appPath2(
|
|
48062
|
-
return projectPath2(`app/${
|
|
48297
|
+
function appPath2(path23) {
|
|
48298
|
+
return projectPath2(`app/${path23 || ""}`);
|
|
48063
48299
|
}
|
|
48064
|
-
function commandsPath2(
|
|
48065
|
-
return appPath2(`Commands/${
|
|
48300
|
+
function commandsPath2(path23) {
|
|
48301
|
+
return appPath2(`Commands/${path23 || ""}`);
|
|
48066
48302
|
}
|
|
48067
|
-
function logsPath2(
|
|
48068
|
-
return storagePath2(`logs/${
|
|
48303
|
+
function logsPath2(path23) {
|
|
48304
|
+
return storagePath2(`logs/${path23 || ""}`);
|
|
48069
48305
|
}
|
|
48070
48306
|
function projectPath2(filePath = "", options2) {
|
|
48071
|
-
let
|
|
48072
|
-
while (
|
|
48073
|
-
|
|
48074
|
-
const finalPath = resolve22(
|
|
48307
|
+
let path23 = process52.cwd();
|
|
48308
|
+
while (path23.includes("storage"))
|
|
48309
|
+
path23 = resolve22(path23, "..");
|
|
48310
|
+
const finalPath = resolve22(path23, filePath);
|
|
48075
48311
|
if (options2?.relative)
|
|
48076
48312
|
return relative2(process52.cwd(), finalPath);
|
|
48077
48313
|
return finalPath;
|
|
48078
48314
|
}
|
|
48079
|
-
function storagePath2(
|
|
48080
|
-
return projectPath2(`storage/${
|
|
48315
|
+
function storagePath2(path23) {
|
|
48316
|
+
return projectPath2(`storage/${path23 || ""}`);
|
|
48081
48317
|
}
|
|
48082
|
-
var
|
|
48318
|
+
var config6 = {
|
|
48083
48319
|
ai: {
|
|
48084
48320
|
deploy: false,
|
|
48085
48321
|
models: [
|
|
@@ -48656,7 +48892,7 @@ var config4 = {
|
|
|
48656
48892
|
}
|
|
48657
48893
|
}
|
|
48658
48894
|
};
|
|
48659
|
-
var defaults_default2 =
|
|
48895
|
+
var defaults_default2 = config6;
|
|
48660
48896
|
var ai_default2 = {
|
|
48661
48897
|
default: "meta.llama2-70b-chat-v1",
|
|
48662
48898
|
models: [
|
|
@@ -53276,11 +53512,11 @@ var createNeverThrowError2 = (message, result, config5 = defaultErrorConfig2) =>
|
|
|
53276
53512
|
};
|
|
53277
53513
|
function __awaiter2(thisArg, _arguments, P22, generator) {
|
|
53278
53514
|
function adopt(value) {
|
|
53279
|
-
return value instanceof P22 ? value : new P22(function(
|
|
53280
|
-
|
|
53515
|
+
return value instanceof P22 ? value : new P22(function(resolve32) {
|
|
53516
|
+
resolve32(value);
|
|
53281
53517
|
});
|
|
53282
53518
|
}
|
|
53283
|
-
return new (P22 || (P22 = Promise))(function(
|
|
53519
|
+
return new (P22 || (P22 = Promise))(function(resolve32, reject) {
|
|
53284
53520
|
function fulfilled(value) {
|
|
53285
53521
|
try {
|
|
53286
53522
|
step(generator.next(value));
|
|
@@ -53296,7 +53532,7 @@ function __awaiter2(thisArg, _arguments, P22, generator) {
|
|
|
53296
53532
|
}
|
|
53297
53533
|
}
|
|
53298
53534
|
function step(result) {
|
|
53299
|
-
result.done ?
|
|
53535
|
+
result.done ? resolve32(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
53300
53536
|
}
|
|
53301
53537
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
53302
53538
|
});
|
|
@@ -53384,14 +53620,14 @@ function __asyncValues2(o) {
|
|
|
53384
53620
|
}, i);
|
|
53385
53621
|
function verb(n) {
|
|
53386
53622
|
i[n] = o[n] && function(v22) {
|
|
53387
|
-
return new Promise(function(
|
|
53388
|
-
v22 = o[n](v22), settle(
|
|
53623
|
+
return new Promise(function(resolve32, reject) {
|
|
53624
|
+
v22 = o[n](v22), settle(resolve32, reject, v22.done, v22.value);
|
|
53389
53625
|
});
|
|
53390
53626
|
};
|
|
53391
53627
|
}
|
|
53392
|
-
function settle(
|
|
53628
|
+
function settle(resolve32, reject, d, v22) {
|
|
53393
53629
|
Promise.resolve(v22).then(function(v3) {
|
|
53394
|
-
|
|
53630
|
+
resolve32({ value: v3, done: d });
|
|
53395
53631
|
}, reject);
|
|
53396
53632
|
}
|
|
53397
53633
|
}
|
|
@@ -53692,7 +53928,7 @@ class Err2 {
|
|
|
53692
53928
|
}
|
|
53693
53929
|
var fromThrowable2 = Result2.fromThrowable;
|
|
53694
53930
|
var import_prompts2 = __toESM22(require_prompts32(), 1);
|
|
53695
|
-
async function
|
|
53931
|
+
async function exec2(command, options2) {
|
|
53696
53932
|
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]|"[^"]*")+/g);
|
|
53697
53933
|
log2.debug("exec:", Array.isArray(command) ? command.join(" ") : command, options2);
|
|
53698
53934
|
log2.debug("cmd:", cmd);
|
|
@@ -53738,7 +53974,7 @@ async function runCommand(command, options2) {
|
|
|
53738
53974
|
stdio: options2?.stdio ?? [options2?.stdin ?? "inherit", "pipe", "pipe"],
|
|
53739
53975
|
verbose: options2?.verbose ?? false
|
|
53740
53976
|
};
|
|
53741
|
-
return await
|
|
53977
|
+
return await exec2(command, opts);
|
|
53742
53978
|
}
|
|
53743
53979
|
var exports_esm2 = {};
|
|
53744
53980
|
__export3(exports_esm2, {
|
|
@@ -54164,7 +54400,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
54164
54400
|
return min;
|
|
54165
54401
|
}
|
|
54166
54402
|
if (process112.platform === "win32") {
|
|
54167
|
-
const osRelease =
|
|
54403
|
+
const osRelease = os3.release().split(".");
|
|
54168
54404
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
54169
54405
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
54170
54406
|
}
|
|
@@ -56703,7 +56939,7 @@ var quotes2 = collect2([
|
|
|
56703
56939
|
]);
|
|
56704
56940
|
var export_prompts2 = import_prompts2.default;
|
|
56705
56941
|
var import_node_forge2 = __toESM3(require_lib2(), 1);
|
|
56706
|
-
function
|
|
56942
|
+
function deepMerge2(target, source) {
|
|
56707
56943
|
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
56708
56944
|
return source;
|
|
56709
56945
|
}
|
|
@@ -56711,7 +56947,7 @@ function deepMerge(target, source) {
|
|
|
56711
56947
|
return source.map((sourceItem, index) => {
|
|
56712
56948
|
const targetItem = target[index];
|
|
56713
56949
|
if (isObject32(sourceItem) && isObject32(targetItem)) {
|
|
56714
|
-
return
|
|
56950
|
+
return deepMerge2(targetItem, sourceItem);
|
|
56715
56951
|
}
|
|
56716
56952
|
return sourceItem;
|
|
56717
56953
|
});
|
|
@@ -56727,7 +56963,7 @@ function deepMerge(target, source) {
|
|
|
56727
56963
|
if (sourceValue === null || sourceValue === undefined) {
|
|
56728
56964
|
merged[key] = sourceValue;
|
|
56729
56965
|
} else if (isObject32(sourceValue) && isObject32(targetValue)) {
|
|
56730
|
-
merged[key] =
|
|
56966
|
+
merged[key] = deepMerge2(targetValue, sourceValue);
|
|
56731
56967
|
} else {
|
|
56732
56968
|
merged[key] = sourceValue;
|
|
56733
56969
|
}
|
|
@@ -56738,35 +56974,37 @@ function deepMerge(target, source) {
|
|
|
56738
56974
|
function isObject32(item) {
|
|
56739
56975
|
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
56740
56976
|
}
|
|
56741
|
-
async function
|
|
56742
|
-
const configPath =
|
|
56977
|
+
async function loadConfig2({ name, cwd, defaultConfig: defaultConfig2 }) {
|
|
56978
|
+
const configPath = resolve3(cwd || process22.cwd(), `${name}.config`);
|
|
56743
56979
|
try {
|
|
56744
56980
|
const importedConfig = await import(configPath);
|
|
56745
56981
|
const loadedConfig = importedConfig.default || importedConfig;
|
|
56746
|
-
return
|
|
56982
|
+
return deepMerge2(defaultConfig2, loadedConfig);
|
|
56747
56983
|
} catch (error) {
|
|
56748
|
-
return
|
|
56749
|
-
}
|
|
56750
|
-
}
|
|
56751
|
-
var
|
|
56984
|
+
return defaultConfig2;
|
|
56985
|
+
}
|
|
56986
|
+
}
|
|
56987
|
+
var defaultConfig2 = {
|
|
56988
|
+
altNameIPs: ["127.0.0.1"],
|
|
56989
|
+
altNameURIs: ["localhost"],
|
|
56990
|
+
organizationName: "Local Development",
|
|
56991
|
+
countryName: "US",
|
|
56992
|
+
stateName: "California",
|
|
56993
|
+
localityName: "Playa Vista",
|
|
56994
|
+
commonName: "stacks.localhost",
|
|
56995
|
+
validityDays: 825,
|
|
56996
|
+
hostCertCN: "stacks.localhost",
|
|
56997
|
+
domain: "stacks.localhost",
|
|
56998
|
+
rootCA: { certificate: "", privateKey: "" },
|
|
56999
|
+
basePath: "",
|
|
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`),
|
|
57003
|
+
verbose: false
|
|
57004
|
+
};
|
|
57005
|
+
var config42 = await loadConfig2({
|
|
56752
57006
|
name: "tls",
|
|
56753
|
-
defaultConfig:
|
|
56754
|
-
altNameIPs: ["127.0.0.1"],
|
|
56755
|
-
altNameURIs: ["localhost"],
|
|
56756
|
-
organizationName: "Local Development",
|
|
56757
|
-
countryName: "US",
|
|
56758
|
-
stateName: "California",
|
|
56759
|
-
localityName: "Playa Vista",
|
|
56760
|
-
commonName: "stacks.localhost",
|
|
56761
|
-
validityDays: 825,
|
|
56762
|
-
hostCertCN: "stacks.localhost",
|
|
56763
|
-
domain: "stacks.localhost",
|
|
56764
|
-
rootCAObject: { certificate: "", privateKey: "" },
|
|
56765
|
-
caCertPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
|
|
56766
|
-
certPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt`),
|
|
56767
|
-
keyPath: path.join(os22.homedir(), ".stacks", "ssl", `stacks.localhost.crt.key`),
|
|
56768
|
-
verbose: false
|
|
56769
|
-
}
|
|
57007
|
+
defaultConfig: defaultConfig2
|
|
56770
57008
|
});
|
|
56771
57009
|
var import_node_forge = __toESM3(require_lib2(), 1);
|
|
56772
57010
|
function makeNumberPositive(hexString) {
|
|
@@ -56780,10 +57018,10 @@ function findFoldersWithFile(rootDir, fileName) {
|
|
|
56780
57018
|
const result = [];
|
|
56781
57019
|
function search(dir) {
|
|
56782
57020
|
try {
|
|
56783
|
-
const files =
|
|
57021
|
+
const files = fs3.readdirSync(dir);
|
|
56784
57022
|
for (const file of files) {
|
|
56785
|
-
const filePath =
|
|
56786
|
-
const stats =
|
|
57023
|
+
const filePath = path22.join(dir, file);
|
|
57024
|
+
const stats = fs3.lstatSync(filePath);
|
|
56787
57025
|
if (stats.isDirectory()) {
|
|
56788
57026
|
search(filePath);
|
|
56789
57027
|
} else if (file === fileName) {
|
|
@@ -56797,26 +57035,26 @@ function findFoldersWithFile(rootDir, fileName) {
|
|
|
56797
57035
|
search(rootDir);
|
|
56798
57036
|
return result;
|
|
56799
57037
|
}
|
|
56800
|
-
function
|
|
57038
|
+
function debugLog2(category, message, verbose) {
|
|
56801
57039
|
if (verbose || config42.verbose) {
|
|
56802
57040
|
console.debug(`[tlsx:${category}] ${message}`);
|
|
56803
57041
|
}
|
|
56804
57042
|
}
|
|
56805
57043
|
function generateRandomSerial(verbose) {
|
|
56806
|
-
|
|
57044
|
+
debugLog2("cert", "Generating random serial number", verbose);
|
|
56807
57045
|
const serialNumber = makeNumberPositive(import_node_forge2.default.util.bytesToHex(import_node_forge2.default.random.getBytesSync(20)));
|
|
56808
|
-
|
|
57046
|
+
debugLog2("cert", `Generated serial number: ${serialNumber}`, verbose);
|
|
56809
57047
|
return serialNumber;
|
|
56810
57048
|
}
|
|
56811
57049
|
function calculateValidityDates(options22) {
|
|
56812
57050
|
const notBeforeDays = options22.notBeforeDays ?? 2;
|
|
56813
57051
|
const validityDays = options22.validityDays ?? (options22.validityYears ? options22.validityYears * 365 : 180);
|
|
56814
|
-
|
|
57052
|
+
debugLog2("cert", "Calculating certificate validity dates", options22.verbose);
|
|
56815
57053
|
const notBefore = new Date(Date.now() - 86400 * notBeforeDays * 1000);
|
|
56816
57054
|
const notAfter = new Date(notBefore.getTime() + validityDays * 24 * 60 * 60 * 1000);
|
|
56817
57055
|
notBefore.setUTCHours(0, 0, 0, 0);
|
|
56818
57056
|
notAfter.setUTCHours(23, 59, 59, 999);
|
|
56819
|
-
|
|
57057
|
+
debugLog2("cert", `Validity period: ${notBefore.toISOString()} to ${notAfter.toISOString()}`, options22.verbose);
|
|
56820
57058
|
return { notBefore, notAfter };
|
|
56821
57059
|
}
|
|
56822
57060
|
function generateCertificateExtensions(options22) {
|
|
@@ -56849,9 +57087,9 @@ function generateCertificateExtensions(options22) {
|
|
|
56849
57087
|
return extensions;
|
|
56850
57088
|
}
|
|
56851
57089
|
async function createRootCA(options22 = {}) {
|
|
56852
|
-
|
|
57090
|
+
debugLog2("ca", "Creating new Root CA Certificate", options22.verbose);
|
|
56853
57091
|
const keySize = options22.keySize || 2048;
|
|
56854
|
-
|
|
57092
|
+
debugLog2("ca", `Generating ${keySize}-bit RSA key pair`, options22.verbose);
|
|
56855
57093
|
const { privateKey, publicKey } = import_node_forge2.pki.rsa.generateKeyPair(keySize);
|
|
56856
57094
|
const attributes = [
|
|
56857
57095
|
{ shortName: "C", value: options22.countryName || config42.countryName },
|
|
@@ -56898,14 +57136,14 @@ async function createRootCA(options22 = {}) {
|
|
|
56898
57136
|
};
|
|
56899
57137
|
}
|
|
56900
57138
|
async function generateCertificate(options22) {
|
|
56901
|
-
|
|
56902
|
-
|
|
56903
|
-
if (!options22.
|
|
57139
|
+
debugLog2("cert", "Generating new certificate", options22.verbose);
|
|
57140
|
+
debugLog2("cert", `Options: ${JSON.stringify(options22)}`, options22.verbose);
|
|
57141
|
+
if (!options22.rootCA?.certificate || !options22.rootCA?.privateKey) {
|
|
56904
57142
|
throw new Error("Root CA certificate and private key are required");
|
|
56905
57143
|
}
|
|
56906
|
-
const caCert = import_node_forge2.pki.certificateFromPem(options22.
|
|
56907
|
-
const caKey = import_node_forge2.pki.privateKeyFromPem(options22.
|
|
56908
|
-
|
|
57144
|
+
const caCert = import_node_forge2.pki.certificateFromPem(options22.rootCA.certificate);
|
|
57145
|
+
const caKey = import_node_forge2.pki.privateKeyFromPem(options22.rootCA.privateKey);
|
|
57146
|
+
debugLog2("cert", "Generating 2048-bit RSA key pair for host certificate", options22.verbose);
|
|
56909
57147
|
const keySize = 2048;
|
|
56910
57148
|
const { privateKey, publicKey } = import_node_forge2.pki.rsa.generateKeyPair(keySize);
|
|
56911
57149
|
const attributes = options22.certificateAttributes || [
|
|
@@ -56936,253 +57174,217 @@ async function generateCertificate(options22) {
|
|
|
56936
57174
|
};
|
|
56937
57175
|
}
|
|
56938
57176
|
async function addCertToSystemTrustStoreAndSaveCert(cert, caCert, options22) {
|
|
56939
|
-
|
|
56940
|
-
|
|
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);
|
|
56941
57179
|
const certPath = storeCertificate(cert, options22);
|
|
56942
|
-
|
|
57180
|
+
debugLog2("trust", "Storing CA certificate", options22?.verbose);
|
|
56943
57181
|
const caCertPath = storeCACertificate(caCert, options22);
|
|
56944
57182
|
const platform22 = os4.platform();
|
|
56945
|
-
|
|
57183
|
+
debugLog2("trust", `Detected platform: ${platform22}`, options22?.verbose);
|
|
56946
57184
|
const args = "TC, C, C";
|
|
56947
57185
|
if (platform22 === "darwin") {
|
|
56948
|
-
|
|
57186
|
+
debugLog2("trust", "Adding certificate to macOS keychain", options22?.verbose);
|
|
56949
57187
|
await runCommand(`sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${caCertPath}`);
|
|
56950
57188
|
} else if (platform22 === "win32") {
|
|
56951
|
-
|
|
57189
|
+
debugLog2("trust", "Adding certificate to Windows certificate store", options22?.verbose);
|
|
56952
57190
|
await runCommand(`certutil -f -v -addstore -enterprise Root ${caCertPath}`);
|
|
56953
57191
|
} else if (platform22 === "linux") {
|
|
56954
|
-
|
|
57192
|
+
debugLog2("trust", "Adding certificate to Linux certificate store", options22?.verbose);
|
|
56955
57193
|
const rootDirectory = os4.homedir();
|
|
56956
57194
|
const targetFileName = "cert9.db";
|
|
56957
|
-
|
|
57195
|
+
debugLog2("trust", `Searching for certificate databases in ${rootDirectory}`, options22?.verbose);
|
|
56958
57196
|
const foldersWithFile = findFoldersWithFile(rootDirectory, targetFileName);
|
|
56959
57197
|
for (const folder of foldersWithFile) {
|
|
56960
|
-
|
|
57198
|
+
debugLog2("trust", `Processing certificate database in ${folder}`, options22?.verbose);
|
|
56961
57199
|
try {
|
|
56962
|
-
|
|
57200
|
+
debugLog2("trust", `Attempting to delete existing cert for ${config42.commonName}`, options22?.verbose);
|
|
56963
57201
|
await runCommand(`certutil -d sql:${folder} -D -n ${config42.commonName}`);
|
|
56964
57202
|
} catch (error) {
|
|
56965
|
-
|
|
57203
|
+
debugLog2("trust", `Warning: Error deleting existing cert: ${error}`, options22?.verbose);
|
|
56966
57204
|
console.warn(`Error deleting existing cert: ${error}`);
|
|
56967
57205
|
}
|
|
56968
|
-
|
|
57206
|
+
debugLog2("trust", `Adding new certificate to ${folder}`, options22?.verbose);
|
|
56969
57207
|
await runCommand(`certutil -d sql:${folder} -A -t ${args} -n ${config42.commonName} -i ${caCertPath}`);
|
|
56970
57208
|
log2.info(`Cert added to ${folder}`);
|
|
56971
57209
|
}
|
|
56972
57210
|
} else {
|
|
56973
|
-
|
|
57211
|
+
debugLog2("trust", `Error: Unsupported platform ${platform22}`, options22?.verbose);
|
|
56974
57212
|
throw new Error(`Unsupported platform: ${platform22}`);
|
|
56975
57213
|
}
|
|
56976
|
-
|
|
57214
|
+
debugLog2("trust", "Certificate successfully added to system trust store", options22?.verbose);
|
|
56977
57215
|
return certPath;
|
|
56978
57216
|
}
|
|
56979
57217
|
function storeCertificate(cert, options22) {
|
|
56980
|
-
|
|
56981
|
-
const certPath = options22?.certPath || config42.certPath;
|
|
56982
|
-
const certKeyPath = options22?.keyPath || config42.keyPath;
|
|
56983
|
-
|
|
56984
|
-
|
|
57218
|
+
debugLog2("storage", `Storing certificate and private key with options: ${JSON.stringify(options22)}`, options22?.verbose);
|
|
57219
|
+
const certPath = path3.join(options22?.basePath || config42.basePath, options22?.certPath || config42.certPath);
|
|
57220
|
+
const certKeyPath = path3.join(options22?.basePath || config42.basePath, options22?.keyPath || config42.keyPath);
|
|
57221
|
+
debugLog2("storage", `Certificate path: ${certPath}`, options22?.verbose);
|
|
57222
|
+
debugLog2("storage", `Private key path: ${certKeyPath}`, options22?.verbose);
|
|
56985
57223
|
const certDir = path3.dirname(certPath);
|
|
56986
57224
|
if (!fs2.existsSync(certDir)) {
|
|
56987
|
-
|
|
57225
|
+
debugLog2("storage", `Creating certificate directory: ${certDir}`, options22?.verbose);
|
|
56988
57226
|
fs2.mkdirSync(certDir, { recursive: true });
|
|
56989
57227
|
}
|
|
56990
|
-
|
|
57228
|
+
debugLog2("storage", "Writing certificate file", options22?.verbose);
|
|
56991
57229
|
fs2.writeFileSync(certPath, cert.certificate);
|
|
56992
57230
|
const certKeyDir = path3.dirname(certKeyPath);
|
|
56993
57231
|
if (!fs2.existsSync(certKeyDir)) {
|
|
56994
|
-
|
|
57232
|
+
debugLog2("storage", `Creating private key directory: ${certKeyDir}`, options22?.verbose);
|
|
56995
57233
|
fs2.mkdirSync(certKeyDir, { recursive: true });
|
|
56996
57234
|
}
|
|
56997
|
-
|
|
57235
|
+
debugLog2("storage", "Writing private key file", options22?.verbose);
|
|
56998
57236
|
fs2.writeFileSync(certKeyPath, cert.privateKey);
|
|
56999
|
-
|
|
57237
|
+
debugLog2("storage", "Certificate and private key stored successfully", options22?.verbose);
|
|
57000
57238
|
return certPath;
|
|
57001
57239
|
}
|
|
57002
57240
|
function storeCACertificate(caCert, options22) {
|
|
57003
|
-
|
|
57004
|
-
const caCertPath = options22?.caCertPath || config42.caCertPath;
|
|
57005
|
-
|
|
57241
|
+
debugLog2("storage", "Storing CA certificate", options22?.verbose);
|
|
57242
|
+
const caCertPath = path3.join(options22?.basePath || config42.basePath, options22?.caCertPath || config42.caCertPath);
|
|
57243
|
+
debugLog2("storage", `CA certificate path: ${caCertPath}`, options22?.verbose);
|
|
57006
57244
|
const caCertDir = path3.dirname(caCertPath);
|
|
57007
57245
|
if (!fs2.existsSync(caCertDir)) {
|
|
57008
|
-
|
|
57246
|
+
debugLog2("storage", `Creating CA certificate directory: ${caCertDir}`, options22?.verbose);
|
|
57009
57247
|
fs2.mkdirSync(caCertDir, { recursive: true });
|
|
57010
57248
|
}
|
|
57011
|
-
|
|
57249
|
+
debugLog2("storage", "Writing CA certificate file", options22?.verbose);
|
|
57012
57250
|
fs2.writeFileSync(caCertPath, caCert);
|
|
57013
|
-
|
|
57251
|
+
debugLog2("storage", "CA certificate stored successfully", options22?.verbose);
|
|
57014
57252
|
return caCertPath;
|
|
57015
57253
|
}
|
|
57016
57254
|
var export_tls = import_node_forge2.tls;
|
|
57017
57255
|
var export_pki = import_node_forge2.pki;
|
|
57018
57256
|
var export_forge = import_node_forge2.default;
|
|
57019
57257
|
|
|
57020
|
-
// src/config.ts
|
|
57021
|
-
import os3 from "os";
|
|
57022
|
-
import path4 from "path";
|
|
57023
|
-
|
|
57024
|
-
// node_modules/bun-config/dist/index.js
|
|
57025
|
-
import { resolve as resolve3 } from "path";
|
|
57026
|
-
import process3 from "process";
|
|
57027
|
-
function deepMerge2(target, source) {
|
|
57028
|
-
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
57029
|
-
return source;
|
|
57030
|
-
}
|
|
57031
|
-
if (Array.isArray(source) && Array.isArray(target)) {
|
|
57032
|
-
return source.map((sourceItem, index) => {
|
|
57033
|
-
const targetItem = target[index];
|
|
57034
|
-
if (isObject5(sourceItem) && isObject5(targetItem)) {
|
|
57035
|
-
return deepMerge2(targetItem, sourceItem);
|
|
57036
|
-
}
|
|
57037
|
-
return sourceItem;
|
|
57038
|
-
});
|
|
57039
|
-
}
|
|
57040
|
-
if (!isObject5(source) || !isObject5(target)) {
|
|
57041
|
-
return source;
|
|
57042
|
-
}
|
|
57043
|
-
const merged = { ...target };
|
|
57044
|
-
for (const key in source) {
|
|
57045
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
57046
|
-
const sourceValue = source[key];
|
|
57047
|
-
const targetValue = merged[key];
|
|
57048
|
-
if (sourceValue === null || sourceValue === undefined) {
|
|
57049
|
-
merged[key] = sourceValue;
|
|
57050
|
-
} else if (isObject5(sourceValue) && isObject5(targetValue)) {
|
|
57051
|
-
merged[key] = deepMerge2(targetValue, sourceValue);
|
|
57052
|
-
} else {
|
|
57053
|
-
merged[key] = sourceValue;
|
|
57054
|
-
}
|
|
57055
|
-
}
|
|
57056
|
-
}
|
|
57057
|
-
return merged;
|
|
57058
|
-
}
|
|
57059
|
-
function isObject5(item) {
|
|
57060
|
-
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
57061
|
-
}
|
|
57062
|
-
async function loadConfig2({ name, cwd, defaultConfig }) {
|
|
57063
|
-
const configPath = resolve3(cwd || process3.cwd(), `${name}.config`);
|
|
57064
|
-
try {
|
|
57065
|
-
const importedConfig = await import(configPath);
|
|
57066
|
-
const loadedConfig = importedConfig.default || importedConfig;
|
|
57067
|
-
return deepMerge2(defaultConfig, loadedConfig);
|
|
57068
|
-
} catch (error) {
|
|
57069
|
-
return defaultConfig;
|
|
57070
|
-
}
|
|
57071
|
-
}
|
|
57072
|
-
|
|
57073
|
-
// src/config.ts
|
|
57074
|
-
var config6 = await loadConfig2({
|
|
57075
|
-
name: "reverse-proxy",
|
|
57076
|
-
defaultConfig: {
|
|
57077
|
-
from: "localhost:5173",
|
|
57078
|
-
to: "stacks.localhost",
|
|
57079
|
-
https: {
|
|
57080
|
-
caCertPath: path4.join(os3.homedir(), ".stacks", "ssl", `stacks.localhost.ca.crt`),
|
|
57081
|
-
certPath: path4.join(os3.homedir(), ".stacks", "ssl", `stacks.localhost.crt`),
|
|
57082
|
-
keyPath: path4.join(os3.homedir(), ".stacks", "ssl", `stacks.localhost.crt.key`)
|
|
57083
|
-
},
|
|
57084
|
-
etcHostsCleanup: true,
|
|
57085
|
-
verbose: false
|
|
57086
|
-
}
|
|
57087
|
-
});
|
|
57088
|
-
|
|
57089
57258
|
// src/https.ts
|
|
57090
57259
|
var cachedSSLConfig = null;
|
|
57091
|
-
function
|
|
57092
|
-
|
|
57260
|
+
function resolveSSLPaths(options3, defaultConfig3) {
|
|
57261
|
+
const domain = isMultiProxyConfig(options3) ? options3.proxies[0].to || "stacks.localhost" : options3.to || "stacks.localhost";
|
|
57262
|
+
if (typeof options3.https === "object" && typeof defaultConfig3.https === "object") {
|
|
57263
|
+
const hasAllPaths = options3.https.caCertPath && options3.https.certPath && options3.https.keyPath;
|
|
57264
|
+
if (hasAllPaths) {
|
|
57265
|
+
const baseConfig = httpsConfig({
|
|
57266
|
+
...options3,
|
|
57267
|
+
to: domain,
|
|
57268
|
+
https: defaultConfig3.https
|
|
57269
|
+
});
|
|
57270
|
+
const altNameIPs = options3.https.altNameIPs?.filter((ip) => ip !== undefined) || baseConfig.altNameIPs;
|
|
57271
|
+
const altNameURIs = options3.https.altNameURIs?.filter((uri) => uri !== undefined) || baseConfig.altNameURIs;
|
|
57272
|
+
return {
|
|
57273
|
+
...baseConfig,
|
|
57274
|
+
caCertPath: options3.https.caCertPath || baseConfig.caCertPath,
|
|
57275
|
+
certPath: options3.https.certPath || baseConfig.certPath,
|
|
57276
|
+
keyPath: options3.https.keyPath || baseConfig.keyPath,
|
|
57277
|
+
basePath: options3.https.basePath || baseConfig.basePath,
|
|
57278
|
+
commonName: options3.https.commonName || baseConfig.commonName,
|
|
57279
|
+
organizationName: options3.https.organizationName || baseConfig.organizationName,
|
|
57280
|
+
countryName: options3.https.countryName || baseConfig.countryName,
|
|
57281
|
+
stateName: options3.https.stateName || baseConfig.stateName,
|
|
57282
|
+
localityName: options3.https.localityName || baseConfig.localityName,
|
|
57283
|
+
validityDays: options3.https.validityDays || baseConfig.validityDays,
|
|
57284
|
+
altNameIPs,
|
|
57285
|
+
altNameURIs,
|
|
57286
|
+
verbose: options3.verbose || baseConfig.verbose
|
|
57287
|
+
};
|
|
57288
|
+
}
|
|
57289
|
+
}
|
|
57290
|
+
return httpsConfig({
|
|
57291
|
+
...options3,
|
|
57292
|
+
to: domain
|
|
57293
|
+
});
|
|
57093
57294
|
}
|
|
57094
57295
|
function generateWildcardPatterns(domain) {
|
|
57095
57296
|
const patterns = new Set;
|
|
57096
57297
|
patterns.add(domain);
|
|
57097
57298
|
const parts = domain.split(".");
|
|
57098
|
-
if (parts.length >= 2)
|
|
57299
|
+
if (parts.length >= 2)
|
|
57099
57300
|
patterns.add(`*.${parts.slice(1).join(".")}`);
|
|
57100
|
-
}
|
|
57101
57301
|
return Array.from(patterns);
|
|
57102
57302
|
}
|
|
57103
|
-
function
|
|
57104
|
-
const
|
|
57105
|
-
|
|
57106
|
-
|
|
57107
|
-
|
|
57108
|
-
|
|
57109
|
-
|
|
57110
|
-
|
|
57111
|
-
|
|
57112
|
-
|
|
57113
|
-
}
|
|
57114
|
-
|
|
57115
|
-
|
|
57116
|
-
debugLog2("ssl", `Using HTTPS config: ${JSON.stringify(httpsConfig)}`, verbose);
|
|
57117
|
-
const allPatterns = new Set;
|
|
57118
|
-
domains.forEach((domain) => {
|
|
57119
|
-
allPatterns.add(domain);
|
|
57120
|
-
generateWildcardPatterns(domain).forEach((pattern) => allPatterns.add(pattern));
|
|
57121
|
-
});
|
|
57122
|
-
allPatterns.add("localhost");
|
|
57123
|
-
allPatterns.add("*.localhost");
|
|
57124
|
-
const uniqueDomains = Array.from(allPatterns);
|
|
57125
|
-
debugLog2("ssl", `Generated domain patterns: ${uniqueDomains.join(", ")}`, verbose);
|
|
57303
|
+
function generateSSLPaths(options3) {
|
|
57304
|
+
const domain = getPrimaryDomain(options3);
|
|
57305
|
+
let basePath = "";
|
|
57306
|
+
if (typeof options3?.https === "object") {
|
|
57307
|
+
basePath = options3.https.basePath || "";
|
|
57308
|
+
return {
|
|
57309
|
+
caCertPath: options3.https.caCertPath || join4(basePath, `${domain}.ca.crt`),
|
|
57310
|
+
certPath: options3.https.certPath || join4(basePath, `${domain}.crt`),
|
|
57311
|
+
keyPath: options3.https.keyPath || join4(basePath, `${domain}.key`)
|
|
57312
|
+
};
|
|
57313
|
+
}
|
|
57314
|
+
const sslBase = basePath || join4(homedir2(), ".stacks", "ssl");
|
|
57315
|
+
const sanitizedDomain = domain.replace(/\*/g, "wildcard");
|
|
57126
57316
|
return {
|
|
57127
|
-
|
|
57128
|
-
|
|
57129
|
-
|
|
57130
|
-
certPath: httpsConfig?.certPath ?? path6.join(sslBase, "rpx.crt"),
|
|
57131
|
-
keyPath: httpsConfig?.keyPath ?? path6.join(sslBase, "rpx.key"),
|
|
57132
|
-
altNameIPs: httpsConfig?.altNameIPs ?? ["127.0.0.1", "::1"],
|
|
57133
|
-
altNameURIs: httpsConfig?.altNameURIs ?? [],
|
|
57134
|
-
commonName: httpsConfig?.commonName ?? domains[0],
|
|
57135
|
-
organizationName: httpsConfig?.organizationName ?? "Local Development",
|
|
57136
|
-
countryName: httpsConfig?.countryName ?? "US",
|
|
57137
|
-
stateName: httpsConfig?.stateName ?? "California",
|
|
57138
|
-
localityName: httpsConfig?.localityName ?? "Playa Vista",
|
|
57139
|
-
validityDays: httpsConfig?.validityDays ?? 825,
|
|
57140
|
-
verbose: verbose ?? false,
|
|
57141
|
-
subjectAltNames: uniqueDomains.map((domain) => ({
|
|
57142
|
-
type: 2,
|
|
57143
|
-
value: domain
|
|
57144
|
-
}))
|
|
57317
|
+
caCertPath: join4(sslBase, `${sanitizedDomain}.ca.crt`),
|
|
57318
|
+
certPath: join4(sslBase, `${sanitizedDomain}.crt`),
|
|
57319
|
+
keyPath: join4(sslBase, `${sanitizedDomain}.key`)
|
|
57145
57320
|
};
|
|
57146
57321
|
}
|
|
57147
|
-
function
|
|
57148
|
-
const
|
|
57149
|
-
|
|
57150
|
-
|
|
57151
|
-
|
|
57152
|
-
|
|
57153
|
-
|
|
57154
|
-
|
|
57155
|
-
|
|
57156
|
-
|
|
57157
|
-
|
|
57158
|
-
|
|
57159
|
-
|
|
57160
|
-
|
|
57161
|
-
|
|
57162
|
-
|
|
57163
|
-
verbose
|
|
57164
|
-
};
|
|
57322
|
+
function getAllDomains(options3) {
|
|
57323
|
+
const domains = new Set;
|
|
57324
|
+
if (isMultiProxyOptions(options3)) {
|
|
57325
|
+
options3.proxies.forEach((proxy) => {
|
|
57326
|
+
const domain = proxy.to || "stacks.localhost";
|
|
57327
|
+
generateWildcardPatterns(domain).forEach((pattern) => domains.add(pattern));
|
|
57328
|
+
});
|
|
57329
|
+
} else if (isSingleProxyOptions(options3)) {
|
|
57330
|
+
const domain = options3.to || "stacks.localhost";
|
|
57331
|
+
generateWildcardPatterns(domain).forEach((pattern) => domains.add(pattern));
|
|
57332
|
+
} else {
|
|
57333
|
+
domains.add("stacks.localhost");
|
|
57334
|
+
}
|
|
57335
|
+
domains.add("localhost");
|
|
57336
|
+
domains.add("*.localhost");
|
|
57337
|
+
return domains;
|
|
57165
57338
|
}
|
|
57166
|
-
function
|
|
57167
|
-
|
|
57339
|
+
async function loadSSLConfig(options3) {
|
|
57340
|
+
debugLog("ssl", `Loading SSL configuration`, options3.verbose);
|
|
57341
|
+
const mergedOptions = {
|
|
57342
|
+
...config4,
|
|
57343
|
+
...options3
|
|
57344
|
+
};
|
|
57345
|
+
options3.https = httpsConfig(mergedOptions);
|
|
57346
|
+
if (!options3.https?.keyPath && !options3.https?.certPath) {
|
|
57347
|
+
debugLog("ssl", "No SSL configuration provided", options3.verbose);
|
|
57348
|
+
return null;
|
|
57349
|
+
}
|
|
57350
|
+
if (options3.https?.keyPath && !options3.https?.certPath || !options3.https?.keyPath && options3.https?.certPath) {
|
|
57351
|
+
const missing = !options3.https?.keyPath ? "keyPath" : "certPath";
|
|
57352
|
+
debugLog("ssl", `Invalid SSL configuration - missing ${missing}`, options3.verbose);
|
|
57353
|
+
throw new Error(`SSL Configuration requires both keyPath and certPath. Missing: ${missing}`);
|
|
57354
|
+
}
|
|
57355
|
+
try {
|
|
57356
|
+
if (!options3.https?.keyPath || !options3.https?.certPath)
|
|
57357
|
+
return null;
|
|
57358
|
+
try {
|
|
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);
|
|
57363
|
+
return { key, cert };
|
|
57364
|
+
} catch (error) {
|
|
57365
|
+
debugLog("ssl", `Failed to read certificates: ${error}`, options3.verbose);
|
|
57366
|
+
return null;
|
|
57367
|
+
}
|
|
57368
|
+
} catch (err3) {
|
|
57369
|
+
debugLog("ssl", `SSL configuration error: ${err3}`, options3.verbose);
|
|
57370
|
+
throw err3;
|
|
57371
|
+
}
|
|
57168
57372
|
}
|
|
57169
57373
|
async function generateCertificate2(options3) {
|
|
57170
57374
|
if (cachedSSLConfig) {
|
|
57171
|
-
|
|
57172
|
-
debugLog2("ssl", "Using cached SSL configuration", verbose2);
|
|
57375
|
+
debugLog("ssl", "Using cached SSL configuration", options3.verbose);
|
|
57173
57376
|
return;
|
|
57174
57377
|
}
|
|
57175
|
-
const domains =
|
|
57176
|
-
|
|
57177
|
-
|
|
57178
|
-
const rootCAConfig = generateRootCAConfig(verbose);
|
|
57378
|
+
const domains = isMultiProxyOptions(options3) ? options3.proxies.map((proxy) => proxy.to) : [options3.to];
|
|
57379
|
+
debugLog("ssl", `Generating certificate for domains: ${domains.join(", ")}`, options3.verbose);
|
|
57380
|
+
const rootCAConfig = httpsConfig(options3, options3.verbose);
|
|
57179
57381
|
log.info("Generating Root CA certificate...");
|
|
57180
57382
|
const caCert = await createRootCA(rootCAConfig);
|
|
57181
|
-
const hostConfig =
|
|
57383
|
+
const hostConfig = httpsConfig(options3, options3.verbose);
|
|
57182
57384
|
log.info(`Generating host certificate for: ${domains.join(", ")}`);
|
|
57183
57385
|
const hostCert = await generateCertificate({
|
|
57184
57386
|
...hostConfig,
|
|
57185
|
-
|
|
57387
|
+
rootCA: {
|
|
57186
57388
|
certificate: caCert.certificate,
|
|
57187
57389
|
privateKey: caCert.privateKey
|
|
57188
57390
|
}
|
|
@@ -57194,283 +57396,145 @@ async function generateCertificate2(options3) {
|
|
|
57194
57396
|
ca: caCert.certificate
|
|
57195
57397
|
};
|
|
57196
57398
|
log.success(`Certificate generated successfully for ${domains.length} domain${domains.length > 1 ? "s" : ""}`);
|
|
57197
|
-
|
|
57399
|
+
debugLog("ssl", `Certificate includes domains: ${domains.join(", ")}`, options3.verbose);
|
|
57198
57400
|
}
|
|
57199
57401
|
function getSSLConfig() {
|
|
57200
57402
|
return cachedSSLConfig;
|
|
57201
57403
|
}
|
|
57202
|
-
|
|
57203
|
-
|
|
57204
|
-
|
|
57205
|
-
if (verbose) {
|
|
57206
|
-
console.debug(`[rpx:${category}] ${message}`);
|
|
57207
|
-
}
|
|
57208
|
-
}
|
|
57209
|
-
function extractDomains(options3) {
|
|
57210
|
-
if (isMultiProxyConfig(options3)) {
|
|
57211
|
-
return options3.proxies.map((proxy) => {
|
|
57212
|
-
const domain2 = proxy.to || "stacks.localhost";
|
|
57213
|
-
return domain2.startsWith("http") ? new URL(domain2).hostname : domain2;
|
|
57214
|
-
});
|
|
57215
|
-
}
|
|
57216
|
-
const domain = options3.to || "stacks.localhost";
|
|
57217
|
-
return [domain.startsWith("http") ? new URL(domain).hostname : domain];
|
|
57218
|
-
}
|
|
57219
|
-
|
|
57220
|
-
// src/hosts.ts
|
|
57221
|
-
var hostsFilePath = process9.platform === "win32" ? path7.join(process9.env.windir || "C:\\Windows", "System32", "drivers", "etc", "hosts") : "/etc/hosts";
|
|
57222
|
-
async function sudoWrite(operation, content) {
|
|
57223
|
-
return new Promise((resolve4, reject) => {
|
|
57224
|
-
if (process9.platform === "win32") {
|
|
57225
|
-
reject(new Error("Administrator privileges required on Windows"));
|
|
57226
|
-
return;
|
|
57227
|
-
}
|
|
57228
|
-
const tmpFile = path7.join(os7.tmpdir(), "hosts.tmp");
|
|
57229
|
-
try {
|
|
57230
|
-
if (operation === "append") {
|
|
57231
|
-
const currentContent = fs3.readFileSync(hostsFilePath, "utf8");
|
|
57232
|
-
fs3.writeFileSync(tmpFile, currentContent + content, "utf8");
|
|
57233
|
-
} else {
|
|
57234
|
-
fs3.writeFileSync(tmpFile, content, "utf8");
|
|
57235
|
-
}
|
|
57236
|
-
const sudo = spawn("sudo", ["cp", tmpFile, hostsFilePath]);
|
|
57237
|
-
sudo.on("close", (code) => {
|
|
57238
|
-
try {
|
|
57239
|
-
fs3.unlinkSync(tmpFile);
|
|
57240
|
-
if (code === 0)
|
|
57241
|
-
resolve4();
|
|
57242
|
-
else
|
|
57243
|
-
reject(new Error(`sudo process exited with code ${code}`));
|
|
57244
|
-
} catch (err3) {
|
|
57245
|
-
reject(err3);
|
|
57246
|
-
}
|
|
57247
|
-
});
|
|
57248
|
-
sudo.on("error", (err3) => {
|
|
57249
|
-
try {
|
|
57250
|
-
fs3.unlinkSync(tmpFile);
|
|
57251
|
-
} catch {
|
|
57252
|
-
}
|
|
57253
|
-
reject(err3);
|
|
57254
|
-
});
|
|
57255
|
-
} catch (err3) {
|
|
57256
|
-
reject(err3);
|
|
57257
|
-
}
|
|
57258
|
-
});
|
|
57259
|
-
}
|
|
57260
|
-
async function addHosts(hosts, verbose) {
|
|
57261
|
-
debugLog2("hosts", `Adding hosts: ${hosts.join(", ")}`, verbose);
|
|
57262
|
-
debugLog2("hosts", `Using hosts file at: ${hostsFilePath}`, verbose);
|
|
57404
|
+
async function checkExistingCertificates(options3) {
|
|
57405
|
+
const name = getPrimaryDomain(options3);
|
|
57406
|
+
const paths = generateSSLPaths(options3);
|
|
57263
57407
|
try {
|
|
57264
|
-
|
|
57265
|
-
|
|
57266
|
-
|
|
57267
|
-
|
|
57268
|
-
|
|
57269
|
-
|
|
57270
|
-
|
|
57271
|
-
|
|
57272
|
-
|
|
57273
|
-
|
|
57274
|
-
|
|
57275
|
-
|
|
57276
|
-
# Added by rpx
|
|
57277
|
-
127.0.0.1 ${host}
|
|
57278
|
-
::1 ${host}`).join(`
|
|
57279
|
-
`);
|
|
57280
|
-
try {
|
|
57281
|
-
await fs3.promises.appendFile(hostsFilePath, hostEntries, { flag: "a" });
|
|
57282
|
-
log.success(`Added new hosts: ${newEntries.join(", ")}`);
|
|
57283
|
-
} catch (writeErr) {
|
|
57284
|
-
if (writeErr.code === "EACCES") {
|
|
57285
|
-
debugLog2("hosts", "Permission denied, attempting with sudo", verbose);
|
|
57286
|
-
try {
|
|
57287
|
-
await sudoWrite("append", hostEntries);
|
|
57288
|
-
log.success(`Added new hosts with sudo: ${newEntries.join(", ")}`);
|
|
57289
|
-
} catch (sudoErr) {
|
|
57290
|
-
log.error("Failed to modify hosts file automatically");
|
|
57291
|
-
log.warn("Please add these entries to your hosts file manually:");
|
|
57292
|
-
hostEntries.split(`
|
|
57293
|
-
`).forEach((entry) => log.warn(entry));
|
|
57294
|
-
if (process9.platform === "win32") {
|
|
57295
|
-
log.warn(`
|
|
57296
|
-
On Windows:`);
|
|
57297
|
-
log.warn("1. Run notepad as administrator");
|
|
57298
|
-
log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
|
|
57299
|
-
} else {
|
|
57300
|
-
log.warn(`
|
|
57301
|
-
On Unix systems:`);
|
|
57302
|
-
log.warn(`sudo nano ${hostsFilePath}`);
|
|
57303
|
-
}
|
|
57304
|
-
throw new Error("Failed to modify hosts file: manual intervention required");
|
|
57305
|
-
}
|
|
57306
|
-
} else {
|
|
57307
|
-
throw writeErr;
|
|
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");
|
|
57414
|
+
let ca;
|
|
57415
|
+
if (paths.caCertPath) {
|
|
57416
|
+
try {
|
|
57417
|
+
ca = await fs5.readFile(paths.caCertPath, "utf8");
|
|
57418
|
+
} catch (err3) {
|
|
57419
|
+
debugLog("ssl", `Failed to read CA cert: ${err3}`, options3?.verbose);
|
|
57308
57420
|
}
|
|
57309
57421
|
}
|
|
57422
|
+
return { key, cert, ca };
|
|
57310
57423
|
} catch (err3) {
|
|
57311
|
-
|
|
57312
|
-
|
|
57313
|
-
throw error;
|
|
57424
|
+
debugLog("ssl", `Failed to read certificates: ${err3}`, options3?.verbose);
|
|
57425
|
+
return null;
|
|
57314
57426
|
}
|
|
57315
57427
|
}
|
|
57316
|
-
|
|
57317
|
-
|
|
57318
|
-
|
|
57319
|
-
|
|
57320
|
-
|
|
57321
|
-
|
|
57322
|
-
|
|
57323
|
-
|
|
57324
|
-
|
|
57325
|
-
|
|
57326
|
-
|
|
57327
|
-
|
|
57328
|
-
|
|
57329
|
-
|
|
57330
|
-
|
|
57331
|
-
|
|
57332
|
-
|
|
57333
|
-
|
|
57334
|
-
|
|
57335
|
-
|
|
57336
|
-
|
|
57337
|
-
|
|
57338
|
-
|
|
57339
|
-
|
|
57340
|
-
|
|
57341
|
-
|
|
57342
|
-
|
|
57343
|
-
|
|
57344
|
-
|
|
57345
|
-
|
|
57346
|
-
hosts.forEach((host) => {
|
|
57347
|
-
log.warn("# Added by rpx");
|
|
57348
|
-
log.warn(`127.0.0.1 ${host}`);
|
|
57349
|
-
log.warn(`::1 ${host}`);
|
|
57350
|
-
});
|
|
57351
|
-
if (process9.platform === "win32") {
|
|
57352
|
-
log.warn(`
|
|
57353
|
-
On Windows:`);
|
|
57354
|
-
log.warn("1. Run notepad as administrator");
|
|
57355
|
-
log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
|
|
57356
|
-
} else {
|
|
57357
|
-
log.warn(`
|
|
57358
|
-
On Unix systems:`);
|
|
57359
|
-
log.warn(`sudo nano ${hostsFilePath}`);
|
|
57360
|
-
}
|
|
57361
|
-
throw new Error("Failed to modify hosts file: manual intervention required");
|
|
57362
|
-
}
|
|
57363
|
-
} else {
|
|
57364
|
-
throw writeErr;
|
|
57365
|
-
}
|
|
57366
|
-
}
|
|
57367
|
-
} catch (err3) {
|
|
57368
|
-
const error = err3;
|
|
57369
|
-
log.error(`Failed to remove hosts: ${error.message}`);
|
|
57370
|
-
throw error;
|
|
57428
|
+
function httpsConfig(options3, verbose) {
|
|
57429
|
+
const primaryDomain = getPrimaryDomain(options3);
|
|
57430
|
+
debugLog("ssl", `Primary domain: ${primaryDomain}`, verbose);
|
|
57431
|
+
const defaultPaths = generateSSLPaths(options3);
|
|
57432
|
+
if (typeof options3.https === "object") {
|
|
57433
|
+
const config5 = {
|
|
57434
|
+
domain: primaryDomain,
|
|
57435
|
+
hostCertCN: primaryDomain,
|
|
57436
|
+
basePath: options3.https.basePath || "",
|
|
57437
|
+
caCertPath: options3.https.caCertPath || defaultPaths.caCertPath,
|
|
57438
|
+
certPath: options3.https.certPath || defaultPaths.certPath,
|
|
57439
|
+
keyPath: options3.https.keyPath || defaultPaths.keyPath,
|
|
57440
|
+
altNameIPs: ["127.0.0.1", "::1"],
|
|
57441
|
+
altNameURIs: [],
|
|
57442
|
+
commonName: options3.https.commonName || primaryDomain,
|
|
57443
|
+
organizationName: options3.https.organizationName || "Local Development",
|
|
57444
|
+
countryName: options3.https.countryName || "US",
|
|
57445
|
+
stateName: options3.https.stateName || "California",
|
|
57446
|
+
localityName: options3.https.localityName || "Playa Vista",
|
|
57447
|
+
validityDays: options3.https.validityDays || 825,
|
|
57448
|
+
verbose: verbose || false,
|
|
57449
|
+
subjectAltNames: Array.from(getAllDomains(options3)).map((domain) => ({
|
|
57450
|
+
type: 2,
|
|
57451
|
+
value: domain
|
|
57452
|
+
}))
|
|
57453
|
+
};
|
|
57454
|
+
if (isValidRootCA(options3.https.rootCA)) {
|
|
57455
|
+
config5.rootCA = options3.https.rootCA;
|
|
57456
|
+
}
|
|
57457
|
+
return config5;
|
|
57371
57458
|
}
|
|
57372
|
-
|
|
57373
|
-
|
|
57374
|
-
|
|
57375
|
-
|
|
57376
|
-
|
|
57377
|
-
|
|
57378
|
-
|
|
57379
|
-
|
|
57380
|
-
|
|
57459
|
+
return {
|
|
57460
|
+
domain: primaryDomain,
|
|
57461
|
+
hostCertCN: primaryDomain,
|
|
57462
|
+
basePath: "",
|
|
57463
|
+
...defaultPaths,
|
|
57464
|
+
altNameIPs: ["127.0.0.1", "::1"],
|
|
57465
|
+
altNameURIs: [],
|
|
57466
|
+
commonName: primaryDomain,
|
|
57467
|
+
organizationName: "Local Development",
|
|
57468
|
+
countryName: "US",
|
|
57469
|
+
stateName: "California",
|
|
57470
|
+
localityName: "Playa Vista",
|
|
57471
|
+
validityDays: 825,
|
|
57472
|
+
verbose: verbose || false,
|
|
57473
|
+
subjectAltNames: Array.from(getAllDomains(options3)).map((domain) => ({
|
|
57474
|
+
type: 2,
|
|
57475
|
+
value: domain
|
|
57476
|
+
}))
|
|
57477
|
+
};
|
|
57381
57478
|
}
|
|
57382
57479
|
|
|
57383
57480
|
// src/start.ts
|
|
57384
57481
|
var activeServers = new Set;
|
|
57385
57482
|
async function cleanup(options3) {
|
|
57386
|
-
|
|
57483
|
+
debugLog("cleanup", "Starting cleanup process", options3?.verbose);
|
|
57387
57484
|
console.log(`
|
|
57388
57485
|
`);
|
|
57389
57486
|
log.info("Shutting down proxy servers...");
|
|
57390
57487
|
const cleanupPromises = [];
|
|
57391
57488
|
const serverClosePromises = Array.from(activeServers).map((server) => new Promise((resolve4) => {
|
|
57392
57489
|
server.close(() => {
|
|
57393
|
-
|
|
57490
|
+
debugLog("cleanup", "Server closed successfully", options3?.verbose);
|
|
57394
57491
|
resolve4();
|
|
57395
57492
|
});
|
|
57396
57493
|
}));
|
|
57397
57494
|
cleanupPromises.push(...serverClosePromises);
|
|
57398
57495
|
if (options3?.etcHostsCleanup && options3.domains?.length) {
|
|
57399
|
-
|
|
57496
|
+
debugLog("cleanup", "Cleaning up hosts file entries", options3?.verbose);
|
|
57400
57497
|
const domainsToClean = options3.domains.filter((domain) => !domain.includes("localhost"));
|
|
57401
57498
|
if (domainsToClean.length > 0) {
|
|
57402
57499
|
log.info("Cleaning up hosts file entries...");
|
|
57403
57500
|
cleanupPromises.push(removeHosts(domainsToClean, options3?.verbose).then(() => {
|
|
57404
|
-
|
|
57501
|
+
debugLog("cleanup", `Removed hosts entries for ${domainsToClean.join(", ")}`, options3?.verbose);
|
|
57405
57502
|
}).catch((err3) => {
|
|
57406
|
-
|
|
57503
|
+
debugLog("cleanup", `Failed to remove hosts entries: ${err3}`, options3?.verbose);
|
|
57407
57504
|
log.warn(`Failed to clean up hosts file entries for ${domainsToClean.join(", ")}:`, err3);
|
|
57408
57505
|
}));
|
|
57409
57506
|
}
|
|
57410
57507
|
}
|
|
57411
57508
|
try {
|
|
57412
57509
|
await Promise.all(cleanupPromises);
|
|
57413
|
-
|
|
57510
|
+
debugLog("cleanup", "All cleanup tasks completed successfully", options3?.verbose);
|
|
57414
57511
|
log.success("All cleanup tasks completed successfully");
|
|
57415
|
-
|
|
57512
|
+
process9.exit(0);
|
|
57416
57513
|
} catch (err3) {
|
|
57417
|
-
|
|
57514
|
+
debugLog("cleanup", `Error during cleanup: ${err3}`, options3?.verbose);
|
|
57418
57515
|
log.error("Error during cleanup:", err3);
|
|
57419
|
-
|
|
57516
|
+
process9.exit(1);
|
|
57420
57517
|
}
|
|
57421
57518
|
}
|
|
57422
|
-
|
|
57423
|
-
|
|
57424
|
-
|
|
57425
|
-
|
|
57519
|
+
process9.on("SIGINT", cleanup);
|
|
57520
|
+
process9.on("SIGTERM", cleanup);
|
|
57521
|
+
process9.on("uncaughtException", (err3) => {
|
|
57522
|
+
debugLog("process", `Uncaught exception: ${err3}`, true);
|
|
57426
57523
|
log.error("Uncaught exception:", err3);
|
|
57427
57524
|
cleanup();
|
|
57428
57525
|
});
|
|
57429
|
-
async function loadSSLConfig(options3) {
|
|
57430
|
-
debugLog2("ssl", `Loading SSL configuration`, options3.verbose);
|
|
57431
|
-
if (options3.https === true)
|
|
57432
|
-
options3.https = httpsConfig(options3);
|
|
57433
|
-
else if (options3.https === false)
|
|
57434
|
-
return null;
|
|
57435
|
-
if (!options3.https?.keyPath && !options3.https?.certPath) {
|
|
57436
|
-
debugLog2("ssl", "No SSL configuration provided", options3.verbose);
|
|
57437
|
-
return null;
|
|
57438
|
-
}
|
|
57439
|
-
if (options3.https?.keyPath && !options3.https?.certPath || !options3.https?.keyPath && options3.https?.certPath) {
|
|
57440
|
-
const missing = !options3.https?.keyPath ? "keyPath" : "certPath";
|
|
57441
|
-
debugLog2("ssl", `Invalid SSL configuration - missing ${missing}`, options3.verbose);
|
|
57442
|
-
throw new Error(`SSL Configuration requires both keyPath and certPath. Missing: ${missing}`);
|
|
57443
|
-
}
|
|
57444
|
-
try {
|
|
57445
|
-
if (!options3.https?.keyPath || !options3.https?.certPath)
|
|
57446
|
-
return null;
|
|
57447
|
-
try {
|
|
57448
|
-
debugLog2("ssl", "Reading SSL certificate files", options3.verbose);
|
|
57449
|
-
const key = await fs5.promises.readFile(options3.https?.keyPath, "utf8");
|
|
57450
|
-
const cert = await fs5.promises.readFile(options3.https?.certPath, "utf8");
|
|
57451
|
-
debugLog2("ssl", "SSL configuration loaded successfully", options3.verbose);
|
|
57452
|
-
return { key, cert };
|
|
57453
|
-
} catch (error) {
|
|
57454
|
-
debugLog2("ssl", `Failed to read certificates: ${error}`, options3.verbose);
|
|
57455
|
-
return null;
|
|
57456
|
-
}
|
|
57457
|
-
} catch (err3) {
|
|
57458
|
-
debugLog2("ssl", `SSL configuration error: ${err3}`, options3.verbose);
|
|
57459
|
-
throw err3;
|
|
57460
|
-
}
|
|
57461
|
-
}
|
|
57462
57526
|
function isPortInUse(port, hostname, verbose) {
|
|
57463
|
-
|
|
57527
|
+
debugLog("port", `Checking if port ${port} is in use on ${hostname}`, verbose);
|
|
57464
57528
|
return new Promise((resolve4) => {
|
|
57465
57529
|
const server = net.createServer();
|
|
57466
57530
|
server.once("error", (err3) => {
|
|
57467
57531
|
if (err3.code === "EADDRINUSE") {
|
|
57468
|
-
|
|
57532
|
+
debugLog("port", `Port ${port} is in use`, verbose);
|
|
57469
57533
|
resolve4(true);
|
|
57470
57534
|
}
|
|
57471
57535
|
});
|
|
57472
57536
|
server.once("listening", () => {
|
|
57473
|
-
|
|
57537
|
+
debugLog("port", `Port ${port} is available`, verbose);
|
|
57474
57538
|
server.close();
|
|
57475
57539
|
resolve4(false);
|
|
57476
57540
|
});
|
|
@@ -57478,17 +57542,17 @@ function isPortInUse(port, hostname, verbose) {
|
|
|
57478
57542
|
});
|
|
57479
57543
|
}
|
|
57480
57544
|
async function findAvailablePort(startPort, hostname, verbose) {
|
|
57481
|
-
|
|
57545
|
+
debugLog("port", `Finding available port starting from ${startPort}`, verbose);
|
|
57482
57546
|
let port = startPort;
|
|
57483
57547
|
while (await isPortInUse(port, hostname, verbose)) {
|
|
57484
|
-
|
|
57548
|
+
debugLog("port", `Port ${port} is in use, trying ${port + 1}`, verbose);
|
|
57485
57549
|
port++;
|
|
57486
57550
|
}
|
|
57487
|
-
|
|
57551
|
+
debugLog("port", `Found available port: ${port}`, verbose);
|
|
57488
57552
|
return port;
|
|
57489
57553
|
}
|
|
57490
57554
|
async function testConnection(hostname, port, verbose) {
|
|
57491
|
-
|
|
57555
|
+
debugLog("connection", `Testing connection to ${hostname}:${port}`, verbose);
|
|
57492
57556
|
return new Promise((resolve4, reject) => {
|
|
57493
57557
|
const socket = net.connect({
|
|
57494
57558
|
host: hostname,
|
|
@@ -57496,30 +57560,30 @@ async function testConnection(hostname, port, verbose) {
|
|
|
57496
57560
|
timeout: 5000
|
|
57497
57561
|
});
|
|
57498
57562
|
socket.once("connect", () => {
|
|
57499
|
-
|
|
57563
|
+
debugLog("connection", `Successfully connected to ${hostname}:${port}`, verbose);
|
|
57500
57564
|
socket.end();
|
|
57501
57565
|
resolve4();
|
|
57502
57566
|
});
|
|
57503
57567
|
socket.once("timeout", () => {
|
|
57504
|
-
|
|
57568
|
+
debugLog("connection", `Connection to ${hostname}:${port} timed out`, verbose);
|
|
57505
57569
|
socket.destroy();
|
|
57506
57570
|
reject(new Error(`Connection to ${hostname}:${port} timed out`));
|
|
57507
57571
|
});
|
|
57508
57572
|
socket.once("error", (err3) => {
|
|
57509
|
-
|
|
57573
|
+
debugLog("connection", `Failed to connect to ${hostname}:${port}: ${err3}`, verbose);
|
|
57510
57574
|
socket.destroy();
|
|
57511
57575
|
reject(new Error(`Failed to connect to ${hostname}:${port}: ${err3.message}`));
|
|
57512
57576
|
});
|
|
57513
57577
|
});
|
|
57514
57578
|
}
|
|
57515
57579
|
async function startServer(options3) {
|
|
57516
|
-
|
|
57517
|
-
const fromUrl = new URL(options3.from
|
|
57518
|
-
const toUrl = new URL(options3.to
|
|
57580
|
+
debugLog("server", `Starting server with options: ${JSON.stringify(options3)}`, options3.verbose);
|
|
57581
|
+
const fromUrl = new URL((options3.from?.startsWith("http") ? options3.from : `http://${options3.from}`) || "localhost:5173");
|
|
57582
|
+
const toUrl = new URL((options3.to?.startsWith("http") ? options3.to : `http://${options3.to}`) || "stacks.localhost");
|
|
57519
57583
|
const fromPort = Number.parseInt(fromUrl.port) || (fromUrl.protocol.includes("https:") ? 443 : 80);
|
|
57520
57584
|
const hostsToCheck = [toUrl.hostname];
|
|
57521
57585
|
if (!toUrl.hostname.includes("localhost") && !toUrl.hostname.includes("127.0.0.1")) {
|
|
57522
|
-
|
|
57586
|
+
debugLog("hosts", `Checking if hosts file entry exists for: ${toUrl.hostname}`, options3?.verbose);
|
|
57523
57587
|
try {
|
|
57524
57588
|
const hostsExist = await checkHosts(hostsToCheck, options3.verbose);
|
|
57525
57589
|
if (!hostsExist[0]) {
|
|
@@ -57532,7 +57596,7 @@ async function startServer(options3) {
|
|
|
57532
57596
|
log.warn("You can manually add this entry to your hosts file:");
|
|
57533
57597
|
log.warn(`127.0.0.1 ${toUrl.hostname}`);
|
|
57534
57598
|
log.warn(`::1 ${toUrl.hostname}`);
|
|
57535
|
-
if (
|
|
57599
|
+
if (process9.platform === "win32") {
|
|
57536
57600
|
log.warn("On Windows:");
|
|
57537
57601
|
log.warn("1. Run notepad as administrator");
|
|
57538
57602
|
log.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");
|
|
@@ -57542,7 +57606,7 @@ async function startServer(options3) {
|
|
|
57542
57606
|
}
|
|
57543
57607
|
}
|
|
57544
57608
|
} else {
|
|
57545
|
-
|
|
57609
|
+
debugLog("hosts", `Host entry already exists for ${toUrl.hostname}`, options3.verbose);
|
|
57546
57610
|
}
|
|
57547
57611
|
} catch (checkError) {
|
|
57548
57612
|
log.error("Failed to check hosts file:", checkError.message);
|
|
@@ -57551,9 +57615,9 @@ async function startServer(options3) {
|
|
|
57551
57615
|
try {
|
|
57552
57616
|
await testConnection(fromUrl.hostname, fromPort, options3.verbose);
|
|
57553
57617
|
} catch (err3) {
|
|
57554
|
-
|
|
57618
|
+
debugLog("server", `Connection test failed: ${err3}`, options3.verbose);
|
|
57555
57619
|
log.error(err3.message);
|
|
57556
|
-
|
|
57620
|
+
process9.exit(1);
|
|
57557
57621
|
}
|
|
57558
57622
|
let sslConfig = options3._cachedSSLConfig || null;
|
|
57559
57623
|
if (options3.https) {
|
|
@@ -57565,17 +57629,17 @@ async function startServer(options3) {
|
|
|
57565
57629
|
});
|
|
57566
57630
|
}
|
|
57567
57631
|
try {
|
|
57568
|
-
|
|
57632
|
+
debugLog("ssl", `Attempting to load SSL configuration for ${toUrl.hostname}`, options3.verbose);
|
|
57569
57633
|
sslConfig = await loadSSLConfig({
|
|
57570
57634
|
...options3,
|
|
57571
57635
|
to: toUrl.hostname,
|
|
57572
57636
|
https: options3.https
|
|
57573
57637
|
});
|
|
57574
57638
|
} catch (loadError) {
|
|
57575
|
-
|
|
57639
|
+
debugLog("ssl", `Failed to load certificates, will generate new ones: ${loadError}`, options3.verbose);
|
|
57576
57640
|
}
|
|
57577
57641
|
if (!sslConfig) {
|
|
57578
|
-
|
|
57642
|
+
debugLog("ssl", `Generating new certificates for ${toUrl.hostname}`, options3.verbose);
|
|
57579
57643
|
await generateCertificate2({
|
|
57580
57644
|
...options3,
|
|
57581
57645
|
from: fromUrl.toString(),
|
|
@@ -57592,14 +57656,14 @@ async function startServer(options3) {
|
|
|
57592
57656
|
}
|
|
57593
57657
|
}
|
|
57594
57658
|
} catch (err3) {
|
|
57595
|
-
|
|
57659
|
+
debugLog("server", `SSL setup failed: ${err3}`, options3.verbose);
|
|
57596
57660
|
throw err3;
|
|
57597
57661
|
}
|
|
57598
57662
|
}
|
|
57599
|
-
|
|
57663
|
+
debugLog("server", `Setting up reverse proxy with SSL config for ${toUrl.hostname}`, options3.verbose);
|
|
57600
57664
|
await setupReverseProxy({
|
|
57601
57665
|
...options3,
|
|
57602
|
-
from: options3.from,
|
|
57666
|
+
from: options3.from || "localhost:5173",
|
|
57603
57667
|
to: toUrl.hostname,
|
|
57604
57668
|
fromPort,
|
|
57605
57669
|
sourceUrl: {
|
|
@@ -57610,9 +57674,9 @@ async function startServer(options3) {
|
|
|
57610
57674
|
});
|
|
57611
57675
|
}
|
|
57612
57676
|
async function createProxyServer(from, to, fromPort, listenPort, hostname, sourceUrl, ssl, verbose) {
|
|
57613
|
-
|
|
57677
|
+
debugLog("proxy", `Creating proxy server ${from} -> ${to}`, verbose);
|
|
57614
57678
|
const requestHandler = (req, res) => {
|
|
57615
|
-
|
|
57679
|
+
debugLog("request", `Incoming request: ${req.method} ${req.url}`, verbose);
|
|
57616
57680
|
const proxyOptions = {
|
|
57617
57681
|
hostname: sourceUrl.hostname,
|
|
57618
57682
|
port: fromPort,
|
|
@@ -57623,9 +57687,9 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
|
|
|
57623
57687
|
host: sourceUrl.host
|
|
57624
57688
|
}
|
|
57625
57689
|
};
|
|
57626
|
-
|
|
57690
|
+
debugLog("request", `Proxy request options: ${JSON.stringify(proxyOptions)}`, verbose);
|
|
57627
57691
|
const proxyReq = http.request(proxyOptions, (proxyRes) => {
|
|
57628
|
-
|
|
57692
|
+
debugLog("response", `Proxy response received with status ${proxyRes.statusCode}`, verbose);
|
|
57629
57693
|
const headers = {
|
|
57630
57694
|
...proxyRes.headers,
|
|
57631
57695
|
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
|
|
@@ -57635,7 +57699,7 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
|
|
|
57635
57699
|
proxyRes.pipe(res);
|
|
57636
57700
|
});
|
|
57637
57701
|
proxyReq.on("error", (err3) => {
|
|
57638
|
-
|
|
57702
|
+
debugLog("request", `Proxy request failed: ${err3}`, verbose);
|
|
57639
57703
|
log.error("Proxy request failed:", err3);
|
|
57640
57704
|
res.writeHead(502);
|
|
57641
57705
|
res.end(`Proxy Error: ${err3.message}`);
|
|
@@ -57662,11 +57726,11 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
|
|
|
57662
57726
|
allowHTTP1: true,
|
|
57663
57727
|
ALPNProtocols: ["h2", "http/1.1"]
|
|
57664
57728
|
} : undefined;
|
|
57665
|
-
|
|
57729
|
+
debugLog("server", `Creating server with SSL config: ${!!ssl}`, verbose);
|
|
57666
57730
|
const server = ssl && serverOptions ? https.createServer(serverOptions, requestHandler) : http.createServer(requestHandler);
|
|
57667
57731
|
if (ssl) {
|
|
57668
57732
|
server.on("secureConnection", (tlsSocket) => {
|
|
57669
|
-
|
|
57733
|
+
debugLog("tls", `TLS Connection established: ${JSON.stringify({
|
|
57670
57734
|
protocol: tlsSocket.getProtocol?.(),
|
|
57671
57735
|
cipher: tlsSocket.getCipher?.(),
|
|
57672
57736
|
authorized: tlsSocket.authorized,
|
|
@@ -57677,7 +57741,7 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
|
|
|
57677
57741
|
activeServers.add(server);
|
|
57678
57742
|
return new Promise((resolve4, reject) => {
|
|
57679
57743
|
server.listen(listenPort, hostname, () => {
|
|
57680
|
-
|
|
57744
|
+
debugLog("server", `Server listening on port ${listenPort}`, verbose);
|
|
57681
57745
|
console.log("");
|
|
57682
57746
|
console.log(` ${green(bold("reverse-proxy"))} ${green(`v${version}`)}`);
|
|
57683
57747
|
console.log("");
|
|
@@ -57694,13 +57758,13 @@ async function createProxyServer(from, to, fromPort, listenPort, hostname, sourc
|
|
|
57694
57758
|
resolve4();
|
|
57695
57759
|
});
|
|
57696
57760
|
server.on("error", (err3) => {
|
|
57697
|
-
|
|
57761
|
+
debugLog("server", `Server error: ${err3}`, verbose);
|
|
57698
57762
|
reject(err3);
|
|
57699
57763
|
});
|
|
57700
57764
|
});
|
|
57701
57765
|
}
|
|
57702
57766
|
async function setupReverseProxy(options3) {
|
|
57703
|
-
|
|
57767
|
+
debugLog("setup", `Setting up reverse proxy: ${JSON.stringify(options3)}`, options3.verbose);
|
|
57704
57768
|
const { from, to, fromPort, sourceUrl, ssl, verbose, etcHostsCleanup, portManager } = options3;
|
|
57705
57769
|
const httpPort = 80;
|
|
57706
57770
|
const httpsPort = 443;
|
|
@@ -57709,11 +57773,11 @@ async function setupReverseProxy(options3) {
|
|
|
57709
57773
|
if (ssl && !portManager?.usedPorts.has(httpPort)) {
|
|
57710
57774
|
const isHttpPortBusy = await isPortInUse(httpPort, hostname, verbose);
|
|
57711
57775
|
if (!isHttpPortBusy) {
|
|
57712
|
-
|
|
57776
|
+
debugLog("setup", "Starting HTTP redirect server", verbose);
|
|
57713
57777
|
startHttpRedirectServer(verbose);
|
|
57714
57778
|
portManager?.usedPorts.add(httpPort);
|
|
57715
57779
|
} else {
|
|
57716
|
-
|
|
57780
|
+
debugLog("setup", "Port 80 is in use, skipping HTTP redirect", verbose);
|
|
57717
57781
|
log.warn("Port 80 is in use, HTTP to HTTPS redirect will not be available");
|
|
57718
57782
|
}
|
|
57719
57783
|
}
|
|
@@ -57731,7 +57795,7 @@ async function setupReverseProxy(options3) {
|
|
|
57731
57795
|
}
|
|
57732
57796
|
await createProxyServer(from, to, fromPort, finalPort, hostname, sourceUrl, ssl, verbose);
|
|
57733
57797
|
} catch (err3) {
|
|
57734
|
-
|
|
57798
|
+
debugLog("setup", `Setup failed: ${err3}`, verbose);
|
|
57735
57799
|
log.error(`Failed to setup reverse proxy: ${err3.message}`);
|
|
57736
57800
|
cleanup({
|
|
57737
57801
|
domains: [to],
|
|
@@ -57741,70 +57805,96 @@ async function setupReverseProxy(options3) {
|
|
|
57741
57805
|
}
|
|
57742
57806
|
}
|
|
57743
57807
|
function startHttpRedirectServer(verbose) {
|
|
57744
|
-
|
|
57808
|
+
debugLog("redirect", "Starting HTTP redirect server", verbose);
|
|
57745
57809
|
const server = http.createServer((req, res) => {
|
|
57746
57810
|
const host = req.headers.host || "";
|
|
57747
|
-
|
|
57811
|
+
debugLog("redirect", `Redirecting request from ${host}${req.url} to HTTPS`, verbose);
|
|
57748
57812
|
res.writeHead(301, {
|
|
57749
57813
|
Location: `https://${host}${req.url}`
|
|
57750
57814
|
});
|
|
57751
57815
|
res.end();
|
|
57752
57816
|
}).listen(80);
|
|
57753
57817
|
activeServers.add(server);
|
|
57754
|
-
|
|
57818
|
+
debugLog("redirect", "HTTP redirect server started", verbose);
|
|
57755
57819
|
}
|
|
57756
57820
|
function startProxy(options3) {
|
|
57757
|
-
|
|
57821
|
+
const mergedOptions = {
|
|
57822
|
+
...config4,
|
|
57823
|
+
...options3
|
|
57824
|
+
};
|
|
57825
|
+
debugLog("proxy", `Starting proxy with options: ${JSON.stringify(mergedOptions)}`, mergedOptions?.verbose);
|
|
57758
57826
|
const serverOptions = {
|
|
57759
|
-
from:
|
|
57760
|
-
to:
|
|
57761
|
-
https: httpsConfig(
|
|
57762
|
-
etcHostsCleanup:
|
|
57763
|
-
verbose:
|
|
57827
|
+
from: mergedOptions.from,
|
|
57828
|
+
to: mergedOptions.to,
|
|
57829
|
+
https: httpsConfig(mergedOptions),
|
|
57830
|
+
etcHostsCleanup: mergedOptions.etcHostsCleanup,
|
|
57831
|
+
verbose: mergedOptions.verbose
|
|
57764
57832
|
};
|
|
57765
57833
|
console.log("serverOptions", serverOptions);
|
|
57766
57834
|
startServer(serverOptions).catch((err3) => {
|
|
57767
|
-
|
|
57835
|
+
debugLog("proxy", `Failed to start proxy: ${err3}`, mergedOptions.verbose);
|
|
57768
57836
|
log.error(`Failed to start proxy: ${err3.message}`);
|
|
57769
57837
|
cleanup({
|
|
57770
|
-
domains: [
|
|
57771
|
-
etcHostsCleanup:
|
|
57772
|
-
verbose:
|
|
57838
|
+
domains: [mergedOptions.to],
|
|
57839
|
+
etcHostsCleanup: mergedOptions.etcHostsCleanup,
|
|
57840
|
+
verbose: mergedOptions.verbose
|
|
57773
57841
|
});
|
|
57774
57842
|
});
|
|
57775
57843
|
}
|
|
57776
57844
|
async function startProxies(options3) {
|
|
57777
|
-
|
|
57778
|
-
|
|
57779
|
-
|
|
57780
|
-
|
|
57781
|
-
|
|
57845
|
+
debugLog("proxies", "Starting proxy setup", options3?.verbose);
|
|
57846
|
+
const mergedOptions = {
|
|
57847
|
+
...config4,
|
|
57848
|
+
...options3
|
|
57849
|
+
};
|
|
57850
|
+
const primaryDomain = isMultiProxyConfig(mergedOptions) ? mergedOptions.proxies[0].to || "stacks.localhost" : mergedOptions.to || "stacks.localhost";
|
|
57851
|
+
if (mergedOptions.https) {
|
|
57852
|
+
const existingSSLConfig = await checkExistingCertificates(mergedOptions);
|
|
57853
|
+
if (existingSSLConfig) {
|
|
57854
|
+
debugLog("ssl", `Using existing certificates for ${primaryDomain}`, mergedOptions.verbose);
|
|
57855
|
+
mergedOptions._cachedSSLConfig = existingSSLConfig;
|
|
57856
|
+
} else {
|
|
57857
|
+
debugLog("ssl", `No valid certificates found for ${primaryDomain}, generating new ones`, mergedOptions.verbose);
|
|
57858
|
+
await generateCertificate2(mergedOptions);
|
|
57859
|
+
const sslConfig2 = await checkExistingCertificates(mergedOptions);
|
|
57860
|
+
if (!sslConfig2) {
|
|
57861
|
+
throw new Error(`Failed to load SSL certificates after generation for ${primaryDomain}. Please check file permissions and paths.`);
|
|
57862
|
+
}
|
|
57863
|
+
mergedOptions._cachedSSLConfig = sslConfig2;
|
|
57864
|
+
}
|
|
57782
57865
|
}
|
|
57783
|
-
const proxyOptions =
|
|
57866
|
+
const proxyOptions = isMultiProxyConfig(mergedOptions) ? mergedOptions.proxies.map((proxy) => ({
|
|
57784
57867
|
...proxy,
|
|
57785
|
-
https:
|
|
57786
|
-
etcHostsCleanup:
|
|
57787
|
-
verbose:
|
|
57788
|
-
_cachedSSLConfig:
|
|
57789
|
-
})) : [
|
|
57790
|
-
|
|
57791
|
-
|
|
57868
|
+
https: mergedOptions.https,
|
|
57869
|
+
etcHostsCleanup: mergedOptions.etcHostsCleanup,
|
|
57870
|
+
verbose: mergedOptions.verbose,
|
|
57871
|
+
_cachedSSLConfig: mergedOptions._cachedSSLConfig
|
|
57872
|
+
})) : [{
|
|
57873
|
+
from: mergedOptions.from || "localhost:5173",
|
|
57874
|
+
to: mergedOptions.to || "stacks.localhost",
|
|
57875
|
+
https: mergedOptions.https,
|
|
57876
|
+
etcHostsCleanup: mergedOptions.etcHostsCleanup,
|
|
57877
|
+
verbose: mergedOptions.verbose,
|
|
57878
|
+
_cachedSSLConfig: mergedOptions._cachedSSLConfig
|
|
57879
|
+
}];
|
|
57880
|
+
const domains = proxyOptions.map((opt) => opt.to || "stacks.localhost");
|
|
57881
|
+
const sslConfig = mergedOptions._cachedSSLConfig;
|
|
57792
57882
|
const cleanupHandler = () => cleanup({
|
|
57793
57883
|
domains,
|
|
57794
|
-
etcHostsCleanup:
|
|
57795
|
-
verbose:
|
|
57884
|
+
etcHostsCleanup: mergedOptions.etcHostsCleanup || false,
|
|
57885
|
+
verbose: mergedOptions.verbose || false
|
|
57796
57886
|
});
|
|
57797
|
-
|
|
57798
|
-
|
|
57799
|
-
|
|
57800
|
-
|
|
57801
|
-
|
|
57887
|
+
process9.on("SIGINT", cleanupHandler);
|
|
57888
|
+
process9.on("SIGTERM", cleanupHandler);
|
|
57889
|
+
process9.on("uncaughtException", (err3) => {
|
|
57890
|
+
debugLog("process", `Uncaught exception: ${err3}`, true);
|
|
57891
|
+
console.error("Uncaught exception:", err3);
|
|
57802
57892
|
cleanupHandler();
|
|
57803
57893
|
});
|
|
57804
57894
|
for (const option of proxyOptions) {
|
|
57805
57895
|
try {
|
|
57806
57896
|
const domain = option.to || "stacks.localhost";
|
|
57807
|
-
|
|
57897
|
+
debugLog("proxy", `Starting proxy for ${domain} with SSL config: ${!!sslConfig}`, option.verbose);
|
|
57808
57898
|
await startServer({
|
|
57809
57899
|
from: option.from || "localhost:5173",
|
|
57810
57900
|
to: domain,
|
|
@@ -57814,15 +57904,12 @@ async function startProxies(options3) {
|
|
|
57814
57904
|
_cachedSSLConfig: sslConfig
|
|
57815
57905
|
});
|
|
57816
57906
|
} catch (err3) {
|
|
57817
|
-
|
|
57818
|
-
|
|
57907
|
+
debugLog("proxies", `Failed to start proxy for ${option.to}: ${err3}`, option.verbose);
|
|
57908
|
+
console.error(`Failed to start proxy for ${option.to}:`, err3);
|
|
57819
57909
|
cleanupHandler();
|
|
57820
57910
|
}
|
|
57821
57911
|
}
|
|
57822
57912
|
}
|
|
57823
|
-
function isMultiProxyConfig2(options3) {
|
|
57824
|
-
return "proxies" in options3;
|
|
57825
|
-
}
|
|
57826
57913
|
|
|
57827
57914
|
// src/index.ts
|
|
57828
57915
|
var src_default = startProxies;
|
|
@@ -57832,17 +57919,27 @@ export {
|
|
|
57832
57919
|
startProxies,
|
|
57833
57920
|
startHttpRedirectServer,
|
|
57834
57921
|
setupReverseProxy,
|
|
57922
|
+
resolveSSLPaths,
|
|
57835
57923
|
removeHosts,
|
|
57924
|
+
loadSSLConfig,
|
|
57925
|
+
isValidRootCA,
|
|
57926
|
+
isSingleProxyOptions,
|
|
57927
|
+
isMultiProxyOptions,
|
|
57836
57928
|
isMultiProxyConfig,
|
|
57837
57929
|
httpsConfig,
|
|
57838
57930
|
hostsFilePath,
|
|
57839
57931
|
getSSLConfig,
|
|
57932
|
+
getPrimaryDomain,
|
|
57933
|
+
getAllDomains,
|
|
57934
|
+
generateWildcardPatterns,
|
|
57935
|
+
generateSSLPaths,
|
|
57840
57936
|
generateCertificate2 as generateCertificate,
|
|
57841
|
-
|
|
57937
|
+
extractHostname,
|
|
57842
57938
|
src_default as default,
|
|
57843
|
-
|
|
57844
|
-
|
|
57939
|
+
debugLog,
|
|
57940
|
+
config4 as config,
|
|
57845
57941
|
cleanup,
|
|
57846
57942
|
checkHosts,
|
|
57943
|
+
checkExistingCertificates,
|
|
57847
57944
|
addHosts
|
|
57848
57945
|
};
|