@saptools/cf-inspector 0.4.3 → 0.4.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
@@ -152,13 +152,13 @@ var init_wsTransport = __esm({
152
152
  });
153
153
 
154
154
  // src/cli.ts
155
- import process11 from "process";
155
+ import process12 from "process";
156
156
 
157
157
  // src/cli/program.ts
158
158
  import { Command } from "commander";
159
159
 
160
160
  // src/cli/commands/attach.ts
161
- import process2 from "process";
161
+ import process3 from "process";
162
162
 
163
163
  // src/inspector/discovery.ts
164
164
  init_types();
@@ -387,6 +387,13 @@ function writeWatchEvent(event, json) {
387
387
  }
388
388
  }
389
389
 
390
+ // src/cli/target.ts
391
+ import process2 from "process";
392
+ import {
393
+ readCurrentCfTarget,
394
+ requireCurrentCfRegion
395
+ } from "@saptools/cf-debugger";
396
+
390
397
  // src/cf/tunnel.ts
391
398
  import { startDebugger } from "@saptools/cf-debugger";
392
399
  async function openCfTunnel(target) {
@@ -874,29 +881,79 @@ function parsePositiveInt(raw, label) {
874
881
  }
875
882
  return value;
876
883
  }
877
- function resolveTarget(opts) {
884
+ async function resolveTargetWithCurrentCfTarget(opts) {
878
885
  const port = parsePositiveInt(opts.port, "--port");
879
886
  if (port !== void 0) {
880
887
  return { kind: "port", port, host: opts.host ?? "127.0.0.1" };
881
888
  }
882
- if (hasCfTarget(opts)) {
883
- const cfTimeoutSec = parsePositiveInt(opts.cfTimeout, "--cf-timeout") ?? DEFAULT_CF_TIMEOUT_SEC;
884
- return {
885
- kind: "cf",
886
- region: opts.region,
887
- org: opts.org,
888
- space: opts.space,
889
- app: opts.app,
890
- cfTimeoutMs: cfTimeoutSec * 1e3
891
- };
889
+ const app = optionalText(opts.app);
890
+ if (app === void 0) {
891
+ throw missingTargetError();
892
892
  }
893
- throw new CfInspectorError(
894
- "MISSING_TARGET",
895
- "Provide either --port (and optionally --host) or all of --region, --org, --space, --app."
893
+ const cfTimeoutSec = parsePositiveInt(opts.cfTimeout, "--cf-timeout") ?? DEFAULT_CF_TIMEOUT_SEC;
894
+ const region = optionalText(opts.region);
895
+ const org = optionalText(opts.org);
896
+ const space = optionalText(opts.space);
897
+ if (region !== void 0 && org !== void 0 && space !== void 0) {
898
+ return buildCfTarget(region, org, space, app, cfTimeoutSec);
899
+ }
900
+ const current = await readCurrentTarget();
901
+ if (current === void 0) {
902
+ throw new CfInspectorError(
903
+ "MISSING_TARGET",
904
+ "No current CF target found. Run `cf target -o <org> -s <space>` or pass --region/--org/--space."
905
+ );
906
+ }
907
+ return buildCfTarget(
908
+ region ?? currentRegion(current),
909
+ org ?? current.org,
910
+ space ?? current.space,
911
+ app,
912
+ cfTimeoutSec
896
913
  );
897
914
  }
898
- function hasCfTarget(opts) {
899
- return opts.region !== void 0 && opts.org !== void 0 && opts.space !== void 0 && opts.app !== void 0;
915
+ function buildCfTarget(region, org, space, app, cfTimeoutSec) {
916
+ return {
917
+ kind: "cf",
918
+ region,
919
+ org,
920
+ space,
921
+ app,
922
+ cfTimeoutMs: cfTimeoutSec * 1e3
923
+ };
924
+ }
925
+ function optionalText(value) {
926
+ const trimmed = value?.trim();
927
+ return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
928
+ }
929
+ function currentCfOptions() {
930
+ const command = process2.env["CF_DEBUGGER_CF_BIN"];
931
+ return command === void 0 ? void 0 : { command };
932
+ }
933
+ async function readCurrentTarget() {
934
+ try {
935
+ return await readCurrentCfTarget(currentCfOptions());
936
+ } catch (error) {
937
+ throw new CfInspectorError(
938
+ "MISSING_TARGET",
939
+ "No current CF target found. Run `cf target -o <org> -s <space>` or pass --region/--org/--space.",
940
+ error instanceof Error ? error.message : String(error)
941
+ );
942
+ }
943
+ }
944
+ function currentRegion(current) {
945
+ try {
946
+ return requireCurrentCfRegion(current, "Pass --region explicitly.");
947
+ } catch (error) {
948
+ const message = error instanceof Error ? error.message : String(error);
949
+ throw new CfInspectorError("MISSING_TARGET", message);
950
+ }
951
+ }
952
+ function missingTargetError() {
953
+ return new CfInspectorError(
954
+ "MISSING_TARGET",
955
+ "Provide either --port (and optionally --host), an --app with current cf target, or all of --region, --org, --space, --app."
956
+ );
900
957
  }
901
958
  async function withSession(target, fn, reportProgress) {
902
959
  const tunnel = await openTarget(target, reportProgress);
@@ -949,7 +1006,7 @@ async function openTarget(target, reportProgress) {
949
1006
 
950
1007
  // src/cli/commands/attach.ts
951
1008
  async function handleAttach(opts) {
952
- const target = resolveTarget(opts);
1009
+ const target = await resolveTargetWithCurrentCfTarget(opts);
953
1010
  const tunnel = await openTarget(target);
954
1011
  try {
955
1012
  const version = await fetchInspectorVersion(tunnel.host, tunnel.port, 5e3);
@@ -957,7 +1014,7 @@ async function handleAttach(opts) {
957
1014
  writeJson({ host: tunnel.host, port: tunnel.port, ...version });
958
1015
  return;
959
1016
  }
960
- process2.stdout.write(
1017
+ process3.stdout.write(
961
1018
  `Connected to ${tunnel.host}:${tunnel.port.toString()}
962
1019
  Browser: ${version.browser}
963
1020
  Protocol: ${version.protocolVersion}
@@ -969,7 +1026,7 @@ async function handleAttach(opts) {
969
1026
  }
970
1027
 
971
1028
  // src/cli/commands/eval.ts
972
- import process3 from "process";
1029
+ import process4 from "process";
973
1030
 
974
1031
  // src/inspector/runtime.ts
975
1032
  init_types();
@@ -1026,14 +1083,14 @@ async function getProperties(session, objectId) {
1026
1083
 
1027
1084
  // src/cli/commands/eval.ts
1028
1085
  async function handleEval(opts) {
1029
- const target = resolveTarget(opts);
1086
+ const target = await resolveTargetWithCurrentCfTarget(opts);
1030
1087
  const result = await withSession(target, async (session) => {
1031
1088
  return await evaluateGlobal(session, opts.expr);
1032
1089
  });
1033
1090
  if (opts.json) {
1034
1091
  writeJson(result);
1035
1092
  if (result.exceptionDetails !== void 0) {
1036
- process3.exitCode = 1;
1093
+ process4.exitCode = 1;
1037
1094
  }
1038
1095
  return;
1039
1096
  }
@@ -1042,33 +1099,33 @@ async function handleEval(opts) {
1042
1099
  function writeHumanEvalResult(result) {
1043
1100
  if (result.exceptionDetails !== void 0) {
1044
1101
  const detail = typeof result.exceptionDetails.exception?.description === "string" ? result.exceptionDetails.exception.description : typeof result.exceptionDetails.text === "string" ? result.exceptionDetails.text : "evaluation failed";
1045
- process3.stderr.write(`${detail}
1102
+ process4.stderr.write(`${detail}
1046
1103
  `);
1047
- process3.exitCode = 1;
1104
+ process4.exitCode = 1;
1048
1105
  return;
1049
1106
  }
1050
1107
  const inner = result.result;
1051
1108
  if (inner === void 0) {
1052
- process3.stdout.write("\n");
1109
+ process4.stdout.write("\n");
1053
1110
  return;
1054
1111
  }
1055
1112
  if (typeof inner.value === "string") {
1056
- process3.stdout.write(`${inner.value}
1113
+ process4.stdout.write(`${inner.value}
1057
1114
  `);
1058
1115
  return;
1059
1116
  }
1060
1117
  if (typeof inner.description === "string") {
1061
- process3.stdout.write(`${inner.description}
1118
+ process4.stdout.write(`${inner.description}
1062
1119
  `);
1063
1120
  return;
1064
1121
  }
1065
- process3.stdout.write(`${JSON.stringify(inner.value)}
1122
+ process4.stdout.write(`${JSON.stringify(inner.value)}
1066
1123
  `);
1067
1124
  }
1068
1125
 
1069
1126
  // src/cli/commands/exception.ts
1070
1127
  import { performance as performance3 } from "perf_hooks";
1071
- import process5 from "process";
1128
+ import process6 from "process";
1072
1129
 
1073
1130
  // src/pathMapper.ts
1074
1131
  init_types();
@@ -1115,16 +1172,7 @@ function parseRemoteRoot(value) {
1115
1172
  return { kind: "literal", value: stripTrailingSlash(trimmed) };
1116
1173
  }
1117
1174
  function toRegex(pattern, flags) {
1118
- try {
1119
- const regex = new RegExp(pattern, flags);
1120
- return { kind: "regex", pattern, flags, regex };
1121
- } catch (err) {
1122
- const message = err instanceof Error ? err.message : String(err);
1123
- throw new CfInspectorError(
1124
- "INVALID_REMOTE_ROOT",
1125
- `Failed to compile remote-root regex "${pattern}" with flags "${flags}": ${message}`
1126
- );
1127
- }
1175
+ return { kind: "regex", pattern, flags };
1128
1176
  }
1129
1177
  function parseSlashDelimited(value) {
1130
1178
  if (!value.startsWith("/")) {
@@ -2024,11 +2072,11 @@ function splitCaptureExpressions(raw) {
2024
2072
  }
2025
2073
 
2026
2074
  // src/cli/warnings.ts
2027
- import process4 from "process";
2075
+ import process5 from "process";
2028
2076
  function warnOnUnboundBreakpoints(handles) {
2029
2077
  for (const handle of handles) {
2030
2078
  if (handle.resolvedLocations.length === 0) {
2031
- process4.stderr.write(
2079
+ process5.stderr.write(
2032
2080
  `[cf-inspector] warning: breakpoint ${handle.file}:${handle.line.toString()} did not bind to any loaded script. Check the path or pass --remote-root. Use 'list-scripts' to inspect what V8 currently has loaded.
2033
2081
  `
2034
2082
  );
@@ -2040,7 +2088,7 @@ function roundDurationMs(durationMs) {
2040
2088
  }
2041
2089
  function warnOnUnmatchedPause(pause) {
2042
2090
  const reason = pause.reason.length > 0 ? pause.reason : "unknown";
2043
- process4.stderr.write(
2091
+ process5.stderr.write(
2044
2092
  `[cf-inspector] warning: target is paused by another debugger event (${reason} at ${formatPauseLocation(pause)}); waiting for it to resume...
2045
2093
  `
2046
2094
  );
@@ -2069,7 +2117,8 @@ function formatPauseLocation(pause) {
2069
2117
  // src/cli/commands/exception.ts
2070
2118
  var VALID_PAUSE_TYPES = ["uncaught", "caught", "all"];
2071
2119
  async function handleException(opts) {
2072
- const prepared = prepareExceptionCommand(opts);
2120
+ const target = await resolveTargetWithCurrentCfTarget(opts);
2121
+ const prepared = prepareExceptionCommand(opts, target);
2073
2122
  const result = await runExceptionCommand(prepared, opts);
2074
2123
  if (opts.json) {
2075
2124
  writeJson(result);
@@ -2077,8 +2126,7 @@ async function handleException(opts) {
2077
2126
  writeHumanSnapshot(result);
2078
2127
  }
2079
2128
  }
2080
- function prepareExceptionCommand(opts) {
2081
- const target = resolveTarget(opts);
2129
+ function prepareExceptionCommand(opts, target) {
2082
2130
  const stateRaw = (opts.type ?? "uncaught").trim().toLowerCase();
2083
2131
  if (!VALID_PAUSE_TYPES.includes(stateRaw)) {
2084
2132
  throw new CfInspectorError(
@@ -2131,7 +2179,7 @@ async function resumeAfterException(session, snapshot, pausedStartedAt) {
2131
2179
  await resume(session);
2132
2180
  return withPausedDuration(snapshot, roundDurationMs(performance3.now() - pausedStartedAt));
2133
2181
  } catch {
2134
- process5.stderr.write(
2182
+ process6.stderr.write(
2135
2183
  "[cf-inspector] warning: Debugger.resume failed after exception capture; pausedDurationMs is unknown.\n"
2136
2184
  );
2137
2185
  return withPausedDuration(snapshot, null);
@@ -2145,22 +2193,22 @@ async function disablePauseOnExceptionsBestEffort(session) {
2145
2193
  }
2146
2194
 
2147
2195
  // src/cli/commands/listScripts.ts
2148
- import process6 from "process";
2196
+ import process7 from "process";
2149
2197
  async function handleListScripts(opts) {
2150
- const target = resolveTarget(opts);
2198
+ const target = await resolveTargetWithCurrentCfTarget(opts);
2151
2199
  const scripts = await withSession(target, (session) => Promise.resolve(listScripts(session)));
2152
2200
  if (opts.json) {
2153
2201
  writeJson(scripts);
2154
2202
  return;
2155
2203
  }
2156
2204
  for (const script of scripts) {
2157
- process6.stdout.write(`${script.scriptId} ${script.url}
2205
+ process7.stdout.write(`${script.scriptId} ${script.url}
2158
2206
  `);
2159
2207
  }
2160
2208
  }
2161
2209
 
2162
2210
  // src/cli/commands/log.ts
2163
- import process8 from "process";
2211
+ import process9 from "process";
2164
2212
 
2165
2213
  // src/logpoint/stream.ts
2166
2214
  init_types();
@@ -2409,25 +2457,25 @@ async function waitForStop(session, options, registerMaxEventsSignal) {
2409
2457
  init_types();
2410
2458
 
2411
2459
  // src/cli/signals.ts
2412
- import process7 from "process";
2460
+ import process8 from "process";
2413
2461
  async function withTerminationSignal(fn) {
2414
2462
  const abort = new AbortController();
2415
2463
  const onSignal = () => {
2416
2464
  abort.abort();
2417
2465
  };
2418
- process7.once("SIGINT", onSignal);
2419
- process7.once("SIGTERM", onSignal);
2466
+ process8.once("SIGINT", onSignal);
2467
+ process8.once("SIGTERM", onSignal);
2420
2468
  try {
2421
2469
  return await fn(abort.signal);
2422
2470
  } finally {
2423
- process7.off("SIGINT", onSignal);
2424
- process7.off("SIGTERM", onSignal);
2471
+ process8.off("SIGINT", onSignal);
2472
+ process8.off("SIGTERM", onSignal);
2425
2473
  }
2426
2474
  }
2427
2475
 
2428
2476
  // src/cli/commands/log.ts
2429
2477
  async function handleLog(opts) {
2430
- const target = resolveTarget(opts);
2478
+ const target = await resolveTargetWithCurrentCfTarget(opts);
2431
2479
  const location = parseBreakpointSpec(opts.at);
2432
2480
  const remoteRoot = parseRemoteRoot(opts.remoteRoot);
2433
2481
  const durationSec = parsePositiveInt(opts.duration, "--duration");
@@ -2466,11 +2514,11 @@ async function handleLog(opts) {
2466
2514
  }
2467
2515
  function writeLogSummary(stoppedReason, emitted, json) {
2468
2516
  if (json) {
2469
- process8.stderr.write(`${JSON.stringify({ stopped: stoppedReason, emitted })}
2517
+ process9.stderr.write(`${JSON.stringify({ stopped: stoppedReason, emitted })}
2470
2518
  `);
2471
2519
  return;
2472
2520
  }
2473
- process8.stderr.write(
2521
+ process9.stderr.write(
2474
2522
  `Stopped (${stoppedReason}); emitted ${emitted.toString()} log ${emitted === 1 ? "entry" : "entries"}.
2475
2523
  `
2476
2524
  );
@@ -2478,10 +2526,11 @@ function writeLogSummary(stoppedReason, emitted, json) {
2478
2526
 
2479
2527
  // src/cli/commands/snapshot.ts
2480
2528
  import { performance as performance4 } from "perf_hooks";
2481
- import process9 from "process";
2529
+ import process10 from "process";
2482
2530
  init_types();
2483
2531
  async function handleSnapshot(opts) {
2484
- const prepared = prepareSnapshotCommand(opts);
2532
+ const target = await resolveTargetWithCurrentCfTarget(opts);
2533
+ const prepared = prepareSnapshotCommand(opts, target);
2485
2534
  const reportProgress = opts.quiet === true ? void 0 : writeProgress;
2486
2535
  const result = await runSnapshotCommand(prepared, opts, reportProgress);
2487
2536
  if (opts.json) {
@@ -2491,8 +2540,7 @@ async function handleSnapshot(opts) {
2491
2540
  }
2492
2541
  reportProgress?.("Snapshot complete.");
2493
2542
  }
2494
- function prepareSnapshotCommand(opts) {
2495
- const target = resolveTarget(opts);
2543
+ function prepareSnapshotCommand(opts, target) {
2496
2544
  if (opts.bp.length === 0) {
2497
2545
  throw new CfInspectorError(
2498
2546
  "INVALID_BREAKPOINT",
@@ -2595,7 +2643,7 @@ async function resumeAfterSnapshot(session, snapshot, pausedStartedAt, reportPro
2595
2643
  reportProgress?.("Target resumed.");
2596
2644
  return withPausedDuration(snapshot, roundDurationMs(performance4.now() - pausedStartedAt));
2597
2645
  } catch {
2598
- process9.stderr.write(
2646
+ process10.stderr.write(
2599
2647
  "[cf-inspector] warning: Debugger.resume failed after snapshot; pausedDurationMs is unknown.\n"
2600
2648
  );
2601
2649
  return withPausedDuration(snapshot, null);
@@ -2604,10 +2652,11 @@ async function resumeAfterSnapshot(session, snapshot, pausedStartedAt, reportPro
2604
2652
 
2605
2653
  // src/cli/commands/watch.ts
2606
2654
  import { performance as performance5 } from "perf_hooks";
2607
- import process10 from "process";
2655
+ import process11 from "process";
2608
2656
  init_types();
2609
2657
  async function handleWatch(opts) {
2610
- const prepared = prepareWatchCommand(opts);
2658
+ const target = await resolveTargetWithCurrentCfTarget(opts);
2659
+ const prepared = prepareWatchCommand(opts, target);
2611
2660
  let stoppedReason = "signal";
2612
2661
  let emitted = 0;
2613
2662
  await withTerminationSignal(async (signal) => {
@@ -2619,8 +2668,7 @@ async function handleWatch(opts) {
2619
2668
  });
2620
2669
  writeWatchSummary(stoppedReason, emitted, opts.json);
2621
2670
  }
2622
- function prepareWatchCommand(opts) {
2623
- const target = resolveTarget(opts);
2671
+ function prepareWatchCommand(opts, target) {
2624
2672
  if (opts.bp.length === 0) {
2625
2673
  throw new CfInspectorError(
2626
2674
  "INVALID_BREAKPOINT",
@@ -2709,7 +2757,7 @@ async function runWatchLoop(session, command, opts, signal) {
2709
2757
  try {
2710
2758
  await resume(session);
2711
2759
  } catch {
2712
- process10.stderr.write("[cf-inspector] warning: Debugger.resume failed during watch.\n");
2760
+ process11.stderr.write("[cf-inspector] warning: Debugger.resume failed during watch.\n");
2713
2761
  setStop("transport-closed");
2714
2762
  break;
2715
2763
  }
@@ -2814,11 +2862,11 @@ function formatLocation(command, topFrame) {
2814
2862
  }
2815
2863
  function writeWatchSummary(reason, emitted, json) {
2816
2864
  if (json) {
2817
- process10.stderr.write(`${JSON.stringify({ stopped: reason, emitted })}
2865
+ process11.stderr.write(`${JSON.stringify({ stopped: reason, emitted })}
2818
2866
  `);
2819
2867
  return;
2820
2868
  }
2821
- process10.stderr.write(
2869
+ process11.stderr.write(
2822
2870
  `Stopped (${reason}); emitted ${emitted.toString()} watch ${emitted === 1 ? "event" : "events"}.
2823
2871
  `
2824
2872
  );
@@ -2826,7 +2874,7 @@ function writeWatchSummary(reason, emitted, json) {
2826
2874
 
2827
2875
  // src/cli/program.ts
2828
2876
  function applyTargetOptions(cmd) {
2829
- return cmd.option("--port <number>", "Local port the inspector or tunnel listens on").option("--host <host>", "Hostname (default: 127.0.0.1)", "127.0.0.1").option("--region <key>", "CF region key (e.g. eu10)").option("--org <name>", "CF org name").option("--space <name>", "CF space name").option("--app <name>", "CF app name").option("--cf-timeout <seconds>", "Timeout for CF tunnel readiness in seconds (default: 180)");
2877
+ return cmd.option("--port <number>", "Local port the inspector or tunnel listens on").option("--host <host>", "Hostname (default: 127.0.0.1)", "127.0.0.1").option("--region <key>", "CF region key (default: current cf target)").option("--org <name>", "CF org name (default: current cf target)").option("--space <name>", "CF space name (default: current cf target)").option("--app <name>", "CF app name when not using --port").option("--cf-timeout <seconds>", "Timeout for CF tunnel readiness in seconds (default: 180)");
2830
2878
  }
2831
2879
  var collectStrings = (value, prev = []) => [
2832
2880
  ...prev,
@@ -2897,20 +2945,20 @@ function registerAttach(program) {
2897
2945
  // src/cli.ts
2898
2946
  init_types();
2899
2947
  try {
2900
- await main(process11.argv);
2948
+ await main(process12.argv);
2901
2949
  } catch (err) {
2902
2950
  if (err instanceof CfInspectorError) {
2903
- process11.stderr.write(`Error [${err.code}]: ${err.message}
2951
+ process12.stderr.write(`Error [${err.code}]: ${err.message}
2904
2952
  `);
2905
2953
  if (err.detail !== void 0) {
2906
- process11.stderr.write(` detail: ${err.detail}
2954
+ process12.stderr.write(` detail: ${err.detail}
2907
2955
  `);
2908
2956
  }
2909
- process11.exit(1);
2957
+ process12.exit(1);
2910
2958
  }
2911
2959
  const message = err instanceof Error ? err.message : String(err);
2912
- process11.stderr.write(`Error: ${message}
2960
+ process12.stderr.write(`Error: ${message}
2913
2961
  `);
2914
- process11.exit(1);
2962
+ process12.exit(1);
2915
2963
  }
2916
2964
  //# sourceMappingURL=cli.js.map