@stacksjs/buddy 0.70.156 → 0.70.157

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.
@@ -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'
@@ -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", usePrettyUrls = appLooksCustom && !localhostOnly, 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 = [
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"), LOGIN_KEYCHAIN = join(homedir(), "Library/Keychains/login.keychain-db");
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 readCertCommonName(certPath) {
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
- stopDaemon
768
- } = await importDevelopmentRpx(), hostnames = buildDevelopmentTlsHostnames(domain, includeDashboard), tlsOptions = await buildDevelopmentTlsOptions(domain, includeDashboard, verbose), hostnameInCert = hostnames.every((host) => {
769
- try {
770
- return execSync(`openssl x509 -in "${RPX_HOST_CERT_PATH}" -noout -text`, { encoding: "utf8" }).includes(`DNS:${host}`);
771
- } catch {
772
- return !1;
773
- }
774
- }), cnMatchesApp = readCertCommonName(RPX_HOST_CERT_PATH) === domain;
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 = isRpxRootCaTrustedForSsl(RPX_ROOT_CA_PATH, domain);
782
- if (!trusted) {
783
- trusted = trustRpxRootCaForBrowsers(RPX_ROOT_CA_PATH, domain) || await forceTrustCertificate(RPX_ROOT_CA_PATH, { serverName: domain, verbose }) || isRpxRootCaTrustedForSsl(RPX_ROOT_CA_PATH, domain);
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 = isLiveHttpsChainValid(domain);
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();
@@ -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, setupSSL } from "@stacksjs/actions";
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 setupSSL({
41
+ if (!await setupPrettyDevEnvironment({
41
42
  domain: options.domain,
42
43
  skipHosts: options.skipHosts,
43
44
  skipTrust: options.skipTrust,
@@ -1,5 +1,9 @@
1
1
  import { version as buddyVersion } from '../package.json';
2
- import { version as stacksVersion } from '../../package.json';
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 };
@@ -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.156",
5
+ "version": "0.70.157",
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.156",
96
- "@stacksjs/ai": "^0.70.156",
97
- "@stacksjs/alias": "^0.70.156",
98
- "@stacksjs/arrays": "^0.70.156",
99
- "@stacksjs/auth": "^0.70.156",
100
- "@stacksjs/build": "^0.70.156",
101
- "@stacksjs/cache": "^0.70.156",
102
- "@stacksjs/cli": "^0.70.156",
95
+ "@stacksjs/actions": "^0.70.157",
96
+ "@stacksjs/ai": "^0.70.157",
97
+ "@stacksjs/alias": "^0.70.157",
98
+ "@stacksjs/arrays": "^0.70.157",
99
+ "@stacksjs/auth": "^0.70.157",
100
+ "@stacksjs/build": "^0.70.157",
101
+ "@stacksjs/cache": "^0.70.157",
102
+ "@stacksjs/cli": "^0.70.157",
103
103
  "@stacksjs/clapp": "^0.2.12",
104
- "@stacksjs/cloud": "^0.70.156",
105
- "@stacksjs/collections": "^0.70.156",
106
- "@stacksjs/config": "^0.70.156",
107
- "@stacksjs/database": "^0.70.156",
108
- "@stacksjs/desktop": "^0.70.156",
109
- "@stacksjs/dns": "^0.70.156",
110
- "@stacksjs/email": "^0.70.156",
111
- "@stacksjs/enums": "^0.70.156",
112
- "@stacksjs/error-handling": "^0.70.156",
113
- "@stacksjs/events": "^0.70.156",
114
- "@stacksjs/git": "^0.70.156",
104
+ "@stacksjs/cloud": "^0.70.157",
105
+ "@stacksjs/collections": "^0.70.157",
106
+ "@stacksjs/config": "^0.70.157",
107
+ "@stacksjs/database": "^0.70.157",
108
+ "@stacksjs/desktop": "^0.70.157",
109
+ "@stacksjs/dns": "^0.70.157",
110
+ "@stacksjs/email": "^0.70.157",
111
+ "@stacksjs/enums": "^0.70.157",
112
+ "@stacksjs/error-handling": "^0.70.157",
113
+ "@stacksjs/events": "^0.70.157",
114
+ "@stacksjs/git": "^0.70.157",
115
115
  "@stacksjs/gitit": "^0.2.5",
116
- "@stacksjs/health": "^0.70.156",
116
+ "@stacksjs/health": "^0.70.157",
117
117
  "@stacksjs/dnsx": "^0.2.3",
118
118
  "@stacksjs/httx": "^0.1.10",
119
- "@stacksjs/lint": "^0.70.156",
120
- "@stacksjs/logging": "^0.70.156",
121
- "@stacksjs/notifications": "^0.70.156",
122
- "@stacksjs/objects": "^0.70.156",
123
- "@stacksjs/orm": "^0.70.156",
124
- "@stacksjs/path": "^0.70.156",
125
- "@stacksjs/payments": "^0.70.156",
126
- "@stacksjs/realtime": "^0.70.156",
127
- "@stacksjs/router": "^0.70.156",
128
- "@stacksjs/rpx": "^0.11.29",
129
- "@stacksjs/search-engine": "^0.70.156",
130
- "@stacksjs/security": "^0.70.156",
131
- "@stacksjs/server": "^0.70.156",
132
- "@stacksjs/storage": "^0.70.156",
133
- "@stacksjs/strings": "^0.70.156",
134
- "@stacksjs/testing": "^0.70.156",
135
- "@stacksjs/tunnel": "^0.70.156",
136
- "@stacksjs/types": "^0.70.156",
137
- "@stacksjs/ui": "^0.70.156",
138
- "@stacksjs/utils": "^0.70.156",
139
- "@stacksjs/validation": "^0.70.156",
119
+ "@stacksjs/lint": "^0.70.157",
120
+ "@stacksjs/logging": "^0.70.157",
121
+ "@stacksjs/notifications": "^0.70.157",
122
+ "@stacksjs/objects": "^0.70.157",
123
+ "@stacksjs/orm": "^0.70.157",
124
+ "@stacksjs/path": "^0.70.157",
125
+ "@stacksjs/payments": "^0.70.157",
126
+ "@stacksjs/realtime": "^0.70.157",
127
+ "@stacksjs/router": "^0.70.157",
128
+ "@stacksjs/rpx": "^0.11.31",
129
+ "@stacksjs/search-engine": "^0.70.157",
130
+ "@stacksjs/security": "^0.70.157",
131
+ "@stacksjs/server": "^0.70.157",
132
+ "@stacksjs/storage": "^0.70.157",
133
+ "@stacksjs/strings": "^0.70.157",
134
+ "@stacksjs/testing": "^0.70.157",
135
+ "@stacksjs/tunnel": "^0.70.157",
136
+ "@stacksjs/types": "^0.70.157",
137
+ "@stacksjs/ui": "^0.70.157",
138
+ "@stacksjs/utils": "^0.70.157",
139
+ "@stacksjs/validation": "^0.70.157",
140
140
  "@stacksjs/ts-cloud": "^0.7.47"
141
141
  },
142
142
  "devDependencies": {