@stacksjs/buddy 0.70.156 → 0.70.159
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/commands/dev.d.ts +12 -0
- package/dist/commands/dev.js +89 -145
- package/dist/commands/setup.js +3 -2
- package/dist/version-info.d.ts +5 -1
- package/dist/version-info.js +1 -1
- package/package.json +42 -42
package/dist/commands/dev.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import type { CLI, DevOptions } from '@stacksjs/types';
|
|
2
2
|
export declare function dispatchInteractiveDevSelection(selection: string, runners: InteractiveDevRunners): Promise<boolean>;
|
|
3
3
|
export declare function resolvePrettyDevDomain(appUrl: string | undefined, nativeMode?: boolean): string | null;
|
|
4
|
+
export declare function shouldUsePrettyDevUrls(input: {
|
|
5
|
+
domain: string | null
|
|
6
|
+
localhostOnly: boolean
|
|
7
|
+
proxyManagedExternally: boolean
|
|
8
|
+
systemAuthorized: boolean
|
|
9
|
+
}): boolean;
|
|
4
10
|
export declare function dev(buddy: CLI): void;
|
|
5
11
|
export declare function startDevelopmentServer(_options: DevOptions, _startTime?: number): Promise<void>;
|
|
12
|
+
export declare function setupPrettyDevEnvironment(input: {
|
|
13
|
+
domain?: string
|
|
14
|
+
skipHosts?: boolean
|
|
15
|
+
skipTrust?: boolean
|
|
16
|
+
verbose?: boolean
|
|
17
|
+
}): Promise<boolean>;
|
|
6
18
|
export declare const interactiveDevChoices: readonly [{
|
|
7
19
|
value: 'all';
|
|
8
20
|
title: 'All'
|
package/dist/commands/dev.js
CHANGED
|
@@ -69,6 +69,19 @@ export function resolvePrettyDevDomain(appUrl, nativeMode = !1) {
|
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
export function shouldUsePrettyDevUrls(input) {
|
|
73
|
+
return input.domain !== null && !input.localhostOnly && (input.proxyManagedExternally || input.systemAuthorized);
|
|
74
|
+
}
|
|
75
|
+
async function canStartPrettyDevProxy() {
|
|
76
|
+
if (await waitForHttpsProxy(443, 150))
|
|
77
|
+
return !0;
|
|
78
|
+
try {
|
|
79
|
+
const { authorizeSystemAccess } = await importDevelopmentRpx();
|
|
80
|
+
return authorizeSystemAccess({ interactive: !1 });
|
|
81
|
+
} catch {
|
|
82
|
+
return !1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
72
85
|
export function dev(buddy) {
|
|
73
86
|
const descriptions = {
|
|
74
87
|
dev: "Start development server",
|
|
@@ -202,7 +215,12 @@ export function dev(buddy) {
|
|
|
202
215
|
onUnknownSubcommand(buddy, "dev");
|
|
203
216
|
}
|
|
204
217
|
export async function startDevelopmentServer(_options, _startTime) {
|
|
205
|
-
const options = _options, startedAt = _startTime, appUrl = process.env.APP_URL, nativeMode = options.native === !0, proxyManagedExternally = process.env.STACKS_PROXY_MANAGED === "1", frontendPort = Number(process.env.PORT) || 3000, apiPort = Number(process.env.PORT_API) || 3008, docsPort = Number(process.env.PORT_DOCS) || 3006, dashboardPort = Number(process.env.PORT_ADMIN) || 3002, includeDashboard = process.env.STACKS_DEV_DASHBOARD === "1", domain = resolvePrettyDevDomain(appUrl, nativeMode), appLooksCustom = domain !== null, localhostOnly = process.env.STACKS_DEV_LOCALHOST === "1",
|
|
218
|
+
const options = _options, startedAt = _startTime, appUrl = process.env.APP_URL ?? "stacks.localhost", nativeMode = options.native === !0, proxyManagedExternally = process.env.STACKS_PROXY_MANAGED === "1", frontendPort = Number(process.env.PORT) || 3000, apiPort = Number(process.env.PORT_API) || 3008, docsPort = Number(process.env.PORT_DOCS) || 3006, dashboardPort = Number(process.env.PORT_ADMIN) || 3002, includeDashboard = process.env.STACKS_DEV_DASHBOARD === "1", domain = resolvePrettyDevDomain(appUrl, nativeMode), appLooksCustom = domain !== null, localhostOnly = process.env.STACKS_DEV_LOCALHOST === "1", prettyUrlsRequested = appLooksCustom && !localhostOnly, systemAuthorized = !prettyUrlsRequested || proxyManagedExternally ? !0 : await canStartPrettyDevProxy(), usePrettyUrls = shouldUsePrettyDevUrls({
|
|
219
|
+
domain,
|
|
220
|
+
localhostOnly,
|
|
221
|
+
proxyManagedExternally,
|
|
222
|
+
systemAuthorized
|
|
223
|
+
}), prettySetupRequired = prettyUrlsRequested && !usePrettyUrls, hasCustomDomain = usePrettyUrls && !proxyManagedExternally, displayedDomain = usePrettyUrls ? domain : null, dashboardDomain = displayedDomain ? `dashboard.${displayedDomain}` : null, frontendUrl = displayedDomain ? `https://${displayedDomain}` : `http://localhost:${frontendPort}`, apiUrl = displayedDomain ? `https://${displayedDomain}/api` : `http://localhost:${apiPort}`, docsUrl = displayedDomain ? `https://${displayedDomain}/docs` : `http://localhost:${docsPort}`, dashboardUrl = dashboardDomain ? `https://${dashboardDomain}` : `http://localhost:${dashboardPort}`, managedPorts = [
|
|
206
224
|
frontendPort,
|
|
207
225
|
apiPort,
|
|
208
226
|
docsPort,
|
|
@@ -211,6 +229,11 @@ export async function startDevelopmentServer(_options, _startTime) {
|
|
|
211
229
|
process.env.STACKS_PROXY_MANAGED = "1";
|
|
212
230
|
process.env.STACKS_DEV_QUIET = "1";
|
|
213
231
|
console.log();
|
|
232
|
+
if (prettySetupRequired) {
|
|
233
|
+
console.log(` ${yellow("\u26A0")} ${yellow("Pretty URL setup required")} ${dim("- using localhost for this session")}`);
|
|
234
|
+
console.log(` ${dim(" ")}${dim("Run `./buddy setup:ssl` once, then restart `./buddy dev`.")}`);
|
|
235
|
+
console.log();
|
|
236
|
+
}
|
|
214
237
|
console.log(` ${bold(cyan("stacks"))} ${dim(`v${version}`)} ${dim("starting\u2026")}`);
|
|
215
238
|
console.log();
|
|
216
239
|
if (process.env.STACKS_DEV_NO_KILL !== "1")
|
|
@@ -623,104 +646,7 @@ async function waitForHttpsProxy(port, timeoutMs) {
|
|
|
623
646
|
}
|
|
624
647
|
return !1;
|
|
625
648
|
}
|
|
626
|
-
const RPX_SSL_DIR = join(homedir(), ".stacks", "ssl"), RPX_ROOT_CA_PATH = join(RPX_SSL_DIR, "rpx-root-ca.crt"), RPX_HOST_CERT_PATH = join(RPX_SSL_DIR, "rpx.localhost.crt")
|
|
627
|
-
function normalizeSha256Fingerprint(raw) {
|
|
628
|
-
return (raw.includes("=") ? raw.split("=").pop() : raw).replace(/SHA-256\s+hash:\s*/gi, "").replace(/:/g, "").trim().toUpperCase();
|
|
629
|
-
}
|
|
630
|
-
function readCertFingerprint(certPath) {
|
|
631
|
-
try {
|
|
632
|
-
const out = execSync(`openssl x509 -noout -fingerprint -sha256 -in "${certPath}"`, { encoding: "utf8" });
|
|
633
|
-
return normalizeSha256Fingerprint(out);
|
|
634
|
-
} catch {
|
|
635
|
-
return null;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
function isRpxRootCaInKeychain(caPath) {
|
|
639
|
-
const fp = readCertFingerprint(caPath);
|
|
640
|
-
if (!fp)
|
|
641
|
-
return !1;
|
|
642
|
-
const keychains = [
|
|
643
|
-
"/Library/Keychains/System.keychain",
|
|
644
|
-
LOGIN_KEYCHAIN
|
|
645
|
-
];
|
|
646
|
-
for (const keychain of keychains)
|
|
647
|
-
try {
|
|
648
|
-
const listing = execSync(`security find-certificate -a -Z "${keychain}" 2>/dev/null || true`, { encoding: "utf8" });
|
|
649
|
-
for (const line of listing.split(`
|
|
650
|
-
`))
|
|
651
|
-
if (line.toUpperCase().includes("SHA-256") && normalizeSha256Fingerprint(line) === fp)
|
|
652
|
-
return !0;
|
|
653
|
-
} catch {}
|
|
654
|
-
return !1;
|
|
655
|
-
}
|
|
656
|
-
function execSudoSh(command) {
|
|
657
|
-
const sudoPassword = process.env.SUDO_PASSWORD, escaped = command.replace(/'/g, "'\\''");
|
|
658
|
-
if (sudoPassword)
|
|
659
|
-
execSync(`echo '${sudoPassword}' | sudo -S sh -c '${escaped}' 2>/dev/null`, { stdio: ["pipe", "pipe", "pipe"] });
|
|
660
|
-
else
|
|
661
|
-
execSync(`sudo -n sh -c '${escaped}'`, { stdio: ["pipe", "pipe", "pipe"] });
|
|
662
|
-
}
|
|
663
|
-
const MACOS_CA_TRUST_FLAGS = "-d -r trustRoot -p ssl -p basic";
|
|
664
|
-
function listRpxRootCaHashesInKeychain(keychain) {
|
|
665
|
-
const listing = execSync(`security find-certificate -a -c "rpx.localhost" -Z "${keychain}" 2>/dev/null || true`, { encoding: "utf8" }), hashes = [];
|
|
666
|
-
for (const line of listing.split(`
|
|
667
|
-
`)) {
|
|
668
|
-
const match = line.match(/SHA-256 hash:\s*([A-F0-9]+)/i);
|
|
669
|
-
if (match)
|
|
670
|
-
hashes.push(match[1].toUpperCase());
|
|
671
|
-
}
|
|
672
|
-
return hashes;
|
|
673
|
-
}
|
|
674
|
-
function pruneStaleRpxRootCas(caPath) {
|
|
675
|
-
if (process.platform !== "darwin")
|
|
676
|
-
return;
|
|
677
|
-
const keep = readCertFingerprint(caPath);
|
|
678
|
-
if (!keep)
|
|
679
|
-
return;
|
|
680
|
-
for (const keychain of ["/Library/Keychains/System.keychain", LOGIN_KEYCHAIN])
|
|
681
|
-
for (const hash of listRpxRootCaHashesInKeychain(keychain)) {
|
|
682
|
-
if (hash === keep)
|
|
683
|
-
continue;
|
|
684
|
-
try {
|
|
685
|
-
if (keychain.startsWith("/Library"))
|
|
686
|
-
execSudoSh(`security delete-certificate -Z ${hash} "${keychain}"`);
|
|
687
|
-
else
|
|
688
|
-
execSync(`security delete-certificate -Z ${hash} "${keychain}"`, { stdio: "ignore" });
|
|
689
|
-
} catch {}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
function isRpxRootCaTrustedForSsl(caPath, serverName) {
|
|
693
|
-
if (process.platform !== "darwin")
|
|
694
|
-
return isRpxRootCaInKeychain(caPath);
|
|
695
|
-
try {
|
|
696
|
-
return execSync(`security verify-cert -c "${caPath}" -s "${serverName}" -l -L -R ssl 2>&1`, { encoding: "utf8" }).includes("successful");
|
|
697
|
-
} catch {
|
|
698
|
-
return !1;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
function trustRpxRootCaForBrowsers(caPath, serverName) {
|
|
702
|
-
if (process.platform !== "darwin")
|
|
703
|
-
return !1;
|
|
704
|
-
pruneStaleRpxRootCas(caPath);
|
|
705
|
-
try {
|
|
706
|
-
execSync(`security add-trusted-cert ${MACOS_CA_TRUST_FLAGS} -k "${LOGIN_KEYCHAIN}" "${caPath}"`, { stdio: "ignore" });
|
|
707
|
-
} catch {}
|
|
708
|
-
try {
|
|
709
|
-
execSudoSh(`security add-trusted-cert ${MACOS_CA_TRUST_FLAGS} -k /Library/Keychains/System.keychain "${caPath}"`);
|
|
710
|
-
} catch {
|
|
711
|
-
return !1;
|
|
712
|
-
}
|
|
713
|
-
return isRpxRootCaTrustedForSsl(caPath, serverName) || isRpxRootCaInKeychain(caPath);
|
|
714
|
-
}
|
|
715
|
-
function isLiveHttpsChainValid(domain) {
|
|
716
|
-
if (!existsSync(RPX_ROOT_CA_PATH))
|
|
717
|
-
return !1;
|
|
718
|
-
try {
|
|
719
|
-
return execSync(`echo | openssl s_client -connect ${domain}:443 -servername ${domain} -CAfile "${RPX_ROOT_CA_PATH}" 2>/dev/null | grep "Verify return code"`, { encoding: "utf8", timeout: 4000 }).includes(": 0 (ok)");
|
|
720
|
-
} catch {
|
|
721
|
-
return !1;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
649
|
+
const RPX_SSL_DIR = join(homedir(), ".stacks", "ssl"), RPX_ROOT_CA_PATH = join(RPX_SSL_DIR, "rpx-root-ca.crt"), RPX_HOST_CERT_PATH = join(RPX_SSL_DIR, "rpx.localhost.crt");
|
|
724
650
|
function buildDevelopmentTlsHostnames(domain, includeDashboard) {
|
|
725
651
|
return [
|
|
726
652
|
domain,
|
|
@@ -728,66 +654,45 @@ function buildDevelopmentTlsHostnames(domain, includeDashboard) {
|
|
|
728
654
|
"rpx.localhost"
|
|
729
655
|
];
|
|
730
656
|
}
|
|
731
|
-
function
|
|
732
|
-
try {
|
|
733
|
-
return execSync(`openssl x509 -in "${certPath}" -noout -subject -nameopt RFC2253`, { encoding: "utf8" }).match(/CN=([^,/]+)/)?.[1]?.trim() ?? null;
|
|
734
|
-
} catch {
|
|
735
|
-
return null;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
async function buildDevelopmentTlsOptions(domain, includeDashboard, verbose) {
|
|
739
|
-
const hostnames = buildDevelopmentTlsHostnames(domain, includeDashboard);
|
|
740
|
-
try {
|
|
741
|
-
const { getRegistryDir, readAll } = await importDevelopmentRpx(), entries = await readAll(getRegistryDir(), !1);
|
|
742
|
-
for (const entry of entries) {
|
|
743
|
-
const host = entry.to?.trim();
|
|
744
|
-
if (host && !hostnames.includes(host))
|
|
745
|
-
hostnames.push(host);
|
|
746
|
-
}
|
|
747
|
-
} catch {}
|
|
748
|
-
return {
|
|
749
|
-
https: {
|
|
750
|
-
certPath: RPX_HOST_CERT_PATH,
|
|
751
|
-
keyPath: join(RPX_SSL_DIR, "rpx.localhost.key"),
|
|
752
|
-
caCertPath: join(RPX_SSL_DIR, "rpx.localhost.ca.crt"),
|
|
753
|
-
commonName: domain
|
|
754
|
-
},
|
|
755
|
-
verbose,
|
|
756
|
-
regenerateUntrustedCerts: !0,
|
|
757
|
-
proxies: hostnames.map((to) => ({ from: "localhost:1", to }))
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
async function ensureRpxDevelopmentHttps(domain, options, includeDashboard) {
|
|
657
|
+
async function ensureRpxDevelopmentHttps(domain, options, includeDashboard, trustCertificate = !0) {
|
|
761
658
|
const verbose = options.verbose ?? !1, {
|
|
659
|
+
buildRegistryTlsProxyOptions,
|
|
660
|
+
certIncludesSanHostnames,
|
|
762
661
|
checkExistingCertificates,
|
|
763
662
|
clearSslConfigCache,
|
|
764
663
|
forceTrustCertificate,
|
|
765
664
|
generateCertificate,
|
|
665
|
+
getRegistryDir,
|
|
766
666
|
isDaemonRunning,
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
667
|
+
isRootCaTrustedForSsl,
|
|
668
|
+
readAll,
|
|
669
|
+
readCertCommonName,
|
|
670
|
+
stopDaemon,
|
|
671
|
+
trustRootCaForBrowsers,
|
|
672
|
+
verifyHttpsChain
|
|
673
|
+
} = await importDevelopmentRpx(), hostnames = buildDevelopmentTlsHostnames(domain, includeDashboard), entries = await readAll(getRegistryDir(), !1).catch(() => []);
|
|
674
|
+
for (const entry of entries) {
|
|
675
|
+
const host = entry.to?.trim();
|
|
676
|
+
if (host && !hostnames.includes(host))
|
|
677
|
+
hostnames.push(host);
|
|
678
|
+
}
|
|
679
|
+
const tlsOptions = buildRegistryTlsProxyOptions(hostnames, domain, verbose), hostnameInCert = certIncludesSanHostnames(RPX_HOST_CERT_PATH, hostnames), cnMatchesApp = readCertCommonName(RPX_HOST_CERT_PATH) === domain;
|
|
775
680
|
let certRegenerated = !1;
|
|
776
681
|
if (!await checkExistingCertificates(tlsOptions) || !hostnameInCert || !cnMatchesApp) {
|
|
777
682
|
clearSslConfigCache();
|
|
778
683
|
await generateCertificate({ ...tlsOptions, forceRegenerate: !0 });
|
|
779
684
|
certRegenerated = !0;
|
|
780
685
|
}
|
|
781
|
-
let trusted =
|
|
782
|
-
if (!trusted) {
|
|
783
|
-
trusted =
|
|
686
|
+
let trusted = isRootCaTrustedForSsl(RPX_ROOT_CA_PATH, domain, { verbose });
|
|
687
|
+
if (!trusted && trustCertificate) {
|
|
688
|
+
trusted = trustRootCaForBrowsers(RPX_ROOT_CA_PATH, { serverName: domain, verbose }) || await forceTrustCertificate(RPX_ROOT_CA_PATH, { serverName: domain, verbose }) || isRootCaTrustedForSsl(RPX_ROOT_CA_PATH, domain, { verbose });
|
|
784
689
|
if (trusted)
|
|
785
690
|
console.log(` ${green("\u2713")} ${dim("HTTPS")}: ${dim("Local CA trusted \u2014 reload the browser if you still see a warning")}`);
|
|
786
691
|
else
|
|
787
692
|
console.log(` ${yellow("\u26A0")} ${yellow("HTTPS")}: ${yellow(`Local CA not trusted \u2014 run: sh ${join(RPX_SSL_DIR, "trust-rpx-cert.sh")}`)}`);
|
|
788
693
|
} else if (verbose)
|
|
789
694
|
console.log(` ${green("\u2713")} ${dim("HTTPS")}: ${dim("Local certificate trusted for SSL")}`);
|
|
790
|
-
const chainOk =
|
|
695
|
+
const chainOk = existsSync(RPX_ROOT_CA_PATH) ? await verifyHttpsChain(domain, RPX_ROOT_CA_PATH) : !1;
|
|
791
696
|
if ((certRegenerated || !hostnameInCert || !cnMatchesApp) && await isDaemonRunning()) {
|
|
792
697
|
await stopDaemon({ timeoutMs: 8000 }).catch(() => {});
|
|
793
698
|
if (verbose)
|
|
@@ -867,23 +772,62 @@ async function removeStalePublicDomainOverrides(domain, includeDashboard, verbos
|
|
|
867
772
|
}
|
|
868
773
|
}
|
|
869
774
|
async function prepareRpxTlsForDev(input) {
|
|
870
|
-
const { domain, includeDashboard, options } = input, verbose = options.verbose ?? !1, hosts = [
|
|
775
|
+
const { domain, includeDashboard, options, skipHosts = !1, trustCertificate = !0 } = input, verbose = options.verbose ?? !1, hosts = [
|
|
871
776
|
domain,
|
|
872
777
|
...includeDashboard ? [`dashboard.${domain}`] : []
|
|
873
778
|
], hostsNeedingFile = hosts.filter((host) => {
|
|
874
779
|
const h = host.trim().toLowerCase();
|
|
875
780
|
return h !== "localhost" && !h.endsWith(".localhost") && !h.endsWith(".localhost.");
|
|
876
|
-
}), { addHosts, setupDevelopmentDns } = await importDevelopmentRpx(), dnsDomains = hostsNeedingFile.length > 0 ? hosts : [];
|
|
781
|
+
}), { addHosts, setupDevelopmentDns } = await importDevelopmentRpx(), dnsDomains = !skipHosts && hostsNeedingFile.length > 0 ? hosts : [];
|
|
877
782
|
if (dnsDomains.length > 0) {
|
|
878
783
|
if (!await setupDevelopmentDns({ domains: dnsDomains, verbose }).catch(() => !1) && verbose)
|
|
879
784
|
log.warn(`Dev DNS not configured for ${dnsDomains.join(", ")} \u2014 falling back to /etc/hosts`);
|
|
880
785
|
}
|
|
881
|
-
if (hostsNeedingFile.length > 0)
|
|
786
|
+
if (!skipHosts && hostsNeedingFile.length > 0)
|
|
882
787
|
await addHosts(hostsNeedingFile, verbose).catch((err) => {
|
|
883
788
|
log.warn(`Could not update /etc/hosts for ${hostsNeedingFile.join(", ")}: ${err.message}`);
|
|
884
789
|
log.warn("Add 127.0.0.1 entries manually or set SUDO_PASSWORD in .env");
|
|
885
790
|
});
|
|
886
|
-
await ensureRpxDevelopmentHttps(domain, options, includeDashboard);
|
|
791
|
+
await ensureRpxDevelopmentHttps(domain, options, includeDashboard, trustCertificate);
|
|
792
|
+
}
|
|
793
|
+
export async function setupPrettyDevEnvironment(input) {
|
|
794
|
+
const domain = resolvePrettyDevDomain(input.domain ?? process.env.APP_URL ?? "stacks.localhost");
|
|
795
|
+
if (!domain) {
|
|
796
|
+
log.info("APP_URL already uses localhost; no pretty URL setup is needed");
|
|
797
|
+
return !0;
|
|
798
|
+
}
|
|
799
|
+
const rpx = await importDevelopmentRpx();
|
|
800
|
+
if (!rpx.authorizeSystemAccess({ interactive: process.stdin.isTTY === !0 && process.stdout.isTTY === !0 })) {
|
|
801
|
+
log.error("Pretty URL setup needs administrator authorization to bind ports 80 and 443 and trust the local CA");
|
|
802
|
+
return !1;
|
|
803
|
+
}
|
|
804
|
+
await prepareRpxTlsForDev({
|
|
805
|
+
domain,
|
|
806
|
+
includeDashboard: process.env.STACKS_DEV_DASHBOARD === "1",
|
|
807
|
+
options: { verbose: input.verbose },
|
|
808
|
+
skipHosts: input.skipHosts,
|
|
809
|
+
trustCertificate: !input.skipTrust
|
|
810
|
+
});
|
|
811
|
+
const spawnEnv = {};
|
|
812
|
+
if (process.env.SUDO_PASSWORD)
|
|
813
|
+
spawnEnv.SUDO_PASSWORD = process.env.SUDO_PASSWORD;
|
|
814
|
+
if (input.verbose)
|
|
815
|
+
spawnEnv.RPX_VERBOSE = "1";
|
|
816
|
+
const rpxEntry = resolveRpxEntryPath();
|
|
817
|
+
if (rpxEntry)
|
|
818
|
+
spawnEnv.RPX_MODULE = rpxEntry;
|
|
819
|
+
await startRpxDaemonIfNeeded({
|
|
820
|
+
spawnCommand: await resolveRpxDaemonSpawnCommand(),
|
|
821
|
+
spawnEnv,
|
|
822
|
+
verbose: input.verbose ?? !1,
|
|
823
|
+
stopRpx: rpx.stopDaemon
|
|
824
|
+
});
|
|
825
|
+
const ready = await waitForHttpsProxy(443, 5000);
|
|
826
|
+
if (ready)
|
|
827
|
+
log.success(`Pretty URLs are ready at https://${domain}`);
|
|
828
|
+
else
|
|
829
|
+
log.error("rpx did not become reachable on port 443");
|
|
830
|
+
return ready;
|
|
887
831
|
}
|
|
888
832
|
async function startRpxDaemonIfNeeded(input) {
|
|
889
833
|
const { ensureDaemonRunning, isDaemonRunning: isRpxUp } = await importDevelopmentRpx();
|
package/dist/commands/setup.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import { runAction
|
|
4
|
+
import { runAction } from "@stacksjs/actions";
|
|
5
5
|
import { log, onUnknownSubcommand, runCommand } from "@stacksjs/cli";
|
|
6
6
|
import { Action } from "@stacksjs/enums";
|
|
7
7
|
import { handleError } from "@stacksjs/error-handling";
|
|
8
8
|
import { path as p } from "@stacksjs/path";
|
|
9
9
|
import { copyFile, storage } from "@stacksjs/storage";
|
|
10
10
|
import { ExitCode } from "@stacksjs/types";
|
|
11
|
+
import { setupPrettyDevEnvironment } from "./dev";
|
|
11
12
|
function getTimeoutMs(envVar, fallbackMs) {
|
|
12
13
|
const value = Number(process.env[envVar]);
|
|
13
14
|
if (Number.isFinite(value) && value > 0)
|
|
@@ -37,7 +38,7 @@ export function setup(buddy) {
|
|
|
37
38
|
});
|
|
38
39
|
buddy.command("setup:ssl", descriptions.ssl).alias("ssl:setup").option("-d, --domain [domain]", descriptions.domain).option("--skip-hosts", descriptions.skipHosts, { default: !1 }).option("--skip-trust", descriptions.skipTrust, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
39
40
|
log.debug("Running `buddy setup:ssl` ...", options);
|
|
40
|
-
if (!await
|
|
41
|
+
if (!await setupPrettyDevEnvironment({
|
|
41
42
|
domain: options.domain,
|
|
42
43
|
skipHosts: options.skipHosts,
|
|
43
44
|
skipTrust: options.skipTrust,
|
package/dist/version-info.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { version as buddyVersion } from '../package.json';
|
|
2
|
-
|
|
2
|
+
// Every published Stacks framework package shares the release version. Buddy's
|
|
3
|
+
// own package metadata is therefore the portable source of truth for both
|
|
4
|
+
// labels. Reading the monorepo parent's package.json works from src/ but escapes
|
|
5
|
+
// the package after compilation to dist/ and breaks clean npm installs.
|
|
6
|
+
declare const stacksVersion: unknown;
|
|
3
7
|
export declare const versionDescriptor: string;
|
|
4
8
|
export declare const versionLine: string;
|
|
5
9
|
export { buddyVersion, stacksVersion };
|
package/dist/version-info.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { version as stacksVersion } from "../../package.json";
|
|
2
1
|
import { version as buddyVersion } from "../package.json";
|
|
2
|
+
const stacksVersion = buddyVersion;
|
|
3
3
|
|
|
4
4
|
export { buddyVersion, stacksVersion };
|
|
5
5
|
export const versionDescriptor = `${buddyVersion} stacks/${stacksVersion}`, versionLine = `buddy/${versionDescriptor}`;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/buddy",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
5
|
+
"version": "0.70.159",
|
|
6
6
|
"description": "Meet Buddy. The Stacks runtime.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -92,51 +92,51 @@
|
|
|
92
92
|
"prepublishOnly": "bun run build"
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
|
-
"@stacksjs/actions": "^0.70.
|
|
96
|
-
"@stacksjs/ai": "^0.70.
|
|
97
|
-
"@stacksjs/alias": "^0.70.
|
|
98
|
-
"@stacksjs/arrays": "^0.70.
|
|
99
|
-
"@stacksjs/auth": "^0.70.
|
|
100
|
-
"@stacksjs/build": "^0.70.
|
|
101
|
-
"@stacksjs/cache": "^0.70.
|
|
102
|
-
"@stacksjs/cli": "^0.70.
|
|
95
|
+
"@stacksjs/actions": "^0.70.159",
|
|
96
|
+
"@stacksjs/ai": "^0.70.159",
|
|
97
|
+
"@stacksjs/alias": "^0.70.159",
|
|
98
|
+
"@stacksjs/arrays": "^0.70.159",
|
|
99
|
+
"@stacksjs/auth": "^0.70.159",
|
|
100
|
+
"@stacksjs/build": "^0.70.159",
|
|
101
|
+
"@stacksjs/cache": "^0.70.159",
|
|
102
|
+
"@stacksjs/cli": "^0.70.159",
|
|
103
103
|
"@stacksjs/clapp": "^0.2.12",
|
|
104
|
-
"@stacksjs/cloud": "^0.70.
|
|
105
|
-
"@stacksjs/collections": "^0.70.
|
|
106
|
-
"@stacksjs/config": "^0.70.
|
|
107
|
-
"@stacksjs/database": "^0.70.
|
|
108
|
-
"@stacksjs/desktop": "^0.70.
|
|
109
|
-
"@stacksjs/dns": "^0.70.
|
|
110
|
-
"@stacksjs/email": "^0.70.
|
|
111
|
-
"@stacksjs/enums": "^0.70.
|
|
112
|
-
"@stacksjs/error-handling": "^0.70.
|
|
113
|
-
"@stacksjs/events": "^0.70.
|
|
114
|
-
"@stacksjs/git": "^0.70.
|
|
104
|
+
"@stacksjs/cloud": "^0.70.159",
|
|
105
|
+
"@stacksjs/collections": "^0.70.159",
|
|
106
|
+
"@stacksjs/config": "^0.70.159",
|
|
107
|
+
"@stacksjs/database": "^0.70.159",
|
|
108
|
+
"@stacksjs/desktop": "^0.70.159",
|
|
109
|
+
"@stacksjs/dns": "^0.70.159",
|
|
110
|
+
"@stacksjs/email": "^0.70.159",
|
|
111
|
+
"@stacksjs/enums": "^0.70.159",
|
|
112
|
+
"@stacksjs/error-handling": "^0.70.159",
|
|
113
|
+
"@stacksjs/events": "^0.70.159",
|
|
114
|
+
"@stacksjs/git": "^0.70.159",
|
|
115
115
|
"@stacksjs/gitit": "^0.2.5",
|
|
116
|
-
"@stacksjs/health": "^0.70.
|
|
116
|
+
"@stacksjs/health": "^0.70.159",
|
|
117
117
|
"@stacksjs/dnsx": "^0.2.3",
|
|
118
118
|
"@stacksjs/httx": "^0.1.10",
|
|
119
|
-
"@stacksjs/lint": "^0.70.
|
|
120
|
-
"@stacksjs/logging": "^0.70.
|
|
121
|
-
"@stacksjs/notifications": "^0.70.
|
|
122
|
-
"@stacksjs/objects": "^0.70.
|
|
123
|
-
"@stacksjs/orm": "^0.70.
|
|
124
|
-
"@stacksjs/path": "^0.70.
|
|
125
|
-
"@stacksjs/payments": "^0.70.
|
|
126
|
-
"@stacksjs/realtime": "^0.70.
|
|
127
|
-
"@stacksjs/router": "^0.70.
|
|
128
|
-
"@stacksjs/rpx": "^0.11.
|
|
129
|
-
"@stacksjs/search-engine": "^0.70.
|
|
130
|
-
"@stacksjs/security": "^0.70.
|
|
131
|
-
"@stacksjs/server": "^0.70.
|
|
132
|
-
"@stacksjs/storage": "^0.70.
|
|
133
|
-
"@stacksjs/strings": "^0.70.
|
|
134
|
-
"@stacksjs/testing": "^0.70.
|
|
135
|
-
"@stacksjs/tunnel": "^0.70.
|
|
136
|
-
"@stacksjs/types": "^0.70.
|
|
137
|
-
"@stacksjs/ui": "^0.70.
|
|
138
|
-
"@stacksjs/utils": "^0.70.
|
|
139
|
-
"@stacksjs/validation": "^0.70.
|
|
119
|
+
"@stacksjs/lint": "^0.70.159",
|
|
120
|
+
"@stacksjs/logging": "^0.70.159",
|
|
121
|
+
"@stacksjs/notifications": "^0.70.159",
|
|
122
|
+
"@stacksjs/objects": "^0.70.159",
|
|
123
|
+
"@stacksjs/orm": "^0.70.159",
|
|
124
|
+
"@stacksjs/path": "^0.70.159",
|
|
125
|
+
"@stacksjs/payments": "^0.70.159",
|
|
126
|
+
"@stacksjs/realtime": "^0.70.159",
|
|
127
|
+
"@stacksjs/router": "^0.70.159",
|
|
128
|
+
"@stacksjs/rpx": "^0.11.31",
|
|
129
|
+
"@stacksjs/search-engine": "^0.70.159",
|
|
130
|
+
"@stacksjs/security": "^0.70.159",
|
|
131
|
+
"@stacksjs/server": "^0.70.159",
|
|
132
|
+
"@stacksjs/storage": "^0.70.159",
|
|
133
|
+
"@stacksjs/strings": "^0.70.159",
|
|
134
|
+
"@stacksjs/testing": "^0.70.159",
|
|
135
|
+
"@stacksjs/tunnel": "^0.70.159",
|
|
136
|
+
"@stacksjs/types": "^0.70.159",
|
|
137
|
+
"@stacksjs/ui": "^0.70.159",
|
|
138
|
+
"@stacksjs/utils": "^0.70.159",
|
|
139
|
+
"@stacksjs/validation": "^0.70.159",
|
|
140
140
|
"@stacksjs/ts-cloud": "^0.7.47"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|