@saptools/cf-debugger 0.1.3 → 0.1.5

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 CHANGED
@@ -1,17 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import process4 from "process";
4
+ import process6 from "process";
5
5
  import { Command } from "commander";
6
6
 
7
- // src/debugger.ts
7
+ // src/debug-session/start.ts
8
8
  import { mkdir as mkdir3, rm } from "fs/promises";
9
- import { hostname as getHostname2 } from "os";
10
- import process3 from "process";
11
-
12
- // src/cf.ts
13
- import { execFile, spawn } from "child_process";
14
- import { promisify } from "util";
9
+ import process4 from "process";
15
10
 
16
11
  // src/types.ts
17
12
  var CfDebuggerError = class extends Error {
@@ -27,13 +22,12 @@ var CfDebuggerError = class extends Error {
27
22
  }
28
23
  };
29
24
 
30
- // src/cf.ts
25
+ // src/cloud-foundry/execute.ts
26
+ import { execFile } from "child_process";
27
+ import { promisify } from "util";
31
28
  var execFileAsync = promisify(execFile);
32
29
  var MAX_BUFFER = 16 * 1024 * 1024;
33
30
  var CF_CLI_TIMEOUT_MS = 3e4;
34
- var CF_RESTART_TIMEOUT_MS = 12e4;
35
- var CF_SSH_SIGNAL_TIMEOUT_MS = 15e3;
36
- var CF_AUTH_MAX_ATTEMPTS = 3;
37
31
  function buildEnv(cfHome) {
38
32
  return { ...process.env, CF_HOME: cfHome };
39
33
  }
@@ -58,6 +52,10 @@ async function runCf(args, context, timeoutMs = CF_CLI_TIMEOUT_MS) {
58
52
  );
59
53
  }
60
54
  }
55
+
56
+ // src/cloud-foundry/commands.ts
57
+ var CF_RESTART_TIMEOUT_MS = 12e4;
58
+ var CF_AUTH_MAX_ATTEMPTS = 3;
61
59
  async function cfApi(apiEndpoint, context) {
62
60
  await runCf(["api", apiEndpoint], context);
63
61
  }
@@ -123,6 +121,10 @@ async function cfEnableSsh(appName, context) {
123
121
  async function cfRestartApp(appName, context) {
124
122
  await runCf(["restart", appName], context, CF_RESTART_TIMEOUT_MS);
125
123
  }
124
+
125
+ // src/cloud-foundry/ssh.ts
126
+ import { spawn } from "child_process";
127
+ var CF_SSH_SIGNAL_TIMEOUT_MS = 15e3;
126
128
  async function cfSshOneShot(appName, command, context) {
127
129
  return await new Promise((resolve) => {
128
130
  const child = spawn(resolveBin(context), ["ssh", appName, "-c", command], {
@@ -197,7 +199,7 @@ function sessionCfHomeDir(sessionId) {
197
199
  return join(saptoolsDir(), CF_DEBUGGER_HOMES_DIRNAME, sessionId);
198
200
  }
199
201
 
200
- // src/port.ts
202
+ // src/network/ports.ts
201
203
  import { execFile as execFile2 } from "child_process";
202
204
  import { createConnection, createServer } from "net";
203
205
  import { promisify as promisify2 } from "util";
@@ -366,7 +368,7 @@ function resolveApiEndpoint(regionKey, override) {
366
368
  return endpoint;
367
369
  }
368
370
 
369
- // src/state.ts
371
+ // src/session-state/store.ts
370
372
  import { randomUUID } from "crypto";
371
373
  import { mkdir as mkdir2, readFile, rename, writeFile } from "fs/promises";
372
374
  import { hostname as getHostname } from "os";
@@ -421,7 +423,7 @@ async function withFileLock(lockPath, work, options) {
421
423
  }
422
424
  }
423
425
 
424
- // src/state.ts
426
+ // src/session-state/store.ts
425
427
  async function readJsonFile(path) {
426
428
  let raw;
427
429
  try {
@@ -653,13 +655,29 @@ async function removeSession(sessionId) {
653
655
  });
654
656
  }
655
657
 
656
- // src/debugger.ts
658
+ // src/debug-session/constants.ts
657
659
  var DEFAULT_TUNNEL_READY_TIMEOUT_MS = 3e4;
658
660
  var POST_USR1_DELAY_MS = 300;
659
661
  var PORT_CLEANUP_DELAY_MS = 600;
660
662
  var CHILD_SIGTERM_GRACE_MS = 2e3;
661
663
  var PORT_RECLAIM_DELAY_MS = 250;
662
664
  var PID_TERMINATION_POLL_MS = 100;
665
+
666
+ // src/debug-session/orphans.ts
667
+ import { hostname as getHostname2 } from "os";
668
+ async function pruneAndCleanupOrphans() {
669
+ const result = await readAndPruneActiveSessions();
670
+ const host = getHostname2();
671
+ for (const removed of result.removed) {
672
+ if (removed.hostname === host) {
673
+ void killProcessOnPort(removed.localPort);
674
+ }
675
+ }
676
+ return result.sessions;
677
+ }
678
+
679
+ // src/debug-session/processes.ts
680
+ import process3 from "process";
663
681
  function signalPidOrGroup(pid, signal) {
664
682
  const isWindows = process3.platform === "win32";
665
683
  if (!isWindows) {
@@ -699,24 +717,16 @@ async function killProcessGroupOrProc(child, timeoutMs = CHILD_SIGTERM_GRACE_MS)
699
717
  }
700
718
  await terminatePidOrGroup(child.pid, timeoutMs);
701
719
  }
702
- async function pruneAndCleanupOrphans() {
703
- const result = await readAndPruneActiveSessions();
704
- const host = getHostname2();
705
- for (const removed of result.removed) {
706
- if (removed.hostname === host) {
707
- void killProcessOnPort(removed.localPort);
708
- }
709
- }
710
- return result.sessions;
711
- }
720
+
721
+ // src/debug-session/start.ts
712
722
  function checkAbort(signal) {
713
723
  if (signal?.aborted) {
714
724
  throw new CfDebuggerError("ABORTED", "Operation aborted by caller");
715
725
  }
716
726
  }
717
727
  function requireCredentials(options) {
718
- const email = options.email ?? process3.env["SAP_EMAIL"];
719
- const password = options.password ?? process3.env["SAP_PASSWORD"];
728
+ const email = options.email ?? process4.env["SAP_EMAIL"];
729
+ const password = options.password ?? process4.env["SAP_PASSWORD"];
720
730
  if (email === void 0 || email === "") {
721
731
  throw new CfDebuggerError(
722
732
  "MISSING_CREDENTIALS",
@@ -731,15 +741,7 @@ function requireCredentials(options) {
731
741
  }
732
742
  return { email, password };
733
743
  }
734
- async function startDebugger(options) {
735
- const { email, password } = requireCredentials(options);
736
- const apiEndpoint = resolveApiEndpoint(options.region, options.apiEndpoint);
737
- const tunnelReadyTimeoutMs = options.tunnelReadyTimeoutMs ?? DEFAULT_TUNNEL_READY_TIMEOUT_MS;
738
- const emit = (status, message) => {
739
- options.onStatus?.(status, message);
740
- };
741
- checkAbort(options.signal);
742
- await pruneAndCleanupOrphans();
744
+ async function registerSession(options, apiEndpoint) {
743
745
  const registration = await registerNewSession({
744
746
  region: options.region,
745
747
  org: options.org,
@@ -756,20 +758,151 @@ async function startDebugger(options) {
756
758
  `A debugger session is already running for ${sessionKeyString(options)} on port ${registration.existing.localPort.toString()} (pid ${registration.existing.pid.toString()}, sessionId ${registration.existing.sessionId}). Stop it first with \`cf-debugger stop\`.`
757
759
  );
758
760
  }
759
- const session = registration.session;
761
+ return registration.session;
762
+ }
763
+ async function loginAndTarget(options, apiEndpoint, email, password, context, sessionId, emit) {
764
+ emit("logging-in");
765
+ await updateSessionStatus(sessionId, "logging-in");
766
+ await cfLogin(apiEndpoint, email, password, context);
767
+ checkAbort(options.signal);
768
+ emit("targeting");
769
+ await updateSessionStatus(sessionId, "targeting");
770
+ await cfTarget(options.org, options.space, context);
771
+ checkAbort(options.signal);
772
+ }
773
+ async function signalRemoteNode(options, context, sessionId, emit) {
774
+ emit("signaling");
775
+ await updateSessionStatus(sessionId, "signaling");
776
+ const signalResult = await cfSshOneShot(options.app, `kill -s USR1 $(pidof node)`, context);
777
+ if (!isSshDisabledError(signalResult.stderr)) {
778
+ if (signalResult.exitCode === 0) {
779
+ return;
780
+ }
781
+ const detail = signalResult.stderr.trim().length > 0 ? signalResult.stderr.trim() : `exit code ${String(signalResult.exitCode)}`;
782
+ throw new CfDebuggerError(
783
+ "USR1_SIGNAL_FAILED",
784
+ `Failed to send SIGUSR1 to the Node.js process on ${options.app}: ${detail}`,
785
+ signalResult.stderr
786
+ );
787
+ }
788
+ const alreadyEnabled = await cfSshEnabled(options.app, context);
789
+ if (!alreadyEnabled) {
790
+ emit("ssh-enabling", "Enabling SSH on the app");
791
+ await updateSessionStatus(sessionId, "ssh-enabling");
792
+ await cfEnableSsh(options.app, context);
793
+ }
794
+ emit("ssh-restarting", "Restarting app so SSH becomes active");
795
+ await updateSessionStatus(sessionId, "ssh-restarting");
796
+ await cfRestartApp(options.app, context);
797
+ checkAbort(options.signal);
798
+ await retryRemoteSignal(options, context, sessionId, emit);
799
+ }
800
+ async function retryRemoteSignal(options, context, sessionId, emit) {
801
+ emit("signaling");
802
+ await updateSessionStatus(sessionId, "signaling");
803
+ const retrySignalResult = await cfSshOneShot(
804
+ options.app,
805
+ `kill -s USR1 $(pidof node)`,
806
+ context
807
+ );
808
+ if (retrySignalResult.exitCode === 0) {
809
+ return;
810
+ }
811
+ const detail = retrySignalResult.stderr.trim().length > 0 ? retrySignalResult.stderr.trim() : `exit code ${String(retrySignalResult.exitCode)}`;
812
+ throw new CfDebuggerError(
813
+ "USR1_SIGNAL_FAILED",
814
+ `Failed to send SIGUSR1 to the Node.js process on ${options.app} after enabling SSH: ${detail}`,
815
+ retrySignalResult.stderr
816
+ );
817
+ }
818
+ async function waitAfterSignal(signal) {
819
+ await new Promise((resolve) => {
820
+ setTimeout(resolve, POST_USR1_DELAY_MS);
821
+ });
822
+ checkAbort(signal);
823
+ }
824
+ async function ensurePortAvailable(localPort) {
825
+ if (await isPortFree(localPort)) {
826
+ return;
827
+ }
828
+ await killProcessOnPort(localPort);
829
+ await new Promise((resolve) => {
830
+ setTimeout(resolve, PORT_RECLAIM_DELAY_MS);
831
+ });
832
+ if (!await isPortFree(localPort)) {
833
+ throw new CfDebuggerError(
834
+ "PORT_UNAVAILABLE",
835
+ `Local port ${localPort.toString()} is in use and could not be reclaimed for the tunnel.`
836
+ );
837
+ }
838
+ }
839
+ async function openReadyTunnel(options, session, context, tunnelReadyTimeoutMs, onChild) {
840
+ await ensurePortAvailable(session.localPort);
841
+ const child = spawnSshTunnel(options.app, session.localPort, session.remotePort, context);
842
+ onChild(child);
843
+ if (child.pid !== void 0) {
844
+ await updateSessionPid(session.sessionId, child.pid);
845
+ }
846
+ const ready = await probeTunnelReady(session.localPort, tunnelReadyTimeoutMs);
847
+ checkAbort(options.signal);
848
+ if (!ready) {
849
+ throw new CfDebuggerError(
850
+ "TUNNEL_NOT_READY",
851
+ `SSH tunnel on port ${session.localPort.toString()} did not become ready within ${Math.round(tunnelReadyTimeoutMs / 1e3).toString()}s.`
852
+ );
853
+ }
854
+ const listeningPid = await findListeningProcessId(session.localPort);
855
+ const activePid = listeningPid ?? child.pid ?? session.pid;
856
+ if (activePid !== session.pid) {
857
+ await updateSessionPid(session.sessionId, activePid);
858
+ }
859
+ return { child, activePid };
860
+ }
861
+ function attachTunnelEvents(child, markClosed, resolveExit, emit) {
862
+ child.on("close", (code) => {
863
+ markClosed();
864
+ resolveExit(code);
865
+ });
866
+ child.on("error", (err) => {
867
+ emit("error", err.message);
868
+ });
869
+ }
870
+ function createHandle(session, emit, finalize, exitPromise) {
871
+ let disposePromise;
872
+ return {
873
+ session,
874
+ dispose: async () => {
875
+ disposePromise ??= (async () => {
876
+ emit("stopping");
877
+ await updateSessionStatus(session.sessionId, "stopping");
878
+ await finalize();
879
+ })();
880
+ await disposePromise;
881
+ },
882
+ waitForExit: async () => {
883
+ return await exitPromise;
884
+ }
885
+ };
886
+ }
887
+ async function startDebugger(options) {
888
+ const { email, password } = requireCredentials(options);
889
+ const apiEndpoint = resolveApiEndpoint(options.region, options.apiEndpoint);
890
+ const tunnelReadyTimeoutMs = options.tunnelReadyTimeoutMs ?? DEFAULT_TUNNEL_READY_TIMEOUT_MS;
891
+ const emit = (status, message) => {
892
+ options.onStatus?.(status, message);
893
+ };
894
+ checkAbort(options.signal);
895
+ await pruneAndCleanupOrphans();
896
+ const session = await registerSession(options, apiEndpoint);
760
897
  const context = { cfHome: session.cfHomeDir };
761
898
  let child;
762
899
  let tunnelClosed = false;
763
- let exitResolve;
900
+ let exitResolve = (_code) => {
901
+ throw new Error("Exit resolver was used before initialization");
902
+ };
764
903
  const exitPromise = new Promise((resolve) => {
765
904
  exitResolve = resolve;
766
905
  });
767
- const cleanupFilesystem = async () => {
768
- try {
769
- await rm(session.cfHomeDir, { recursive: true, force: true });
770
- } catch {
771
- }
772
- };
773
906
  const finalize = async () => {
774
907
  if (!tunnelClosed) {
775
908
  tunnelClosed = true;
@@ -781,125 +914,36 @@ async function startDebugger(options) {
781
914
  }, PORT_CLEANUP_DELAY_MS);
782
915
  }
783
916
  await removeSession(session.sessionId);
784
- await cleanupFilesystem();
917
+ await cleanupFilesystem(session.cfHomeDir);
785
918
  emit("stopped");
786
919
  };
787
920
  try {
788
921
  await mkdir3(session.cfHomeDir, { recursive: true });
789
- emit("logging-in");
790
- await updateSessionStatus(session.sessionId, "logging-in");
791
- await cfLogin(apiEndpoint, email, password, context);
792
- checkAbort(options.signal);
793
- emit("targeting");
794
- await updateSessionStatus(session.sessionId, "targeting");
795
- await cfTarget(options.org, options.space, context);
796
- checkAbort(options.signal);
922
+ await loginAndTarget(options, apiEndpoint, email, password, context, session.sessionId, emit);
797
923
  await killProcessOnPort(session.localPort);
798
924
  await new Promise((resolve) => {
799
925
  setTimeout(resolve, 200);
800
926
  });
801
- emit("signaling");
802
- await updateSessionStatus(session.sessionId, "signaling");
803
- const signalResult = await cfSshOneShot(
804
- options.app,
805
- `kill -s USR1 $(pidof node)`,
806
- context
807
- );
808
- if (isSshDisabledError(signalResult.stderr)) {
809
- const alreadyEnabled = await cfSshEnabled(options.app, context);
810
- if (!alreadyEnabled) {
811
- emit("ssh-enabling", "Enabling SSH on the app");
812
- await updateSessionStatus(session.sessionId, "ssh-enabling");
813
- await cfEnableSsh(options.app, context);
814
- }
815
- emit("ssh-restarting", "Restarting app so SSH becomes active");
816
- await updateSessionStatus(session.sessionId, "ssh-restarting");
817
- await cfRestartApp(options.app, context);
818
- checkAbort(options.signal);
819
- emit("signaling");
820
- await updateSessionStatus(session.sessionId, "signaling");
821
- const retrySignalResult = await cfSshOneShot(
822
- options.app,
823
- `kill -s USR1 $(pidof node)`,
824
- context
825
- );
826
- if (retrySignalResult.exitCode !== 0) {
827
- const detail = retrySignalResult.stderr.trim().length > 0 ? retrySignalResult.stderr.trim() : `exit code ${String(retrySignalResult.exitCode)}`;
828
- throw new CfDebuggerError(
829
- "USR1_SIGNAL_FAILED",
830
- `Failed to send SIGUSR1 to the Node.js process on ${options.app} after enabling SSH: ${detail}`,
831
- retrySignalResult.stderr
832
- );
833
- }
834
- } else if (signalResult.exitCode !== 0) {
835
- const detail = signalResult.stderr.trim().length > 0 ? signalResult.stderr.trim() : `exit code ${String(signalResult.exitCode)}`;
836
- throw new CfDebuggerError(
837
- "USR1_SIGNAL_FAILED",
838
- `Failed to send SIGUSR1 to the Node.js process on ${options.app}: ${detail}`,
839
- signalResult.stderr
840
- );
841
- }
842
- await new Promise((resolve) => {
843
- setTimeout(resolve, POST_USR1_DELAY_MS);
844
- });
845
- checkAbort(options.signal);
927
+ await signalRemoteNode(options, context, session.sessionId, emit);
928
+ await waitAfterSignal(options.signal);
846
929
  emit("tunneling");
847
930
  await updateSessionStatus(session.sessionId, "tunneling");
848
- if (!await isPortFree(session.localPort)) {
849
- await killProcessOnPort(session.localPort);
850
- await new Promise((resolve) => {
851
- setTimeout(resolve, PORT_RECLAIM_DELAY_MS);
852
- });
853
- if (!await isPortFree(session.localPort)) {
854
- throw new CfDebuggerError(
855
- "PORT_UNAVAILABLE",
856
- `Local port ${session.localPort.toString()} is in use and could not be reclaimed for the tunnel.`
857
- );
931
+ const tunnel = await openReadyTunnel(
932
+ options,
933
+ session,
934
+ context,
935
+ tunnelReadyTimeoutMs,
936
+ (tunnelChild) => {
937
+ attachTunnelEvents(tunnelChild, () => {
938
+ tunnelClosed = true;
939
+ }, exitResolve, emit);
858
940
  }
859
- }
860
- child = spawnSshTunnel(options.app, session.localPort, session.remotePort, context);
861
- if (child.pid !== void 0) {
862
- await updateSessionPid(session.sessionId, child.pid);
863
- }
864
- child.on("close", (code) => {
865
- tunnelClosed = true;
866
- exitResolve?.(code);
867
- });
868
- child.on("error", (err) => {
869
- emit("error", err.message);
870
- });
871
- const ready = await probeTunnelReady(session.localPort, tunnelReadyTimeoutMs);
872
- checkAbort(options.signal);
873
- if (!ready) {
874
- throw new CfDebuggerError(
875
- "TUNNEL_NOT_READY",
876
- `SSH tunnel on port ${session.localPort.toString()} did not become ready within ${Math.round(tunnelReadyTimeoutMs / 1e3).toString()}s.`
877
- );
878
- }
879
- const listeningPid = await findListeningProcessId(session.localPort);
880
- const activePid = listeningPid ?? child.pid ?? session.pid;
881
- if (activePid !== session.pid) {
882
- await updateSessionPid(session.sessionId, activePid);
883
- }
941
+ );
942
+ child = tunnel.child;
884
943
  emit("ready");
885
944
  const readySession = await updateSessionStatus(session.sessionId, "ready");
886
- const activeSession = readySession ?? { ...session, pid: activePid, status: "ready" };
887
- let disposePromise;
888
- const handle = {
889
- session: activeSession,
890
- dispose: async () => {
891
- disposePromise ??= (async () => {
892
- emit("stopping");
893
- await updateSessionStatus(session.sessionId, "stopping");
894
- await finalize();
895
- })();
896
- await disposePromise;
897
- },
898
- waitForExit: async () => {
899
- return await exitPromise;
900
- }
901
- };
902
- return handle;
945
+ const activeSession = readySession ?? { ...session, pid: tunnel.activePid, status: "ready" };
946
+ return createHandle(activeSession, emit, finalize, exitPromise);
903
947
  } catch (err) {
904
948
  const message = err instanceof Error ? err.message : String(err);
905
949
  emit("error", message);
@@ -907,6 +951,16 @@ async function startDebugger(options) {
907
951
  throw err;
908
952
  }
909
953
  }
954
+ async function cleanupFilesystem(cfHomeDir) {
955
+ try {
956
+ await rm(cfHomeDir, { recursive: true, force: true });
957
+ } catch {
958
+ }
959
+ }
960
+
961
+ // src/debug-session/sessions.ts
962
+ import { rm as rm2 } from "fs/promises";
963
+ import process5 from "process";
910
964
  async function stopDebugger(options) {
911
965
  const sessions = await pruneAndCleanupOrphans();
912
966
  let target;
@@ -919,7 +973,7 @@ async function stopDebugger(options) {
919
973
  if (target === void 0) {
920
974
  return void 0;
921
975
  }
922
- if (target.pid !== process3.pid) {
976
+ if (target.pid !== process5.pid) {
923
977
  try {
924
978
  await terminatePidOrGroup(target.pid);
925
979
  } catch {
@@ -930,7 +984,7 @@ async function stopDebugger(options) {
930
984
  }, PORT_CLEANUP_DELAY_MS);
931
985
  const removed = await removeSession(target.sessionId);
932
986
  try {
933
- await rm(target.cfHomeDir, { recursive: true, force: true });
987
+ await rm2(target.cfHomeDir, { recursive: true, force: true });
934
988
  } catch {
935
989
  }
936
990
  return removed ?? target;
@@ -957,9 +1011,9 @@ async function getSession(key) {
957
1011
  // src/cli.ts
958
1012
  function readRequiredOption(value, flag) {
959
1013
  if (value === void 0 || value === "") {
960
- process4.stderr.write(`Missing required option ${flag}
1014
+ process6.stderr.write(`Missing required option ${flag}
961
1015
  `);
962
- process4.exit(1);
1016
+ process6.exit(1);
963
1017
  }
964
1018
  return value;
965
1019
  }
@@ -969,9 +1023,9 @@ function parseOptionalPort(raw) {
969
1023
  }
970
1024
  const port = Number.parseInt(raw, 10);
971
1025
  if (Number.isNaN(port) || port <= 0 || port > 65535) {
972
- process4.stderr.write(`Invalid port: ${raw}
1026
+ process6.stderr.write(`Invalid port: ${raw}
973
1027
  `);
974
- process4.exit(1);
1028
+ process6.exit(1);
975
1029
  }
976
1030
  return port;
977
1031
  }
@@ -981,16 +1035,16 @@ function parseOptionalTimeout(raw) {
981
1035
  }
982
1036
  const seconds = Number.parseInt(raw, 10);
983
1037
  if (Number.isNaN(seconds) || seconds <= 0) {
984
- process4.stderr.write(`Invalid timeout: ${raw}
1038
+ process6.stderr.write(`Invalid timeout: ${raw}
985
1039
  `);
986
- process4.exit(1);
1040
+ process6.exit(1);
987
1041
  }
988
1042
  return seconds * 1e3;
989
1043
  }
990
1044
  function logStatus(verbose, status, message) {
991
1045
  if (verbose) {
992
1046
  const suffix = message === void 0 ? "" : `: ${message}`;
993
- process4.stdout.write(`[cf-debugger] ${status}${suffix}
1047
+ process6.stdout.write(`[cf-debugger] ${status}${suffix}
994
1048
  `);
995
1049
  }
996
1050
  }
@@ -1005,17 +1059,17 @@ async function handleStart(opts) {
1005
1059
  const abortController = new AbortController();
1006
1060
  const onStartupSignal = (exitCode) => () => {
1007
1061
  abortController.abort();
1008
- process4.stderr.write(`
1062
+ process6.stderr.write(`
1009
1063
  Aborting startup for ${app}...
1010
1064
  `);
1011
1065
  setTimeout(() => {
1012
- process4.exit(exitCode);
1066
+ process6.exit(exitCode);
1013
1067
  }, 5e3).unref();
1014
1068
  };
1015
1069
  const startupSigint = onStartupSignal(130);
1016
1070
  const startupSigterm = onStartupSignal(143);
1017
- process4.on("SIGINT", startupSigint);
1018
- process4.on("SIGTERM", startupSigterm);
1071
+ process6.on("SIGINT", startupSigint);
1072
+ process6.on("SIGTERM", startupSigterm);
1019
1073
  let handle;
1020
1074
  try {
1021
1075
  handle = await startDebugger({
@@ -1032,10 +1086,10 @@ Aborting startup for ${app}...
1032
1086
  }
1033
1087
  });
1034
1088
  } finally {
1035
- process4.off("SIGINT", startupSigint);
1036
- process4.off("SIGTERM", startupSigterm);
1089
+ process6.off("SIGINT", startupSigint);
1090
+ process6.off("SIGTERM", startupSigterm);
1037
1091
  }
1038
- process4.stdout.write(
1092
+ process6.stdout.write(
1039
1093
  `Debugger ready for ${app} (${region}/${org}/${space}).
1040
1094
  Local port: ${handle.session.localPort.toString()}
1041
1095
  Remote port: ${handle.session.remotePort.toString()}
@@ -1047,32 +1101,32 @@ Press Ctrl+C to stop.
1047
1101
  let disposePromise;
1048
1102
  const dispose = async () => {
1049
1103
  disposePromise ??= (async () => {
1050
- process4.stdout.write(`
1104
+ process6.stdout.write(`
1051
1105
  Stopping debugger for ${app}...
1052
1106
  `);
1053
1107
  try {
1054
1108
  await handle.dispose();
1055
1109
  } catch (err) {
1056
1110
  const msg = err instanceof Error ? err.message : String(err);
1057
- process4.stderr.write(`Error during stop: ${msg}
1111
+ process6.stderr.write(`Error during stop: ${msg}
1058
1112
  `);
1059
1113
  }
1060
1114
  })();
1061
1115
  await disposePromise;
1062
1116
  };
1063
- process4.on("SIGINT", () => {
1117
+ process6.on("SIGINT", () => {
1064
1118
  void dispose().then(() => {
1065
- process4.exit(130);
1119
+ process6.exit(130);
1066
1120
  });
1067
1121
  });
1068
- process4.on("SIGTERM", () => {
1122
+ process6.on("SIGTERM", () => {
1069
1123
  void dispose().then(() => {
1070
- process4.exit(143);
1124
+ process6.exit(143);
1071
1125
  });
1072
1126
  });
1073
1127
  const code = await handle.waitForExit();
1074
1128
  await dispose();
1075
- process4.exit(code ?? 0);
1129
+ process6.exit(code ?? 0);
1076
1130
  }
1077
1131
  function resolveKeyFromOpts(opts) {
1078
1132
  if (opts.region !== void 0 && opts.org !== void 0 && opts.space !== void 0 && opts.app !== void 0) {
@@ -1088,7 +1142,7 @@ function resolveKeyFromOpts(opts) {
1088
1142
  async function handleStop(opts) {
1089
1143
  if (opts.all === true) {
1090
1144
  const count = await stopAllDebuggers();
1091
- process4.stdout.write(`Stopped ${count.toString()} session(s).
1145
+ process6.stdout.write(`Stopped ${count.toString()} session(s).
1092
1146
  `);
1093
1147
  return;
1094
1148
  }
@@ -1098,17 +1152,17 @@ async function handleStop(opts) {
1098
1152
  ...key === void 0 ? {} : { key }
1099
1153
  });
1100
1154
  if (result === void 0) {
1101
- process4.stderr.write("No matching session found.\n");
1102
- process4.exit(1);
1155
+ process6.stderr.write("No matching session found.\n");
1156
+ process6.exit(1);
1103
1157
  }
1104
- process4.stdout.write(
1158
+ process6.stdout.write(
1105
1159
  `Stopped session ${result.sessionId} (${result.app}, port ${result.localPort.toString()}).
1106
1160
  `
1107
1161
  );
1108
1162
  }
1109
1163
  async function handleList() {
1110
1164
  const sessions = await listSessions();
1111
- process4.stdout.write(`${JSON.stringify(sessions, null, 2)}
1165
+ process6.stdout.write(`${JSON.stringify(sessions, null, 2)}
1112
1166
  `);
1113
1167
  }
1114
1168
  async function handleStatus(opts) {
@@ -1118,7 +1172,7 @@ async function handleStatus(opts) {
1118
1172
  space: opts.space,
1119
1173
  app: opts.app
1120
1174
  });
1121
- process4.stdout.write(`${JSON.stringify(session ?? null, null, 2)}
1175
+ process6.stdout.write(`${JSON.stringify(session ?? null, null, 2)}
1122
1176
  `);
1123
1177
  }
1124
1178
  async function main(argv) {
@@ -1139,22 +1193,22 @@ async function main(argv) {
1139
1193
  await program.parseAsync([...argv]);
1140
1194
  }
1141
1195
  try {
1142
- await main(process4.argv);
1196
+ await main(process6.argv);
1143
1197
  } catch (err) {
1144
1198
  if (err instanceof CfDebuggerError) {
1145
1199
  if (err.code === "ABORTED") {
1146
- process4.stderr.write(`Aborted: ${err.message}
1200
+ process6.stderr.write(`Aborted: ${err.message}
1147
1201
  `);
1148
- process4.exit(130);
1202
+ process6.exit(130);
1149
1203
  }
1150
- process4.stderr.write(`Error [${err.code}]: ${err.message}
1204
+ process6.stderr.write(`Error [${err.code}]: ${err.message}
1151
1205
  `);
1152
1206
  } else {
1153
1207
  const msg = err instanceof Error ? err.message : String(err);
1154
- process4.stderr.write(`Error: ${msg}
1208
+ process6.stderr.write(`Error: ${msg}
1155
1209
  `);
1156
1210
  }
1157
- process4.exit(1);
1211
+ process6.exit(1);
1158
1212
  }
1159
1213
  export {
1160
1214
  main