@saptools/cf-inspector 0.5.0 → 0.6.0
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/README.md +51 -0
- package/dist/cli.js +380 -153
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +102 -7
- package/dist/index.js +495 -141
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -486,66 +486,70 @@ import "@saptools/cf-debugger";
|
|
|
486
486
|
|
|
487
487
|
// src/cf/tunnel.ts
|
|
488
488
|
import { startDebugger } from "@saptools/cf-debugger";
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
region: target.region,
|
|
489
|
+
function targetOptions(target) {
|
|
490
|
+
return {
|
|
492
491
|
...target.apiEndpoint === void 0 ? {} : { apiEndpoint: target.apiEndpoint },
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
492
|
+
...target.process === void 0 ? {} : { process: target.process },
|
|
493
|
+
...target.instance === void 0 ? {} : { instance: target.instance },
|
|
494
|
+
...target.nodePid === void 0 ? {} : { nodePid: target.nodePid }
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
function lifecycleOptions(target) {
|
|
498
|
+
return {
|
|
499
|
+
...target.allowSshEnableRestart === void 0 ? {} : { allowSshEnableRestart: target.allowSshEnableRestart },
|
|
496
500
|
...target.tunnelReadyTimeoutMs === void 0 ? {} : { tunnelReadyTimeoutMs: target.tunnelReadyTimeoutMs },
|
|
497
501
|
...target.preferredPort === void 0 ? {} : { preferredPort: target.preferredPort },
|
|
498
502
|
...target.verbose === void 0 ? {} : { verbose: target.verbose },
|
|
499
503
|
...target.signal === void 0 ? {} : { signal: target.signal },
|
|
500
504
|
...target.onStatus === void 0 ? {} : { onStatus: target.onStatus }
|
|
501
505
|
};
|
|
502
|
-
try {
|
|
503
|
-
const handle = await startDebugger(opts);
|
|
504
|
-
return {
|
|
505
|
-
localPort: handle.session.localPort,
|
|
506
|
-
handle,
|
|
507
|
-
dispose: async () => {
|
|
508
|
-
await handle.dispose();
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
} catch (err) {
|
|
512
|
-
return reuseExistingTunnelOrThrow(err, target.onStatus);
|
|
513
|
-
}
|
|
514
506
|
}
|
|
515
|
-
function
|
|
516
|
-
if (!isSessionAlreadyRunningError(err)) {
|
|
517
|
-
throw err;
|
|
518
|
-
}
|
|
519
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
520
|
-
const port = extractExistingTunnelPort(message);
|
|
521
|
-
if (port === void 0) {
|
|
522
|
-
throw err;
|
|
523
|
-
}
|
|
524
|
-
const warning = `Reusing existing tunnel on port ${port.toString()}`;
|
|
525
|
-
onStatus?.("ready", warning);
|
|
507
|
+
function toStartDebuggerOptions(target) {
|
|
526
508
|
return {
|
|
527
|
-
|
|
528
|
-
|
|
509
|
+
region: target.region,
|
|
510
|
+
org: target.org,
|
|
511
|
+
space: target.space,
|
|
512
|
+
app: target.app,
|
|
513
|
+
...targetOptions(target),
|
|
514
|
+
...lifecycleOptions(target)
|
|
529
515
|
};
|
|
530
516
|
}
|
|
531
|
-
function
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
517
|
+
async function openOwnedCfTunnel(target) {
|
|
518
|
+
const opts = toStartDebuggerOptions(target);
|
|
519
|
+
const handle = await startDebugger(opts);
|
|
520
|
+
return {
|
|
521
|
+
localPort: handle.session.localPort,
|
|
522
|
+
handle,
|
|
523
|
+
dispose: async () => {
|
|
524
|
+
await handle.dispose();
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
function isExistingSessionError(error) {
|
|
529
|
+
return error instanceof Error && "code" in error && error.code === "SESSION_ALREADY_RUNNING";
|
|
537
530
|
}
|
|
538
|
-
function
|
|
539
|
-
|
|
540
|
-
if (match === null) {
|
|
531
|
+
function existingTunnelPort(error) {
|
|
532
|
+
if (!isExistingSessionError(error)) {
|
|
541
533
|
return void 0;
|
|
542
534
|
}
|
|
543
|
-
const rawPort =
|
|
535
|
+
const rawPort = /\bon port (\d+)\b/iu.exec(error.message)?.[1];
|
|
544
536
|
if (rawPort === void 0) {
|
|
545
537
|
return void 0;
|
|
546
538
|
}
|
|
547
539
|
const port = Number.parseInt(rawPort, 10);
|
|
548
|
-
return Number.
|
|
540
|
+
return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : void 0;
|
|
541
|
+
}
|
|
542
|
+
async function openCfTunnel(target) {
|
|
543
|
+
try {
|
|
544
|
+
return await openOwnedCfTunnel(target);
|
|
545
|
+
} catch (error) {
|
|
546
|
+
const localPort = existingTunnelPort(error);
|
|
547
|
+
if (localPort === void 0) {
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
550
|
+
target.onStatus?.("ready", `Reusing existing tunnel on port ${localPort.toString()}`);
|
|
551
|
+
return { localPort, dispose: () => Promise.resolve() };
|
|
552
|
+
}
|
|
549
553
|
}
|
|
550
554
|
|
|
551
555
|
// src/inspector/session.ts
|
|
@@ -652,54 +656,70 @@ var CdpClient = class _CdpClient {
|
|
|
652
656
|
if (this.closed) {
|
|
653
657
|
throw this.closeReason ?? new CfInspectorError("INSPECTOR_CONNECTION_FAILED", "Connection closed");
|
|
654
658
|
}
|
|
655
|
-
|
|
659
|
+
if (options.signal?.aborted === true) {
|
|
660
|
+
throw this.createWaitAbortError(method);
|
|
661
|
+
}
|
|
662
|
+
return await this.createEventWait(method, options);
|
|
663
|
+
}
|
|
664
|
+
createEventWait(method, options) {
|
|
665
|
+
return new Promise((resolve, reject) => {
|
|
656
666
|
let settled = false;
|
|
667
|
+
let offEvent = () => void 0;
|
|
668
|
+
let offClose = () => void 0;
|
|
657
669
|
const cleanup = () => {
|
|
658
670
|
clearTimeout(timer);
|
|
659
671
|
offEvent();
|
|
660
672
|
offClose();
|
|
673
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
661
674
|
};
|
|
662
|
-
const
|
|
675
|
+
const resolveOnce = (value) => {
|
|
676
|
+
if (settled) {
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
663
679
|
settled = true;
|
|
664
680
|
cleanup();
|
|
665
681
|
resolve(value);
|
|
666
682
|
};
|
|
667
|
-
const
|
|
668
|
-
if (settled) {
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
const params = raw;
|
|
672
|
-
if (options.predicate) {
|
|
673
|
-
let accepted;
|
|
674
|
-
try {
|
|
675
|
-
accepted = options.predicate(params);
|
|
676
|
-
} catch {
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
if (!accepted) {
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
finish(params);
|
|
684
|
-
});
|
|
685
|
-
const offClose = this.onClose((err) => {
|
|
683
|
+
const rejectOnce = (error) => {
|
|
686
684
|
if (settled) {
|
|
687
685
|
return;
|
|
688
686
|
}
|
|
689
687
|
settled = true;
|
|
690
688
|
cleanup();
|
|
691
|
-
reject(
|
|
692
|
-
}
|
|
689
|
+
reject(error);
|
|
690
|
+
};
|
|
691
|
+
const onAbort = () => {
|
|
692
|
+
rejectOnce(this.createWaitAbortError(method));
|
|
693
|
+
};
|
|
693
694
|
const timer = setTimeout(() => {
|
|
694
|
-
|
|
695
|
+
rejectOnce(this.createWaitTimeoutError(method, options.timeoutMs));
|
|
696
|
+
}, options.timeoutMs);
|
|
697
|
+
offEvent = this.on(method, (raw) => {
|
|
698
|
+
const params = raw;
|
|
699
|
+
if (!this.eventMatches(params, options.predicate)) {
|
|
695
700
|
return;
|
|
696
701
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
702
|
+
resolveOnce(params);
|
|
703
|
+
});
|
|
704
|
+
offClose = this.onClose((error) => {
|
|
705
|
+
rejectOnce(error);
|
|
706
|
+
});
|
|
707
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
708
|
+
if (options.signal?.aborted === true) {
|
|
709
|
+
onAbort();
|
|
710
|
+
}
|
|
701
711
|
});
|
|
702
712
|
}
|
|
713
|
+
eventMatches(params, predicate) {
|
|
714
|
+
if (predicate === void 0) {
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
try {
|
|
718
|
+
return predicate(params);
|
|
719
|
+
} catch {
|
|
720
|
+
return false;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
703
723
|
onClose(listener) {
|
|
704
724
|
if (this.closed) {
|
|
705
725
|
const reason = this.closeReason ?? new CfInspectorError("INSPECTOR_CONNECTION_FAILED", "Connection closed");
|
|
@@ -766,6 +786,9 @@ var CdpClient = class _CdpClient {
|
|
|
766
786
|
`Timed out waiting for ${method} after ${timeoutMs.toString()}ms`
|
|
767
787
|
);
|
|
768
788
|
}
|
|
789
|
+
createWaitAbortError(method) {
|
|
790
|
+
return new CfInspectorError("ABORTED", `Aborted while waiting for ${method}`);
|
|
791
|
+
}
|
|
769
792
|
sendPayload(id, method, payload, timer, reject) {
|
|
770
793
|
try {
|
|
771
794
|
this.transport.send(payload);
|
|
@@ -892,96 +915,277 @@ async function createNodeWorkerClient(parent, sessionId, requestTimeoutMs = DEFA
|
|
|
892
915
|
init_types();
|
|
893
916
|
|
|
894
917
|
// src/inspector/conversions.ts
|
|
918
|
+
var INTERNAL_SLOT_SUBTYPES = /* @__PURE__ */ new Set([
|
|
919
|
+
"regexp",
|
|
920
|
+
"date",
|
|
921
|
+
"map",
|
|
922
|
+
"set",
|
|
923
|
+
"weakmap",
|
|
924
|
+
"weakset",
|
|
925
|
+
"iterator",
|
|
926
|
+
"generator",
|
|
927
|
+
"promise",
|
|
928
|
+
"typedarray",
|
|
929
|
+
"arraybuffer",
|
|
930
|
+
"dataview",
|
|
931
|
+
"webassemblymemory",
|
|
932
|
+
"wasmvalue",
|
|
933
|
+
"trustedtype"
|
|
934
|
+
]);
|
|
895
935
|
function asString(value, fallback = "") {
|
|
896
936
|
return typeof value === "string" ? value : fallback;
|
|
897
937
|
}
|
|
898
938
|
function asNumber(value, fallback = 0) {
|
|
899
939
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
900
940
|
}
|
|
941
|
+
function isRecord(value) {
|
|
942
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
943
|
+
}
|
|
901
944
|
function nonEmptyString(value) {
|
|
902
945
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
903
946
|
}
|
|
947
|
+
function optionalNumber(value) {
|
|
948
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
949
|
+
}
|
|
950
|
+
function optionalCoordinate(value) {
|
|
951
|
+
const number = optionalNumber(value);
|
|
952
|
+
return number !== void 0 && Number.isSafeInteger(number) && number >= 0 ? number : void 0;
|
|
953
|
+
}
|
|
954
|
+
function optionalBoolean(value) {
|
|
955
|
+
return typeof value === "boolean" ? value : void 0;
|
|
956
|
+
}
|
|
957
|
+
function toScriptLocation(value) {
|
|
958
|
+
if (!isRecord(value)) {
|
|
959
|
+
return void 0;
|
|
960
|
+
}
|
|
961
|
+
const scriptId = nonEmptyString(value["scriptId"]);
|
|
962
|
+
const lineNumber = optionalCoordinate(value["lineNumber"]);
|
|
963
|
+
if (scriptId === void 0 || lineNumber === void 0) {
|
|
964
|
+
return void 0;
|
|
965
|
+
}
|
|
966
|
+
const rawColumnNumber = value["columnNumber"];
|
|
967
|
+
const columnNumber = optionalCoordinate(rawColumnNumber);
|
|
968
|
+
if (rawColumnNumber !== void 0 && columnNumber === void 0) {
|
|
969
|
+
return void 0;
|
|
970
|
+
}
|
|
971
|
+
return columnNumber === void 0 ? { scriptId, lineNumber } : { scriptId, lineNumber, columnNumber };
|
|
972
|
+
}
|
|
904
973
|
function toResolvedLocations(value) {
|
|
905
974
|
if (!Array.isArray(value)) {
|
|
906
975
|
return [];
|
|
907
976
|
}
|
|
908
977
|
return value.flatMap((entry) => {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
}
|
|
912
|
-
const candidate = entry;
|
|
913
|
-
const scriptId = asString(candidate.scriptId);
|
|
914
|
-
if (scriptId.length === 0) {
|
|
978
|
+
const location = toScriptLocation(entry);
|
|
979
|
+
if (location === void 0 || !isRecord(entry)) {
|
|
915
980
|
return [];
|
|
916
981
|
}
|
|
917
|
-
const url = typeof
|
|
918
|
-
|
|
919
|
-
const result = url === void 0 ? { scriptId, lineNumber, columnNumber: asNumber(candidate.columnNumber) } : { scriptId, url, lineNumber, columnNumber: asNumber(candidate.columnNumber) };
|
|
920
|
-
return [result];
|
|
982
|
+
const url = typeof entry["url"] === "string" ? entry["url"] : void 0;
|
|
983
|
+
return [url === void 0 ? location : { ...location, url }];
|
|
921
984
|
});
|
|
922
985
|
}
|
|
923
|
-
function
|
|
924
|
-
if (
|
|
925
|
-
return
|
|
986
|
+
function remoteCompleteness(subtype) {
|
|
987
|
+
if (subtype === "proxy") {
|
|
988
|
+
return "unavailable";
|
|
926
989
|
}
|
|
927
|
-
return
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
990
|
+
return subtype !== void 0 && INTERNAL_SLOT_SUBTYPES.has(subtype) ? "truncated" : void 0;
|
|
991
|
+
}
|
|
992
|
+
function optionalOwnField(key, value) {
|
|
993
|
+
return Object.hasOwn(value, key) ? { [key]: value[key] } : {};
|
|
994
|
+
}
|
|
995
|
+
function toRemoteObject(value) {
|
|
996
|
+
if (!isRecord(value)) {
|
|
997
|
+
return void 0;
|
|
998
|
+
}
|
|
999
|
+
const type = nonEmptyString(value["type"]);
|
|
1000
|
+
if (type === void 0) {
|
|
1001
|
+
return void 0;
|
|
1002
|
+
}
|
|
1003
|
+
const subtype = nonEmptyString(value["subtype"]);
|
|
1004
|
+
const completeness = remoteCompleteness(subtype);
|
|
1005
|
+
return {
|
|
1006
|
+
type,
|
|
1007
|
+
...subtype === void 0 ? {} : { subtype },
|
|
1008
|
+
...optionalTextField("className", value["className"]),
|
|
1009
|
+
...completeness === void 0 ? {} : { completeness },
|
|
1010
|
+
...optionalOwnField("value", value),
|
|
1011
|
+
...optionalTextField("unserializableValue", value["unserializableValue"]),
|
|
1012
|
+
...optionalTextField("description", value["description"]),
|
|
1013
|
+
...optionalOwnField("deepSerializedValue", value),
|
|
1014
|
+
...optionalTextField("objectId", value["objectId"]),
|
|
1015
|
+
...optionalOwnField("preview", value),
|
|
1016
|
+
...optionalOwnField("customPreview", value)
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
function optionalTextField(key, value) {
|
|
1020
|
+
return typeof value === "string" ? { [key]: value } : {};
|
|
1021
|
+
}
|
|
1022
|
+
function toScope(value) {
|
|
1023
|
+
if (!isRecord(value)) {
|
|
1024
|
+
return void 0;
|
|
1025
|
+
}
|
|
1026
|
+
const type = nonEmptyString(value["type"]);
|
|
1027
|
+
if (type === void 0) {
|
|
1028
|
+
return void 0;
|
|
1029
|
+
}
|
|
1030
|
+
const object = toRemoteObject(value["object"]);
|
|
1031
|
+
const name = nonEmptyString(value["name"]);
|
|
1032
|
+
const startLocation = toScriptLocation(value["startLocation"]);
|
|
1033
|
+
const endLocation = toScriptLocation(value["endLocation"]);
|
|
1034
|
+
return {
|
|
1035
|
+
type,
|
|
1036
|
+
...name === void 0 ? {} : { name },
|
|
1037
|
+
...object === void 0 ? {} : { object },
|
|
1038
|
+
...object?.objectId === void 0 ? {} : { objectId: object.objectId },
|
|
1039
|
+
...startLocation === void 0 ? {} : { startLocation },
|
|
1040
|
+
...endLocation === void 0 ? {} : { endLocation }
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function toScopeChain(value) {
|
|
1044
|
+
return Array.isArray(value) ? value.flatMap((entry) => {
|
|
1045
|
+
const scope = toScope(entry);
|
|
1046
|
+
return scope === void 0 ? [] : [scope];
|
|
1047
|
+
}) : [];
|
|
941
1048
|
}
|
|
942
1049
|
function resolveCallFrameUrl(frame, scripts) {
|
|
943
|
-
const direct = nonEmptyString(frame
|
|
1050
|
+
const direct = nonEmptyString(frame["url"]);
|
|
944
1051
|
if (direct !== void 0) {
|
|
945
1052
|
return direct;
|
|
946
1053
|
}
|
|
947
|
-
const scriptId =
|
|
948
|
-
|
|
1054
|
+
const scriptId = toScriptLocation(frame["location"])?.scriptId;
|
|
1055
|
+
return scriptId === void 0 ? void 0 : nonEmptyString(scripts?.get(scriptId)?.url);
|
|
1056
|
+
}
|
|
1057
|
+
function toCallFrameMetadata(candidate, location, scripts) {
|
|
1058
|
+
const functionLocation = toScriptLocation(candidate["functionLocation"]);
|
|
1059
|
+
const thisObject = toRemoteObject(candidate["this"]);
|
|
1060
|
+
const returnValue = toRemoteObject(candidate["returnValue"]);
|
|
1061
|
+
const url = resolveCallFrameUrl(candidate, scripts);
|
|
1062
|
+
return {
|
|
1063
|
+
...location === void 0 ? {} : { scriptId: location.scriptId },
|
|
1064
|
+
...functionLocation === void 0 ? {} : { functionLocation },
|
|
1065
|
+
...url === void 0 ? {} : { url },
|
|
1066
|
+
...thisObject === void 0 ? {} : { thisObject },
|
|
1067
|
+
...returnValue === void 0 ? {} : { returnValue }
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
function toCallFrame(value, scripts) {
|
|
1071
|
+
if (!isRecord(value)) {
|
|
1072
|
+
return void 0;
|
|
1073
|
+
}
|
|
1074
|
+
const callFrameId = nonEmptyString(value["callFrameId"]);
|
|
1075
|
+
if (callFrameId === void 0) {
|
|
949
1076
|
return void 0;
|
|
950
1077
|
}
|
|
951
|
-
|
|
1078
|
+
const location = toScriptLocation(value["location"]);
|
|
1079
|
+
return {
|
|
1080
|
+
callFrameId,
|
|
1081
|
+
functionName: asString(value["functionName"]),
|
|
1082
|
+
...toCallFrameMetadata(value, location, scripts),
|
|
1083
|
+
lineNumber: location?.lineNumber ?? 0,
|
|
1084
|
+
columnNumber: location?.columnNumber ?? 0,
|
|
1085
|
+
scopeChain: toScopeChain(value["scopeChain"])
|
|
1086
|
+
};
|
|
952
1087
|
}
|
|
953
1088
|
function toCallFrames(value, scripts) {
|
|
954
|
-
|
|
955
|
-
|
|
1089
|
+
return Array.isArray(value) ? value.flatMap((entry) => {
|
|
1090
|
+
const frame = toCallFrame(entry, scripts);
|
|
1091
|
+
return frame === void 0 ? [] : [frame];
|
|
1092
|
+
}) : [];
|
|
1093
|
+
}
|
|
1094
|
+
function toStackTraceId(value) {
|
|
1095
|
+
if (!isRecord(value)) {
|
|
1096
|
+
return void 0;
|
|
956
1097
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1098
|
+
const id = nonEmptyString(value["id"]);
|
|
1099
|
+
if (id === void 0) {
|
|
1100
|
+
return void 0;
|
|
1101
|
+
}
|
|
1102
|
+
const debuggerId = nonEmptyString(value["debuggerId"]);
|
|
1103
|
+
return debuggerId === void 0 ? { id } : { id, debuggerId };
|
|
1104
|
+
}
|
|
1105
|
+
function toStackTraceFrame(value) {
|
|
1106
|
+
if (!isRecord(value)) {
|
|
1107
|
+
return void 0;
|
|
1108
|
+
}
|
|
1109
|
+
const scriptId = nonEmptyString(value["scriptId"]);
|
|
1110
|
+
if (scriptId === void 0) {
|
|
1111
|
+
return void 0;
|
|
1112
|
+
}
|
|
1113
|
+
return {
|
|
1114
|
+
functionName: asString(value["functionName"]),
|
|
1115
|
+
scriptId,
|
|
1116
|
+
url: asString(value["url"]),
|
|
1117
|
+
lineNumber: asNumber(value["lineNumber"]),
|
|
1118
|
+
columnNumber: asNumber(value["columnNumber"])
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
function toStackTrace(value) {
|
|
1122
|
+
if (!isRecord(value) || !Array.isArray(value["callFrames"])) {
|
|
1123
|
+
return void 0;
|
|
1124
|
+
}
|
|
1125
|
+
const callFrames = value["callFrames"].flatMap((entry) => {
|
|
1126
|
+
const frame = toStackTraceFrame(entry);
|
|
1127
|
+
return frame === void 0 ? [] : [frame];
|
|
975
1128
|
});
|
|
1129
|
+
const description = nonEmptyString(value["description"]);
|
|
1130
|
+
const parent = toStackTrace(value["parent"]);
|
|
1131
|
+
const parentId = toStackTraceId(value["parentId"]);
|
|
1132
|
+
return {
|
|
1133
|
+
callFrames,
|
|
1134
|
+
...description === void 0 ? {} : { description },
|
|
1135
|
+
...parent === void 0 ? {} : { parent },
|
|
1136
|
+
...parentId === void 0 ? {} : { parentId }
|
|
1137
|
+
};
|
|
976
1138
|
}
|
|
977
|
-
function toPauseEvent(
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1139
|
+
function toPauseEvent(value, receivedAtMs, scripts) {
|
|
1140
|
+
const params = isRecord(value) ? value : {};
|
|
1141
|
+
const asyncStackTrace = toStackTrace(params["asyncStackTrace"]);
|
|
1142
|
+
const asyncStackTraceId = toStackTraceId(params["asyncStackTraceId"]);
|
|
1143
|
+
const asyncCallStackTraceId = toStackTraceId(params["asyncCallStackTraceId"]);
|
|
1144
|
+
return {
|
|
1145
|
+
reason: asString(params["reason"]),
|
|
1146
|
+
hitBreakpoints: Array.isArray(params["hitBreakpoints"]) ? params["hitBreakpoints"].filter((id) => typeof id === "string") : [],
|
|
1147
|
+
callFrames: toCallFrames(params["callFrames"], scripts),
|
|
1148
|
+
receivedAtMs,
|
|
1149
|
+
...params["data"] === void 0 ? {} : { data: params["data"] },
|
|
1150
|
+
...asyncStackTrace === void 0 ? {} : { asyncStackTrace },
|
|
1151
|
+
...asyncStackTraceId === void 0 ? {} : { asyncStackTraceId },
|
|
1152
|
+
...asyncCallStackTraceId === void 0 ? {} : { asyncCallStackTraceId }
|
|
983
1153
|
};
|
|
984
|
-
|
|
1154
|
+
}
|
|
1155
|
+
function toScriptInfo(value) {
|
|
1156
|
+
if (!isRecord(value)) {
|
|
1157
|
+
return void 0;
|
|
1158
|
+
}
|
|
1159
|
+
const scriptId = nonEmptyString(value["scriptId"]);
|
|
1160
|
+
if (scriptId === void 0) {
|
|
1161
|
+
return void 0;
|
|
1162
|
+
}
|
|
1163
|
+
const stackTrace = toStackTrace(value["stackTrace"]);
|
|
1164
|
+
return {
|
|
1165
|
+
scriptId,
|
|
1166
|
+
url: asString(value["url"]),
|
|
1167
|
+
...optionalNumericField("startLine", value["startLine"]),
|
|
1168
|
+
...optionalNumericField("startColumn", value["startColumn"]),
|
|
1169
|
+
...optionalNumericField("endLine", value["endLine"]),
|
|
1170
|
+
...optionalNumericField("endColumn", value["endColumn"]),
|
|
1171
|
+
...optionalNumericField("executionContextId", value["executionContextId"]),
|
|
1172
|
+
...optionalTextField("hash", value["hash"]),
|
|
1173
|
+
...optionalTextField("buildId", value["buildId"]),
|
|
1174
|
+
...value["executionContextAuxData"] === void 0 ? {} : { executionContextAuxData: value["executionContextAuxData"] },
|
|
1175
|
+
...optionalTextField("sourceMapURL", value["sourceMapURL"]),
|
|
1176
|
+
...optionalBooleanField("hasSourceURL", value["hasSourceURL"]),
|
|
1177
|
+
...optionalBooleanField("isModule", value["isModule"]),
|
|
1178
|
+
...optionalNumericField("length", value["length"]),
|
|
1179
|
+
...stackTrace === void 0 ? {} : { stackTrace }
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
function optionalNumericField(key, value) {
|
|
1183
|
+
const number = optionalNumber(value);
|
|
1184
|
+
return number === void 0 ? {} : { [key]: number };
|
|
1185
|
+
}
|
|
1186
|
+
function optionalBooleanField(key, value) {
|
|
1187
|
+
const boolean = optionalBoolean(value);
|
|
1188
|
+
return boolean === void 0 ? {} : { [key]: boolean };
|
|
985
1189
|
}
|
|
986
1190
|
function topFrameLocation(pause) {
|
|
987
1191
|
const top = pause.callFrames[0];
|
|
@@ -1191,24 +1395,29 @@ async function discoverNodeWorkerTargets(target, connectTimeoutMs = DEFAULT_CONN
|
|
|
1191
1395
|
}
|
|
1192
1396
|
async function initSession(client, target) {
|
|
1193
1397
|
const scripts = /* @__PURE__ */ new Map();
|
|
1194
|
-
client
|
|
1195
|
-
const params = raw;
|
|
1196
|
-
const scriptId = asString(params.scriptId);
|
|
1197
|
-
const url = asString(params.url);
|
|
1198
|
-
if (scriptId.length === 0) {
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
|
-
scripts.set(scriptId, { scriptId, url });
|
|
1202
|
-
});
|
|
1398
|
+
registerScriptTracking(client, scripts);
|
|
1203
1399
|
const pauseBuffer = [];
|
|
1204
1400
|
const pauseWaitGate = { active: false };
|
|
1205
1401
|
const debuggerState = {};
|
|
1402
|
+
registerPauseTracking(client, scripts, pauseBuffer, pauseWaitGate, debuggerState);
|
|
1403
|
+
await client.send("Runtime.enable");
|
|
1404
|
+
await client.send("Debugger.enable");
|
|
1405
|
+
return createSession(client, target, scripts, pauseBuffer, pauseWaitGate, debuggerState);
|
|
1406
|
+
}
|
|
1407
|
+
function registerScriptTracking(client, scripts) {
|
|
1408
|
+
client.on("Debugger.scriptParsed", (raw) => {
|
|
1409
|
+
const script = toScriptInfo(raw);
|
|
1410
|
+
if (script !== void 0) {
|
|
1411
|
+
scripts.set(script.scriptId, script);
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
function registerPauseTracking(client, scripts, pauseBuffer, pauseWaitGate, debuggerState) {
|
|
1206
1416
|
client.on("Debugger.paused", (raw) => {
|
|
1207
1417
|
if (pauseWaitGate.active) {
|
|
1208
1418
|
return;
|
|
1209
1419
|
}
|
|
1210
|
-
const
|
|
1211
|
-
const event = toPauseEvent(params, performance2.now(), scripts);
|
|
1420
|
+
const event = toPauseEvent(raw, performance2.now(), scripts);
|
|
1212
1421
|
if (pauseBuffer.length >= PAUSE_BUFFER_LIMIT) {
|
|
1213
1422
|
pauseBuffer.shift();
|
|
1214
1423
|
}
|
|
@@ -1217,8 +1426,8 @@ async function initSession(client, target) {
|
|
|
1217
1426
|
client.on("Debugger.resumed", () => {
|
|
1218
1427
|
debuggerState.lastResumedAtMs = performance2.now();
|
|
1219
1428
|
});
|
|
1220
|
-
|
|
1221
|
-
|
|
1429
|
+
}
|
|
1430
|
+
function createSession(client, target, scripts, pauseBuffer, pauseWaitGate, debuggerState) {
|
|
1222
1431
|
return {
|
|
1223
1432
|
client,
|
|
1224
1433
|
target,
|
|
@@ -1577,8 +1786,8 @@ function optionalText(value) {
|
|
|
1577
1786
|
const trimmed = value?.trim();
|
|
1578
1787
|
return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
|
|
1579
1788
|
}
|
|
1580
|
-
async function withSession(target, fn, reportProgress) {
|
|
1581
|
-
const tunnel = await openTarget(target, reportProgress);
|
|
1789
|
+
async function withSession(target, fn, reportProgress, signal) {
|
|
1790
|
+
const tunnel = await openTarget(target, reportProgress, signal);
|
|
1582
1791
|
let session;
|
|
1583
1792
|
try {
|
|
1584
1793
|
reportProgress?.(
|
|
@@ -1605,7 +1814,7 @@ async function withSession(target, fn, reportProgress) {
|
|
|
1605
1814
|
await tunnel.dispose();
|
|
1606
1815
|
}
|
|
1607
1816
|
}
|
|
1608
|
-
async function openTarget(target, reportProgress) {
|
|
1817
|
+
async function openTarget(target, reportProgress, signal) {
|
|
1609
1818
|
if (target.kind === "port") {
|
|
1610
1819
|
return {
|
|
1611
1820
|
port: target.port,
|
|
@@ -1621,6 +1830,7 @@ async function openTarget(target, reportProgress) {
|
|
|
1621
1830
|
space: target.space,
|
|
1622
1831
|
app: target.app,
|
|
1623
1832
|
tunnelReadyTimeoutMs: target.tunnelTimeoutMs,
|
|
1833
|
+
...signal === void 0 ? {} : { signal },
|
|
1624
1834
|
...reportProgress === void 0 ? {} : {
|
|
1625
1835
|
onStatus: (status, message) => {
|
|
1626
1836
|
reportProgress(message ?? formatCfTunnelStatus(status));
|
|
@@ -1675,7 +1885,8 @@ async function evaluateOnFrame(session, callFrameId, expression, options = {}) {
|
|
|
1675
1885
|
returnByValue: false,
|
|
1676
1886
|
generatePreview: true,
|
|
1677
1887
|
silent: true,
|
|
1678
|
-
...options.throwOnSideEffect === void 0 ? {} : { throwOnSideEffect: options.throwOnSideEffect }
|
|
1888
|
+
...options.throwOnSideEffect === void 0 ? {} : { throwOnSideEffect: options.throwOnSideEffect },
|
|
1889
|
+
...options.objectGroup === void 0 ? {} : { objectGroup: options.objectGroup }
|
|
1679
1890
|
});
|
|
1680
1891
|
}
|
|
1681
1892
|
function isSideEffectRefusal(result) {
|
|
@@ -2012,6 +2223,11 @@ function pauseMatches(pause, breakpointIds, pauseReasons) {
|
|
|
2012
2223
|
function remainingUntil(deadlineMs) {
|
|
2013
2224
|
return Math.max(0, deadlineMs - performance3.now());
|
|
2014
2225
|
}
|
|
2226
|
+
function throwIfAborted(signal) {
|
|
2227
|
+
if (signal?.aborted === true) {
|
|
2228
|
+
throw new CfInspectorError("ABORTED", "Aborted while waiting for Debugger.paused");
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2015
2231
|
function hasResumedSincePause(session, pause) {
|
|
2016
2232
|
const pauseAt = pause.receivedAtMs;
|
|
2017
2233
|
const resumedAt = session.debuggerState.lastResumedAtMs;
|
|
@@ -2030,20 +2246,23 @@ function throwUnrelatedPauseTimeout(pause, timeoutMs) {
|
|
|
2030
2246
|
pauseDetail(pause)
|
|
2031
2247
|
);
|
|
2032
2248
|
}
|
|
2033
|
-
async function waitForUnmatchedPauseToResume(session, pause, deadlineMs,
|
|
2249
|
+
async function waitForUnmatchedPauseToResume(session, pause, deadlineMs, options) {
|
|
2034
2250
|
if (hasResumedSincePause(session, pause)) {
|
|
2035
2251
|
return;
|
|
2036
2252
|
}
|
|
2037
2253
|
const remainingMs = remainingUntil(deadlineMs);
|
|
2038
2254
|
if (remainingMs <= 0) {
|
|
2039
|
-
throwUnrelatedPauseTimeout(pause, timeoutMs);
|
|
2255
|
+
throwUnrelatedPauseTimeout(pause, options.timeoutMs);
|
|
2040
2256
|
}
|
|
2041
2257
|
try {
|
|
2042
|
-
await session.client.waitFor("Debugger.resumed", {
|
|
2258
|
+
await session.client.waitFor("Debugger.resumed", {
|
|
2259
|
+
timeoutMs: remainingMs,
|
|
2260
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2261
|
+
});
|
|
2043
2262
|
session.debuggerState.lastResumedAtMs = performance3.now();
|
|
2044
2263
|
} catch (err) {
|
|
2045
2264
|
if (err instanceof CfInspectorError && err.code === "BREAKPOINT_NOT_HIT") {
|
|
2046
|
-
throwUnrelatedPauseTimeout(pause, timeoutMs);
|
|
2265
|
+
throwUnrelatedPauseTimeout(pause, options.timeoutMs);
|
|
2047
2266
|
}
|
|
2048
2267
|
throw err;
|
|
2049
2268
|
}
|
|
@@ -2060,13 +2279,16 @@ async function handleUnmatchedPause(session, pause, options, deadlineMs) {
|
|
|
2060
2279
|
return;
|
|
2061
2280
|
}
|
|
2062
2281
|
options.onUnmatchedPause?.(pause);
|
|
2063
|
-
await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options
|
|
2282
|
+
await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options);
|
|
2064
2283
|
}
|
|
2065
2284
|
async function waitForPause(session, options) {
|
|
2285
|
+
throwIfAborted(options.signal);
|
|
2066
2286
|
const deadlineMs = performance3.now() + options.timeoutMs;
|
|
2067
2287
|
const buffer = session.pauseBuffer;
|
|
2068
2288
|
while (buffer.length > 0 || remainingUntil(deadlineMs) > 0) {
|
|
2289
|
+
throwIfAborted(options.signal);
|
|
2069
2290
|
while (buffer.length > 0) {
|
|
2291
|
+
throwIfAborted(options.signal);
|
|
2070
2292
|
const buffered = buffer.shift();
|
|
2071
2293
|
if (buffered === void 0) {
|
|
2072
2294
|
continue;
|
|
@@ -2095,6 +2317,7 @@ async function waitForLivePause(session, options, deadlineMs) {
|
|
|
2095
2317
|
try {
|
|
2096
2318
|
params = await session.client.waitFor("Debugger.paused", {
|
|
2097
2319
|
timeoutMs: remainingMs,
|
|
2320
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
2098
2321
|
predicate: () => {
|
|
2099
2322
|
receivedAtMs = performance3.now();
|
|
2100
2323
|
return true;
|
|
@@ -3399,7 +3622,7 @@ async function handleLog(opts) {
|
|
|
3399
3622
|
warnOnBoundBreakpointWithoutHit([result.handle]);
|
|
3400
3623
|
}
|
|
3401
3624
|
writeLogSummary(result.stoppedReason, result.emitted, opts.json);
|
|
3402
|
-
});
|
|
3625
|
+
}, void 0, signal);
|
|
3403
3626
|
});
|
|
3404
3627
|
}
|
|
3405
3628
|
function writeLogSummary(stoppedReason, emitted, json) {
|
|
@@ -3597,7 +3820,7 @@ async function handleWatch(opts) {
|
|
|
3597
3820
|
const result = await runWatchLoop(session, prepared, opts, signal);
|
|
3598
3821
|
stoppedReason = result.stoppedReason;
|
|
3599
3822
|
emitted = result.emitted;
|
|
3600
|
-
});
|
|
3823
|
+
}, void 0, signal);
|
|
3601
3824
|
});
|
|
3602
3825
|
writeWatchSummary(stoppedReason, emitted, opts.json);
|
|
3603
3826
|
}
|
|
@@ -3762,10 +3985,14 @@ async function waitForNextWatchPause(session, handles, timeoutMs, signal) {
|
|
|
3762
3985
|
return await waitForPause(session, {
|
|
3763
3986
|
timeoutMs,
|
|
3764
3987
|
breakpointIds: handles.map((h) => h.breakpointId),
|
|
3765
|
-
unmatchedPausePolicy: "wait-for-resume"
|
|
3988
|
+
unmatchedPausePolicy: "wait-for-resume",
|
|
3989
|
+
signal
|
|
3766
3990
|
});
|
|
3767
3991
|
} catch (err) {
|
|
3768
3992
|
if (err instanceof CfInspectorError) {
|
|
3993
|
+
if (err.code === "ABORTED") {
|
|
3994
|
+
return "signal";
|
|
3995
|
+
}
|
|
3769
3996
|
if (err.code === "BREAKPOINT_NOT_HIT") {
|
|
3770
3997
|
return "timeout";
|
|
3771
3998
|
}
|