@jshookmcp/jshook 0.2.7 → 0.2.9

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.
Files changed (157) hide show
  1. package/README.md +36 -5
  2. package/README.zh.md +36 -5
  3. package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-BNk-EoBt.mjs} +3 -3
  4. package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-Cq8q01kp.mjs} +5 -5
  5. package/dist/ConsoleMonitor-CPVQW1Y-.mjs +2201 -0
  6. package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-BNPxu0RH.mjs} +1 -1
  7. package/dist/DetailedDataManager-BQQcxh64.mjs +217 -0
  8. package/dist/EventBus-DgPmwpeu.mjs +141 -0
  9. package/dist/EvidenceGraphBridge-SFesNera.mjs +153 -0
  10. package/dist/{ExtensionManager-CZ6IveoV.mjs → ExtensionManager-CWYgw0YW.mjs} +13 -6
  11. package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-gzWtkKuf.mjs} +1 -1
  12. package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-B9gZCdFP.mjs} +3 -3
  13. package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-BLDH0dCv.mjs} +4 -4
  14. package/dist/HookGeneratorBuilders.core.generators.storage-CtcdK78Q.mjs +639 -0
  15. package/dist/InstrumentationSession-CvPC7Jwy.mjs +244 -0
  16. package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CbVdCIJF.mjs} +3 -3
  17. package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-BsDZbLYm.mjs} +81 -78
  18. package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-Bcpml6II.mjs} +44 -18
  19. package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-dZtA1ZGn.mjs} +14 -53
  20. package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-B-FjA2mJ.mjs} +1 -1
  21. package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-D1lzJ_VG.mjs} +2 -2
  22. package/dist/PageController-Bqm2kZ_X.mjs +417 -0
  23. package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-BOhyVsjx.mjs} +4 -4
  24. package/dist/PrerequisiteError-Dl33Svkz.mjs +20 -0
  25. package/dist/ResponseBuilder-D3iFYx2N.mjs +143 -0
  26. package/dist/ReverseEvidenceGraph-Dlsk94LC.mjs +269 -0
  27. package/dist/ScriptManager-aHHq0X7U.mjs +3000 -0
  28. package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-CqdIFlQl.mjs} +2 -2
  29. package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-DhFaPvRO.mjs} +3 -3
  30. package/dist/ToolCatalog-C0JGZoOm.mjs +582 -0
  31. package/dist/ToolError-jh9whhMd.mjs +15 -0
  32. package/dist/ToolProbe-oC7aPrkv.mjs +45 -0
  33. package/dist/ToolRegistry-BjaF4oNz.mjs +131 -0
  34. package/dist/ToolRouter.policy-BWV67ZK-.mjs +304 -0
  35. package/dist/TraceRecorder-DgxyVbdQ.mjs +519 -0
  36. package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-CePkipZY.mjs} +1 -1
  37. package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-BvKs-gxc.mjs} +2 -2
  38. package/dist/WorkflowEngine-CuvkZtWu.mjs +598 -0
  39. package/dist/analysis-CL9uACt9.mjs +463 -0
  40. package/dist/antidebug-CqDTB_uk.mjs +1081 -0
  41. package/dist/artifactRetention-CFEprwPw.mjs +591 -0
  42. package/dist/artifacts-Bk2-_uPq.mjs +59 -0
  43. package/dist/betterSqlite3-0pqusHHH.mjs +74 -0
  44. package/dist/binary-instrument-CXfpx6fT.mjs +979 -0
  45. package/dist/bind-helpers-xFfRF-qm.mjs +22 -0
  46. package/dist/boringssl-inspector-BH2D3VKc.mjs +180 -0
  47. package/dist/browser-BpOr5PEx.mjs +4082 -0
  48. package/dist/concurrency-Bt0yv1kJ.mjs +41 -0
  49. package/dist/{constants-CCvsN80K.mjs → constants-B0OANIBL.mjs} +88 -46
  50. package/dist/coordination-qUbyF8KU.mjs +259 -0
  51. package/dist/debugger-gnKxRSN0.mjs +1271 -0
  52. package/dist/definitions-6M-eejaT.mjs +53 -0
  53. package/dist/definitions-B18eyf0B.mjs +18 -0
  54. package/dist/definitions-B3QdlrHv.mjs +34 -0
  55. package/dist/definitions-B4rAvHNZ.mjs +63 -0
  56. package/dist/definitions-BB_4jnmy.mjs +37 -0
  57. package/dist/definitions-BMfYXoNC.mjs +43 -0
  58. package/dist/definitions-Beid2EB3.mjs +27 -0
  59. package/dist/definitions-C1UvM5Iy.mjs +126 -0
  60. package/dist/definitions-CXEI7QC72.mjs +216 -0
  61. package/dist/definitions-C_4r7Fo-2.mjs +14 -0
  62. package/dist/definitions-CkFDALoa.mjs +26 -0
  63. package/dist/definitions-Cke7zEb8.mjs +94 -0
  64. package/dist/definitions-ClJLzsJQ.mjs +25 -0
  65. package/dist/definitions-Cq-zroAU.mjs +28 -0
  66. package/dist/definitions-Cy3Sl6gV.mjs +34 -0
  67. package/dist/definitions-D3VsGcvz.mjs +47 -0
  68. package/dist/definitions-DVGfrn7y.mjs +96 -0
  69. package/dist/definitions-LKpC3-nL.mjs +9 -0
  70. package/dist/definitions-bAhHQJq9.mjs +359 -0
  71. package/dist/encoding-Bvz5jLRv.mjs +1065 -0
  72. package/dist/evidence-graph-bridge-C_fv9PuC.mjs +135 -0
  73. package/dist/{factory-CibqTNC8.mjs → factory-DxlGh9Xf.mjs} +37 -52
  74. package/dist/graphql-DYWzJ29s.mjs +1026 -0
  75. package/dist/handlers-9sAbfIg-.mjs +2552 -0
  76. package/dist/handlers-Bl8zkwz1.mjs +2716 -0
  77. package/dist/handlers-C67ktuRN.mjs +710 -0
  78. package/dist/handlers-C87g8oCe.mjs +276 -0
  79. package/dist/handlers-CTsDAO6p.mjs +681 -0
  80. package/dist/handlers-Cgyg6c0U.mjs +645 -0
  81. package/dist/handlers-D6j6yka7.mjs +2124 -0
  82. package/dist/handlers-DdFzXLvF.mjs +446 -0
  83. package/dist/handlers-DeLOCd5m.mjs +799 -0
  84. package/dist/handlers-DlCJN4Td.mjs +757 -0
  85. package/dist/handlers-DxGIq15_2.mjs +917 -0
  86. package/dist/handlers-U6L4xhuF.mjs +585 -0
  87. package/dist/handlers-tB9Mp9ZK.mjs +84 -0
  88. package/dist/handlers-tiy7EIBp.mjs +572 -0
  89. package/dist/handlers.impl-DS0d9fUw.mjs +761 -0
  90. package/dist/hooks-CzCWByww.mjs +898 -0
  91. package/dist/index.mjs +384 -155
  92. package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
  93. package/dist/maintenance-P7ePRXQC.mjs +830 -0
  94. package/dist/manifest-2ToTpjv8.mjs +106 -0
  95. package/dist/manifest-3g71z6Bg.mjs +79 -0
  96. package/dist/manifest-82baTv4U.mjs +45 -0
  97. package/dist/manifest-B3QVVeBS.mjs +82 -0
  98. package/dist/manifest-BB2J8IMJ.mjs +149 -0
  99. package/dist/manifest-BKbgbSiY.mjs +60 -0
  100. package/dist/manifest-Bcf-TJzH.mjs +848 -0
  101. package/dist/manifest-BmtZzQiQ2.mjs +45 -0
  102. package/dist/manifest-Bnd7kqEY.mjs +55 -0
  103. package/dist/manifest-BqQX6OQC2.mjs +65 -0
  104. package/dist/manifest-BqrQ4Tpj.mjs +81 -0
  105. package/dist/manifest-Br4RPFt5.mjs +370 -0
  106. package/dist/manifest-C5qDjysN.mjs +107 -0
  107. package/dist/manifest-C9RT5nk32.mjs +34 -0
  108. package/dist/manifest-CAhOuvSl.mjs +204 -0
  109. package/dist/manifest-CBYWCUBJ.mjs +51 -0
  110. package/dist/manifest-CFADCRa1.mjs +37 -0
  111. package/dist/manifest-CQVhavRF.mjs +114 -0
  112. package/dist/manifest-CT7zZBV1.mjs +48 -0
  113. package/dist/manifest-CV12bcrF.mjs +121 -0
  114. package/dist/manifest-CXsRWjjI.mjs +224 -0
  115. package/dist/manifest-CZLUCfG02.mjs +95 -0
  116. package/dist/manifest-D6phHKFd.mjs +131 -0
  117. package/dist/manifest-DCyjf4n2.mjs +294 -0
  118. package/dist/manifest-DHsnKgP6.mjs +60 -0
  119. package/dist/manifest-Df_dliIe.mjs +55 -0
  120. package/dist/manifest-Dh8WBmEW.mjs +129 -0
  121. package/dist/manifest-DhKRAT8_.mjs +92 -0
  122. package/dist/manifest-DlpTj4ic2.mjs +193 -0
  123. package/dist/manifest-DrbmZcFl2.mjs +253 -0
  124. package/dist/manifest-DuwHjUa5.mjs +70 -0
  125. package/dist/manifest-DzwvxPJX.mjs +38 -0
  126. package/dist/manifest-NXctwWQq.mjs +68 -0
  127. package/dist/manifest-Sc_0JQ13.mjs +418 -0
  128. package/dist/manifest-gZ4s_UtG.mjs +96 -0
  129. package/dist/manifest-qSleDqdO.mjs +1023 -0
  130. package/dist/modules-C184v-S9.mjs +11365 -0
  131. package/dist/mojo-ipc-B_H61Afw.mjs +525 -0
  132. package/dist/network-671Cw6hV.mjs +3346 -0
  133. package/dist/{artifacts-BbdOMET5.mjs → outputPaths-B1uGmrWZ.mjs} +219 -212
  134. package/dist/parse-args-BlRjqlkL.mjs +39 -0
  135. package/dist/platform-WmNn8Sxb.mjs +2070 -0
  136. package/dist/process-QcbIy5Zq.mjs +1401 -0
  137. package/dist/proxy-DqNs0bAd.mjs +170 -0
  138. package/dist/registry-D-6e18lB.mjs +34 -0
  139. package/dist/response-BQVP-xUn.mjs +28 -0
  140. package/dist/server/plugin-api.mjs +2 -2
  141. package/dist/shared-state-board-DV-dpHFJ.mjs +586 -0
  142. package/dist/sourcemap-Dq8ez8vS.mjs +650 -0
  143. package/dist/ssrf-policy-ZaUfvhq7.mjs +166 -0
  144. package/dist/streaming-BUQ0VJsg.mjs +725 -0
  145. package/dist/tool-builder-DCbIC5Eo.mjs +186 -0
  146. package/dist/transform-CiYJfNX0.mjs +1007 -0
  147. package/dist/types-Bx92KJfT.mjs +4 -0
  148. package/dist/wasm-DQTnHDs4.mjs +531 -0
  149. package/dist/workflow-f3xJOcjx.mjs +725 -0
  150. package/package.json +48 -78
  151. package/dist/ExtensionManager-DqUSOamB.mjs +0 -2
  152. package/dist/ToolCatalog-CnwmMIw3.mjs +0 -61483
  153. package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-CDe5WPSV.mjs} +0 -0
  154. package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-Bo4T3bz8.mjs} +0 -0
  155. package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-CwVLVdDM.mjs} +0 -0
  156. package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-DVkj9kpI.mjs} +0 -0
  157. package/dist/{types-BBjOqye-.mjs → types-CPhOReNX.mjs} +1 -1
@@ -0,0 +1,1026 @@
1
+ import { et as GRAPHQL_MAX_GRAPH_EDGES, it as GRAPHQL_MAX_SCHEMA_CHARS, nt as GRAPHQL_MAX_PREVIEW_CHARS, rt as GRAPHQL_MAX_QUERY_CHARS, tt as GRAPHQL_MAX_GRAPH_NODES } from "./constants-B0OANIBL.mjs";
2
+ import { a as argString, i as argObject, t as argBool } from "./parse-args-BlRjqlkL.mjs";
3
+ import { s as evaluateWithTimeout } from "./PageController-Bqm2kZ_X.mjs";
4
+ import { c as isSsrfTarget } from "./ssrf-policy-ZaUfvhq7.mjs";
5
+ import "./definitions-Beid2EB3.mjs";
6
+ //#region src/server/domains/graphql/handlers/shared.ts
7
+ function toResponse(payload) {
8
+ return { content: [{
9
+ type: "text",
10
+ text: JSON.stringify(payload, null, 2)
11
+ }] };
12
+ }
13
+ function toError(error, context) {
14
+ const payload = {
15
+ success: false,
16
+ error: getErrorMessage(error)
17
+ };
18
+ if (context) payload.context = context;
19
+ return {
20
+ content: [{
21
+ type: "text",
22
+ text: JSON.stringify(payload, null, 2)
23
+ }],
24
+ isError: true
25
+ };
26
+ }
27
+ function getErrorMessage(error) {
28
+ if (error instanceof Error) return error.message;
29
+ return String(error);
30
+ }
31
+ /**
32
+ * Parse a number argument from args, supporting string-to-number coercion,
33
+ * min/max clamping, and integer truncation.
34
+ * Preserves behavior from the old GraphQLHandlersBase.getNumberArg().
35
+ */
36
+ function parseClampedNumber(args, key, defaultValue, min, max) {
37
+ const value = args[key];
38
+ let parsed = defaultValue;
39
+ if (typeof value === "number" && Number.isFinite(value)) parsed = value;
40
+ else if (typeof value === "string") {
41
+ const fromString = Number(value);
42
+ if (Number.isFinite(fromString)) parsed = fromString;
43
+ }
44
+ if (parsed < min) return min;
45
+ if (parsed > max) return max;
46
+ return Math.trunc(parsed);
47
+ }
48
+ function normalizeHeaders(value) {
49
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
50
+ const dangerousKeys = new Set([
51
+ "__proto__",
52
+ "constructor",
53
+ "prototype"
54
+ ]);
55
+ const headers = Object.create(null);
56
+ for (const [header, rawValue] of Object.entries(value)) {
57
+ if (dangerousKeys.has(header)) continue;
58
+ if (typeof rawValue === "string") headers[header] = rawValue;
59
+ else if (typeof rawValue === "number" || typeof rawValue === "boolean") headers[header] = String(rawValue);
60
+ }
61
+ return headers;
62
+ }
63
+ async function validateExternalEndpoint(endpoint) {
64
+ let parsedEndpoint;
65
+ try {
66
+ parsedEndpoint = new URL(endpoint);
67
+ } catch {
68
+ return `Invalid endpoint URL: ${endpoint}`;
69
+ }
70
+ if (parsedEndpoint.protocol !== "http:" && parsedEndpoint.protocol !== "https:") return `Unsupported endpoint protocol: ${parsedEndpoint.protocol} — only http/https allowed`;
71
+ if (await isSsrfTarget(parsedEndpoint.toString())) return `Blocked: endpoint "${endpoint}" resolves to a private/reserved address`;
72
+ return null;
73
+ }
74
+ function createPreview(text, maxChars) {
75
+ if (text.length <= maxChars) return {
76
+ preview: text,
77
+ truncated: false,
78
+ totalLength: text.length
79
+ };
80
+ return {
81
+ preview: `${text.slice(0, maxChars)}\n... (truncated)`,
82
+ truncated: true,
83
+ totalLength: text.length
84
+ };
85
+ }
86
+ function serializeForPreview(value, maxChars) {
87
+ let serialized;
88
+ if (typeof value === "string") serialized = value;
89
+ else try {
90
+ serialized = JSON.stringify(value, null, 2);
91
+ } catch {
92
+ serialized = String(value);
93
+ }
94
+ return createPreview(serialized, maxChars);
95
+ }
96
+ function parseMatchType(value) {
97
+ if (value === "exact" || value === "contains" || value === "regex") return value;
98
+ return "contains";
99
+ }
100
+ function generateRuleId() {
101
+ return `script_rule_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
102
+ }
103
+ function isRequestInterceptHandled(request) {
104
+ if (typeof request.isInterceptResolutionHandled !== "function") return false;
105
+ try {
106
+ return request.isInterceptResolutionHandled();
107
+ } catch {
108
+ return false;
109
+ }
110
+ }
111
+ async function continueRequest(request) {
112
+ if (isRequestInterceptHandled(request)) return;
113
+ try {
114
+ await request.continue();
115
+ } catch {}
116
+ }
117
+ function ruleMatchesUrl(rule, targetUrl) {
118
+ if (rule.matchType === "exact") return targetUrl === rule.url;
119
+ if (rule.matchType === "contains") return targetUrl.includes(rule.url);
120
+ try {
121
+ return new RegExp(rule.url).test(targetUrl);
122
+ } catch {
123
+ return false;
124
+ }
125
+ }
126
+ function findMatchingRule(rules, url) {
127
+ for (let index = rules.length - 1; index >= 0; index -= 1) {
128
+ const rule = rules[index];
129
+ if (rule && ruleMatchesUrl(rule, url)) return rule;
130
+ }
131
+ return null;
132
+ }
133
+ async function handleInterceptedRequest(rules, request) {
134
+ if (isRequestInterceptHandled(request)) return;
135
+ if (request.resourceType() !== "script") {
136
+ await continueRequest(request);
137
+ return;
138
+ }
139
+ const matchedRule = findMatchingRule(rules, request.url());
140
+ if (!matchedRule) {
141
+ await continueRequest(request);
142
+ return;
143
+ }
144
+ matchedRule.hits += 1;
145
+ try {
146
+ await request.respond({
147
+ status: 200,
148
+ contentType: "application/javascript; charset=utf-8",
149
+ headers: {
150
+ "cache-control": "no-store",
151
+ "x-script-replaced-by": "script_replace_persist"
152
+ },
153
+ body: matchedRule.replacement
154
+ });
155
+ } catch {
156
+ await continueRequest(request);
157
+ }
158
+ }
159
+ async function ensureScriptInterception(rules, installedPages, page) {
160
+ if (installedPages.has(page)) return;
161
+ await page.setRequestInterception(true);
162
+ const listener = (request) => {
163
+ handleInterceptedRequest(rules, request);
164
+ };
165
+ const eventHost = page;
166
+ if (typeof eventHost.prependListener === "function") eventHost.prependListener("request", listener);
167
+ else eventHost.on("request", listener);
168
+ installedPages.add(page);
169
+ }
170
+ //#endregion
171
+ //#region src/server/domains/graphql/handlers.impl.core.runtime.shared.ts
172
+ const INTROSPECTION_QUERY = `
173
+ query IntrospectionQuery {
174
+ __schema {
175
+ queryType { name }
176
+ mutationType { name }
177
+ subscriptionType { name }
178
+ types { ...FullType }
179
+ directives {
180
+ name
181
+ description
182
+ locations
183
+ args(includeDeprecated: true) { ...InputValue }
184
+ }
185
+ }
186
+ }
187
+ fragment FullType on __Type {
188
+ kind
189
+ name
190
+ description
191
+ fields(includeDeprecated: true) {
192
+ name
193
+ description
194
+ args(includeDeprecated: true) { ...InputValue }
195
+ type { ...TypeRef }
196
+ isDeprecated
197
+ deprecationReason
198
+ }
199
+ inputFields(includeDeprecated: true) { ...InputValue }
200
+ interfaces { ...TypeRef }
201
+ enumValues(includeDeprecated: true) {
202
+ name
203
+ description
204
+ isDeprecated
205
+ deprecationReason
206
+ }
207
+ possibleTypes { ...TypeRef }
208
+ }
209
+ fragment InputValue on __InputValue {
210
+ name
211
+ description
212
+ type { ...TypeRef }
213
+ defaultValue
214
+ isDeprecated
215
+ deprecationReason
216
+ }
217
+ fragment TypeRef on __Type {
218
+ kind
219
+ name
220
+ ofType {
221
+ kind
222
+ name
223
+ ofType {
224
+ kind
225
+ name
226
+ ofType {
227
+ kind
228
+ name
229
+ ofType {
230
+ kind
231
+ name
232
+ ofType {
233
+ kind
234
+ name
235
+ ofType {
236
+ kind
237
+ name
238
+ ofType {
239
+ kind
240
+ name
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
247
+ }
248
+ }
249
+ `.trim();
250
+ //#endregion
251
+ //#region src/server/domains/graphql/handlers/callgraph.ts
252
+ var CallGraphHandlers = class {
253
+ constructor(collector) {
254
+ this.collector = collector;
255
+ }
256
+ async handleCallGraphAnalyze(args) {
257
+ try {
258
+ const maxDepth = parseClampedNumber(args, "maxDepth", 5, 1, 20);
259
+ const filterPattern = argString(args, "filterPattern")?.trim() || "";
260
+ if (filterPattern) try {
261
+ RegExp(filterPattern);
262
+ } catch (error) {
263
+ return toError("Invalid filterPattern regex", {
264
+ filterPattern,
265
+ reason: error instanceof Error ? error.message : String(error)
266
+ });
267
+ }
268
+ const result = await evaluateWithTimeout(await this.collector.getActivePage(), ({ maxDepth: depth, filterPattern: filter }) => {
269
+ const globalScope = window;
270
+ const edgeMap = /* @__PURE__ */ new Map();
271
+ const nodeMap = /* @__PURE__ */ new Map();
272
+ let scannedRecords = 0;
273
+ let acceptedRecords = 0;
274
+ const filterRegex = filter ? new RegExp(filter) : null;
275
+ const matchesFilter = (name) => {
276
+ if (!filterRegex) return true;
277
+ filterRegex.lastIndex = 0;
278
+ return filterRegex.test(name);
279
+ };
280
+ const includeEdge = (source, target) => {
281
+ if (!filterRegex) return true;
282
+ return matchesFilter(source) || matchesFilter(target);
283
+ };
284
+ const incrementNode = (name, by = 1) => {
285
+ const existing = nodeMap.get(name);
286
+ if (existing) {
287
+ existing.callCount += by;
288
+ return;
289
+ }
290
+ nodeMap.set(name, {
291
+ id: name,
292
+ name,
293
+ callCount: by
294
+ });
295
+ };
296
+ const addEdge = (sourceRaw, targetRaw) => {
297
+ const source = typeof sourceRaw === "string" ? sourceRaw.trim() || "" : "";
298
+ const target = typeof targetRaw === "string" ? targetRaw.trim() || "" : "";
299
+ if (!source || !target || source === target) return;
300
+ if (!includeEdge(source, target)) return;
301
+ const key = `${source}__->__${target}`;
302
+ const existing = edgeMap.get(key);
303
+ if (existing) existing.count += 1;
304
+ else edgeMap.set(key, {
305
+ source,
306
+ target,
307
+ count: 1
308
+ });
309
+ incrementNode(source, 1);
310
+ incrementNode(target, 1);
311
+ };
312
+ const processRecord = (record, fallbackName) => {
313
+ scannedRecords += 1;
314
+ const calleeRaw = record.callee ?? record.functionName ?? record.fn ?? record.name ?? record.method ?? record.target ?? fallbackName;
315
+ const callee = typeof calleeRaw === "string" ? calleeRaw.trim() || fallbackName : fallbackName;
316
+ const callerRaw = record.caller ?? record.parent ?? record.from ?? "";
317
+ const caller = typeof callerRaw === "string" ? callerRaw.trim() || "" : "";
318
+ let used = false;
319
+ if (caller && callee) {
320
+ addEdge(caller, callee);
321
+ used = true;
322
+ }
323
+ const stackValue = record.stack ?? record.stackTrace ?? record.trace;
324
+ const frames = typeof stackValue === "string" && stackValue.trim().length > 0 ? stackValue.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
325
+ const atMatch = line.match(/at\s+([^(<\s]+)/);
326
+ if (atMatch?.[1]) return atMatch[1];
327
+ const atFileMatch = line.match(/^([^(<\s]+)@/);
328
+ if (atFileMatch?.[1]) return atFileMatch[1];
329
+ return "";
330
+ }).filter((name) => name.length > 0) : [];
331
+ if (frames.length > 1) {
332
+ const depthLimit = Math.min(depth, frames.length - 1);
333
+ for (let index = 0; index < depthLimit; index += 1) addEdge(frames[index + 1], frames[index]);
334
+ used = true;
335
+ } else if (frames.length === 1 && callee && frames[0] !== callee) {
336
+ addEdge(frames[0], callee);
337
+ used = true;
338
+ }
339
+ if (used) acceptedRecords += 1;
340
+ };
341
+ const aiHooks = globalScope.__aiHooks;
342
+ if (aiHooks && typeof aiHooks === "object") for (const [hookName, hookRecords] of Object.entries(aiHooks)) {
343
+ if (!Array.isArray(hookRecords)) continue;
344
+ for (const entry of hookRecords) if (entry && typeof entry === "object") processRecord(entry, hookName);
345
+ }
346
+ for (const key of [
347
+ "__functionTraceRecords",
348
+ "__functionTracerRecords",
349
+ "__functionCalls",
350
+ "__callTrace",
351
+ "__traceCalls"
352
+ ]) {
353
+ const records = globalScope[key];
354
+ if (!Array.isArray(records)) continue;
355
+ for (const entry of records) if (entry && typeof entry === "object") processRecord(entry, key);
356
+ }
357
+ const functionTracer = globalScope.__functionTracer;
358
+ if (functionTracer && typeof functionTracer === "object") {
359
+ const records = functionTracer.records;
360
+ if (Array.isArray(records)) {
361
+ for (const entry of records) if (entry && typeof entry === "object") processRecord(entry, "functionTracer.records");
362
+ }
363
+ }
364
+ const nodes = Array.from(nodeMap.values()).toSorted((left, right) => right.callCount - left.callCount);
365
+ const edges = Array.from(edgeMap.values()).toSorted((left, right) => right.count - left.count);
366
+ return {
367
+ nodes,
368
+ edges,
369
+ stats: {
370
+ scannedRecords,
371
+ acceptedRecords,
372
+ nodeCount: nodes.length,
373
+ edgeCount: edges.length,
374
+ maxDepth: depth,
375
+ filterPattern: filter || null
376
+ }
377
+ };
378
+ }, {
379
+ maxDepth,
380
+ filterPattern
381
+ });
382
+ const nodesTruncated = result.nodes.length > GRAPHQL_MAX_GRAPH_NODES;
383
+ const edgesTruncated = result.edges.length > GRAPHQL_MAX_GRAPH_EDGES;
384
+ return toResponse({
385
+ success: true,
386
+ nodes: result.nodes.slice(0, GRAPHQL_MAX_GRAPH_NODES),
387
+ edges: result.edges.slice(0, GRAPHQL_MAX_GRAPH_EDGES),
388
+ stats: {
389
+ ...result.stats,
390
+ nodesReturned: Math.min(result.nodes.length, GRAPHQL_MAX_GRAPH_NODES),
391
+ edgesReturned: Math.min(result.edges.length, GRAPHQL_MAX_GRAPH_EDGES),
392
+ nodesTruncated,
393
+ edgesTruncated
394
+ }
395
+ });
396
+ } catch (error) {
397
+ return toError(error);
398
+ }
399
+ }
400
+ };
401
+ //#endregion
402
+ //#region src/server/domains/graphql/handlers/script-replace.ts
403
+ var ScriptReplaceHandlers = class {
404
+ scriptReplaceRules = [];
405
+ interceptionInstalledPages = /* @__PURE__ */ new WeakSet();
406
+ constructor(collector) {
407
+ this.collector = collector;
408
+ }
409
+ async handleScriptReplacePersist(args) {
410
+ try {
411
+ const url = argString(args, "url")?.trim();
412
+ const replacement = argString(args, "replacement");
413
+ const matchType = parseMatchType(args.matchType);
414
+ if (!url) return toError("Missing required argument: url");
415
+ if (typeof replacement !== "string" || replacement.length === 0) return toError("Missing required argument: replacement");
416
+ if (matchType === "regex") try {
417
+ RegExp(url);
418
+ } catch (error) {
419
+ return toError("Invalid regex in url for matchType=regex", {
420
+ url,
421
+ reason: getErrorMessage(error)
422
+ });
423
+ }
424
+ const page = await this.collector.getActivePage();
425
+ const rule = {
426
+ id: generateRuleId(),
427
+ url,
428
+ replacement,
429
+ matchType,
430
+ createdAt: Date.now(),
431
+ hits: 0
432
+ };
433
+ this.scriptReplaceRules.push(rule);
434
+ await ensureScriptInterception(this.scriptReplaceRules, this.interceptionInstalledPages, page);
435
+ await page.evaluateOnNewDocument((payload) => {
436
+ const runtimeWindow = window;
437
+ const key = "__scriptReplacePersistRules";
438
+ const filtered = (Array.isArray(runtimeWindow[key]) ? runtimeWindow[key] : []).filter((entry) => entry && entry.id !== payload.id);
439
+ filtered.push(payload);
440
+ runtimeWindow[key] = filtered;
441
+ }, {
442
+ id: rule.id,
443
+ url: rule.url,
444
+ matchType: rule.matchType,
445
+ createdAt: rule.createdAt
446
+ });
447
+ const replacementPreview = createPreview(replacement, GRAPHQL_MAX_PREVIEW_CHARS);
448
+ return toResponse({
449
+ success: true,
450
+ message: "Script replacement rule registered and interception enabled",
451
+ rule: {
452
+ id: rule.id,
453
+ url: rule.url,
454
+ matchType: rule.matchType,
455
+ createdAt: rule.createdAt
456
+ },
457
+ replacement: {
458
+ length: replacement.length,
459
+ preview: replacementPreview.preview,
460
+ truncated: replacementPreview.truncated
461
+ },
462
+ activeRuleCount: this.scriptReplaceRules.length
463
+ });
464
+ } catch (error) {
465
+ return toError(error);
466
+ }
467
+ }
468
+ };
469
+ //#endregion
470
+ //#region src/server/domains/graphql/handlers/introspection.ts
471
+ var IntrospectionHandlers = class {
472
+ constructor(collector) {
473
+ this.collector = collector;
474
+ }
475
+ async handleGraphqlIntrospect(args) {
476
+ try {
477
+ const endpoint = argString(args, "endpoint")?.trim();
478
+ if (!endpoint) return toError("Missing required argument: endpoint");
479
+ const endpointValidationError = await validateExternalEndpoint(endpoint);
480
+ if (endpointValidationError) return toError(endpointValidationError);
481
+ const headers = normalizeHeaders(args.headers);
482
+ if (!argBool(args, "useBrowser", true)) return await this.introspectViaNode(endpoint, headers);
483
+ return await this.introspectViaBrowser(endpoint, headers);
484
+ } catch (error) {
485
+ return toError(error);
486
+ }
487
+ }
488
+ async introspectViaNode(endpoint, headers) {
489
+ const requestHeaders = {
490
+ "content-type": "application/json",
491
+ ...headers
492
+ };
493
+ let response;
494
+ let responseText;
495
+ try {
496
+ const ac = new AbortController();
497
+ const t = setTimeout(() => ac.abort(), 1e4);
498
+ try {
499
+ response = await fetch(endpoint, {
500
+ method: "POST",
501
+ headers: requestHeaders,
502
+ body: JSON.stringify({
503
+ query: INTROSPECTION_QUERY,
504
+ operationName: "IntrospectionQuery"
505
+ }),
506
+ signal: ac.signal
507
+ });
508
+ responseText = await response.text();
509
+ } finally {
510
+ clearTimeout(t);
511
+ }
512
+ } catch (error) {
513
+ return toResponse({
514
+ success: false,
515
+ endpoint,
516
+ status: 0,
517
+ statusText: "FETCH_ERROR",
518
+ error: error instanceof Error ? error.message : String(error)
519
+ });
520
+ }
521
+ const responseHeaders = {};
522
+ response.headers.forEach((value, key) => {
523
+ responseHeaders[key] = value;
524
+ });
525
+ let json = null;
526
+ try {
527
+ json = JSON.parse(responseText);
528
+ } catch {}
529
+ responseText = "";
530
+ if (!response.ok && !json) return toResponse({
531
+ success: false,
532
+ endpoint,
533
+ status: response.status,
534
+ statusText: response.statusText,
535
+ error: "Introspection request failed"
536
+ });
537
+ const jsonRecord = json && typeof json === "object" ? json : null;
538
+ const schemaPayload = jsonRecord && "data" in jsonRecord ? jsonRecord.data : json;
539
+ const schemaPreviewPayload = json !== null && json !== void 0 && typeof schemaPayload !== "undefined" ? serializeForPreview(schemaPayload, GRAPHQL_MAX_SCHEMA_CHARS) : {
540
+ preview: "",
541
+ truncated: false,
542
+ totalLength: 0
543
+ };
544
+ const payload = {
545
+ success: response.ok,
546
+ endpoint,
547
+ status: response.status,
548
+ statusText: response.statusText,
549
+ schemaLength: schemaPreviewPayload.totalLength,
550
+ schemaPreview: schemaPreviewPayload.preview,
551
+ schemaTruncated: schemaPreviewPayload.truncated,
552
+ responseHeaders
553
+ };
554
+ if (!schemaPreviewPayload.truncated) payload.schema = schemaPayload;
555
+ if (jsonRecord && Array.isArray(jsonRecord.errors)) payload.errors = jsonRecord.errors;
556
+ return toResponse(payload);
557
+ }
558
+ async introspectViaBrowser(endpoint, headers) {
559
+ const browserResult = await evaluateWithTimeout(await this.collector.getActivePage(), async (input) => {
560
+ const requestHeaders = {
561
+ "content-type": "application/json",
562
+ ...input.headers
563
+ };
564
+ try {
565
+ const ac = new AbortController();
566
+ const t = setTimeout(() => ac.abort(), 1e4);
567
+ let responseText;
568
+ let response;
569
+ try {
570
+ response = await fetch(input.endpoint, {
571
+ method: "POST",
572
+ headers: requestHeaders,
573
+ body: JSON.stringify({
574
+ query: input.query,
575
+ operationName: "IntrospectionQuery"
576
+ }),
577
+ signal: ac.signal
578
+ });
579
+ responseText = await response.text();
580
+ } finally {
581
+ clearTimeout(t);
582
+ }
583
+ const responseHeaders = {};
584
+ response.headers.forEach((value, key) => {
585
+ responseHeaders[key] = value;
586
+ });
587
+ const totalLength = responseText.length;
588
+ let json = null;
589
+ try {
590
+ json = JSON.parse(responseText);
591
+ } catch {}
592
+ const preview = json === null ? responseText : "";
593
+ responseText = "";
594
+ return {
595
+ ok: response.ok,
596
+ status: response.status,
597
+ statusText: response.statusText,
598
+ responseHeaders,
599
+ totalLength,
600
+ preview,
601
+ truncated: false,
602
+ json
603
+ };
604
+ } catch (error) {
605
+ return {
606
+ ok: false,
607
+ status: 0,
608
+ statusText: "FETCH_ERROR",
609
+ responseHeaders: {},
610
+ totalLength: 0,
611
+ preview: "",
612
+ truncated: false,
613
+ json: null,
614
+ error: error instanceof Error ? error.message : String(error)
615
+ };
616
+ }
617
+ }, {
618
+ endpoint,
619
+ headers,
620
+ query: INTROSPECTION_QUERY,
621
+ maxSchemaChars: GRAPHQL_MAX_SCHEMA_CHARS
622
+ });
623
+ if (!browserResult.ok && !browserResult.json) return toResponse({
624
+ success: false,
625
+ endpoint,
626
+ status: browserResult.status,
627
+ statusText: browserResult.statusText,
628
+ error: browserResult.error ?? "Introspection request failed",
629
+ responsePreview: createPreview(browserResult.preview || "", GRAPHQL_MAX_PREVIEW_CHARS)
630
+ });
631
+ const jsonRecord = browserResult.json && typeof browserResult.json === "object" ? browserResult.json : null;
632
+ const schemaPayload = jsonRecord && "data" in jsonRecord ? jsonRecord.data : browserResult.json;
633
+ const schemaPreviewPayload = browserResult.json !== null && browserResult.json !== void 0 && typeof schemaPayload !== "undefined" ? serializeForPreview(schemaPayload, GRAPHQL_MAX_SCHEMA_CHARS) : {
634
+ preview: browserResult.preview ?? "",
635
+ truncated: browserResult.truncated ?? false,
636
+ totalLength: browserResult.totalLength ?? 0
637
+ };
638
+ const payload = {
639
+ success: browserResult.ok,
640
+ endpoint,
641
+ status: browserResult.status,
642
+ statusText: browserResult.statusText,
643
+ schemaLength: schemaPreviewPayload.totalLength,
644
+ schemaPreview: schemaPreviewPayload.preview,
645
+ schemaTruncated: schemaPreviewPayload.truncated,
646
+ responseHeaders: browserResult.responseHeaders ?? {}
647
+ };
648
+ if (!schemaPreviewPayload.truncated) payload.schema = schemaPayload;
649
+ if (jsonRecord && Array.isArray(jsonRecord.errors)) payload.errors = jsonRecord.errors;
650
+ if (browserResult.error) payload.error = browserResult.error;
651
+ return toResponse(payload);
652
+ }
653
+ };
654
+ //#endregion
655
+ //#region src/server/domains/graphql/handlers/extract.ts
656
+ var ExtractHandlers = class {
657
+ constructor(collector) {
658
+ this.collector = collector;
659
+ }
660
+ async handleGraphqlExtractQueries(args) {
661
+ try {
662
+ const limit = parseClampedNumber(args, "limit", 50, 1, 200);
663
+ const extraction = await evaluateWithTimeout(await this.collector.getActivePage(), (maxItems) => {
664
+ const globalScope = window;
665
+ const extracted = [];
666
+ let scannedRecords = 0;
667
+ const pushIfGraphQL = (payload, metadata) => {
668
+ if (!payload) return;
669
+ const queryRaw = payload.query;
670
+ if (typeof queryRaw !== "string" || queryRaw.trim().length === 0) return;
671
+ const operationNameRaw = payload.operationName;
672
+ const operationName = typeof operationNameRaw === "string" && operationNameRaw.trim().length > 0 ? operationNameRaw : queryRaw.match(/^\s*(query|mutation|subscription)\s+([A-Za-z0-9_]+)/)?.[2] ?? null;
673
+ extracted.push({
674
+ source: metadata.source,
675
+ url: metadata.url,
676
+ method: metadata.method,
677
+ operationName,
678
+ query: queryRaw,
679
+ variables: payload.variables ?? null,
680
+ timestamp: metadata.timestamp,
681
+ contentType: metadata.contentType
682
+ });
683
+ };
684
+ const parseStringBody = (trimmed) => {
685
+ if (!trimmed) return null;
686
+ try {
687
+ const parsed = JSON.parse(trimmed);
688
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
689
+ } catch {}
690
+ if (trimmed.includes("query=")) try {
691
+ const params = new URLSearchParams(trimmed);
692
+ const query = params.get("query");
693
+ if (query) {
694
+ const operationName = params.get("operationName");
695
+ const variablesRaw = params.get("variables");
696
+ let variables = null;
697
+ if (variablesRaw) try {
698
+ variables = JSON.parse(variablesRaw);
699
+ } catch {
700
+ variables = variablesRaw;
701
+ }
702
+ return {
703
+ query,
704
+ operationName,
705
+ variables
706
+ };
707
+ }
708
+ } catch {}
709
+ if (trimmed.startsWith("query ") || trimmed.startsWith("mutation ") || trimmed.startsWith("subscription ")) return { query: trimmed };
710
+ return null;
711
+ };
712
+ const processRequestRecord = (record, source) => {
713
+ scannedRecords += 1;
714
+ const url = typeof record.url === "string" ? record.url : "";
715
+ const method = typeof record.method === "string" ? record.method : "POST";
716
+ const timestamp = typeof record.timestamp === "number" ? record.timestamp : null;
717
+ const headers = (record.headers && typeof record.headers === "object" && !Array.isArray(record.headers) ? record.headers : null) ?? (record.requestHeaders && typeof record.requestHeaders === "object" && !Array.isArray(record.requestHeaders) ? record.requestHeaders : null) ?? {};
718
+ let contentType = "";
719
+ for (const [key, value] of Object.entries(headers)) if (key.toLowerCase() === "content-type") {
720
+ contentType = typeof value === "string" ? value : String(value);
721
+ break;
722
+ }
723
+ contentType = contentType.toLowerCase();
724
+ const bodyCandidates = [record.body, record.postData];
725
+ if (record.options && typeof record.options === "object" && !Array.isArray(record.options)) bodyCandidates.push(record.options.body);
726
+ for (const bodyCandidate of bodyCandidates) {
727
+ let payload = null;
728
+ if (bodyCandidate && typeof bodyCandidate === "object" && !Array.isArray(bodyCandidate)) payload = bodyCandidate;
729
+ else if (typeof bodyCandidate === "string") payload = parseStringBody(bodyCandidate);
730
+ pushIfGraphQL(payload, {
731
+ source,
732
+ url,
733
+ method,
734
+ timestamp,
735
+ contentType
736
+ });
737
+ }
738
+ if (contentType.includes("application/graphql") && typeof record.body === "string") pushIfGraphQL({
739
+ query: record.body,
740
+ variables: null,
741
+ operationName: null
742
+ }, {
743
+ source,
744
+ url,
745
+ method,
746
+ timestamp,
747
+ contentType
748
+ });
749
+ };
750
+ const processArray = (value, source) => {
751
+ if (!Array.isArray(value)) return;
752
+ for (const item of value) if (item && typeof item === "object") processRequestRecord(item, source);
753
+ };
754
+ processArray(globalScope.__fetchRequests, "window.__fetchRequests");
755
+ processArray(globalScope.__xhrRequests, "window.__xhrRequests");
756
+ processArray(globalScope.__networkRequests, "window.__networkRequests");
757
+ const aiHooks = globalScope.__aiHooks;
758
+ if (aiHooks && typeof aiHooks === "object") for (const [hookName, hookRecords] of Object.entries(aiHooks)) {
759
+ if (!Array.isArray(hookRecords)) continue;
760
+ for (const entry of hookRecords) if (entry && typeof entry === "object") processRequestRecord(entry, `window.__aiHooks.${hookName}`);
761
+ }
762
+ extracted.sort((left, right) => (right.timestamp ?? 0) - (left.timestamp ?? 0));
763
+ const deduped = [];
764
+ const seen = /* @__PURE__ */ new Set();
765
+ for (const item of extracted) {
766
+ const key = `${item.url}|${item.operationName ?? ""}|${item.query}|${JSON.stringify(item.variables)}`;
767
+ if (!seen.has(key)) {
768
+ seen.add(key);
769
+ deduped.push(item);
770
+ }
771
+ }
772
+ return {
773
+ scannedRecords,
774
+ totalExtracted: deduped.length,
775
+ extracted: deduped.slice(0, maxItems)
776
+ };
777
+ }, limit);
778
+ const queries = extraction.extracted.map((item, index) => {
779
+ const queryPreview = createPreview(item.query, GRAPHQL_MAX_QUERY_CHARS);
780
+ const variablesPreview = serializeForPreview(item.variables, GRAPHQL_MAX_PREVIEW_CHARS);
781
+ const normalized = {
782
+ index,
783
+ source: item.source,
784
+ url: item.url,
785
+ method: item.method,
786
+ operationName: item.operationName,
787
+ contentType: item.contentType,
788
+ timestamp: item.timestamp,
789
+ queryLength: item.query.length,
790
+ queryPreview: queryPreview.preview,
791
+ queryTruncated: queryPreview.truncated
792
+ };
793
+ if (!queryPreview.truncated) normalized.query = item.query;
794
+ if (!variablesPreview.truncated) normalized.variables = item.variables;
795
+ else {
796
+ normalized.variablesPreview = variablesPreview.preview;
797
+ normalized.variablesTruncated = true;
798
+ }
799
+ return normalized;
800
+ });
801
+ return toResponse({
802
+ success: true,
803
+ limit,
804
+ stats: {
805
+ scannedRecords: extraction.scannedRecords,
806
+ totalExtracted: extraction.totalExtracted,
807
+ returned: queries.length
808
+ },
809
+ queries
810
+ });
811
+ } catch (error) {
812
+ return toError(error);
813
+ }
814
+ }
815
+ };
816
+ //#endregion
817
+ //#region src/server/domains/graphql/handlers/replay.ts
818
+ var ReplayHandlers = class {
819
+ constructor(collector) {
820
+ this.collector = collector;
821
+ }
822
+ async handleGraphqlReplay(args) {
823
+ try {
824
+ const endpoint = argString(args, "endpoint")?.trim();
825
+ const query = argString(args, "query");
826
+ if (!endpoint) return toError("Missing required argument: endpoint");
827
+ if (typeof query !== "string" || query.trim().length === 0) return toError("Missing required argument: query");
828
+ const endpointValidationError = await validateExternalEndpoint(endpoint);
829
+ if (endpointValidationError) return toError(endpointValidationError);
830
+ const variables = argObject(args, "variables") ?? {};
831
+ const operationNameRaw = argString(args, "operationName");
832
+ const operationName = operationNameRaw && operationNameRaw.trim().length > 0 ? operationNameRaw.trim() : null;
833
+ const headers = normalizeHeaders(args.headers);
834
+ if (!argBool(args, "useBrowser", true)) return await this.replayViaNode(endpoint, query, variables, operationName, headers);
835
+ return await this.replayViaBrowser(endpoint, query, variables, operationName, headers);
836
+ } catch (error) {
837
+ return toError(error);
838
+ }
839
+ }
840
+ async replayViaNode(endpoint, query, variables, operationName, headers) {
841
+ const requestHeaders = {
842
+ "content-type": "application/json",
843
+ ...headers
844
+ };
845
+ let response;
846
+ let responseText;
847
+ try {
848
+ const ac = new AbortController();
849
+ const t = setTimeout(() => ac.abort(), 1e4);
850
+ try {
851
+ response = await fetch(endpoint, {
852
+ method: "POST",
853
+ headers: requestHeaders,
854
+ body: JSON.stringify({
855
+ query,
856
+ variables,
857
+ operationName
858
+ }),
859
+ signal: ac.signal
860
+ });
861
+ responseText = await response.text();
862
+ } finally {
863
+ clearTimeout(t);
864
+ }
865
+ } catch (error) {
866
+ return toResponse({
867
+ success: false,
868
+ endpoint,
869
+ status: 0,
870
+ statusText: "FETCH_ERROR",
871
+ error: error instanceof Error ? error.message : String(error),
872
+ operationName
873
+ });
874
+ }
875
+ const responseHeaders = {};
876
+ response.headers.forEach((value, key) => {
877
+ responseHeaders[key] = value;
878
+ });
879
+ let responseJson = null;
880
+ try {
881
+ responseJson = JSON.parse(responseText);
882
+ } catch {
883
+ responseJson = null;
884
+ }
885
+ responseText = "";
886
+ return toResponse(buildReplayPayloadFromJson(responseJson, endpoint, operationName, response.ok, response.status, response.statusText, responseHeaders));
887
+ }
888
+ async replayViaBrowser(endpoint, query, variables, operationName, headers) {
889
+ const browserResult = await evaluateWithTimeout(await this.collector.getActivePage(), async (input) => {
890
+ const requestHeaders = {
891
+ "content-type": "application/json",
892
+ ...input.headers
893
+ };
894
+ try {
895
+ const ac = new AbortController();
896
+ const t = setTimeout(() => ac.abort(), 1e4);
897
+ let responseText;
898
+ let response;
899
+ try {
900
+ response = await fetch(input.endpoint, {
901
+ method: "POST",
902
+ headers: requestHeaders,
903
+ body: JSON.stringify({
904
+ query: input.query,
905
+ variables: input.variables,
906
+ operationName: input.operationName
907
+ }),
908
+ signal: ac.signal
909
+ });
910
+ responseText = await response.text();
911
+ } finally {
912
+ clearTimeout(t);
913
+ }
914
+ let responseJson = null;
915
+ try {
916
+ responseJson = JSON.parse(responseText);
917
+ } catch {
918
+ responseJson = null;
919
+ }
920
+ const rawText = responseJson === null ? responseText : "";
921
+ responseText = "";
922
+ const responseHeaders = {};
923
+ response.headers.forEach((value, key) => {
924
+ responseHeaders[key] = value;
925
+ });
926
+ return {
927
+ ok: response.ok,
928
+ status: response.status,
929
+ statusText: response.statusText,
930
+ responseText: rawText,
931
+ responseJson,
932
+ responseHeaders
933
+ };
934
+ } catch (error) {
935
+ return {
936
+ ok: false,
937
+ status: 0,
938
+ statusText: "FETCH_ERROR",
939
+ responseText: "",
940
+ responseJson: null,
941
+ error: error instanceof Error ? error.message : String(error)
942
+ };
943
+ }
944
+ }, {
945
+ endpoint,
946
+ query,
947
+ variables,
948
+ operationName,
949
+ headers
950
+ });
951
+ const payload = {
952
+ success: browserResult.ok,
953
+ endpoint,
954
+ status: browserResult.status,
955
+ statusText: browserResult.statusText,
956
+ operationName,
957
+ responseHeaders: browserResult.responseHeaders ?? {}
958
+ };
959
+ if (browserResult.responseJson !== null) {
960
+ const responsePreview = serializeForPreview(browserResult.responseJson, GRAPHQL_MAX_SCHEMA_CHARS);
961
+ payload.responseLength = responsePreview.totalLength;
962
+ payload.responsePreview = responsePreview.preview;
963
+ payload.responseTruncated = responsePreview.truncated;
964
+ if (!responsePreview.truncated) payload.response = browserResult.responseJson;
965
+ } else if (browserResult.responseText) {
966
+ const text = browserResult.responseText;
967
+ payload.responseFormat = "text";
968
+ payload.responseLength = text.length;
969
+ payload.responsePreview = text.length > GRAPHQL_MAX_SCHEMA_CHARS ? text.slice(0, GRAPHQL_MAX_SCHEMA_CHARS) : text;
970
+ payload.responseTruncated = text.length > GRAPHQL_MAX_SCHEMA_CHARS;
971
+ }
972
+ if (browserResult.error) payload.error = browserResult.error;
973
+ return toResponse(payload);
974
+ }
975
+ };
976
+ function buildReplayPayloadFromJson(responseJson, endpoint, operationName, ok, status, statusText, responseHeaders) {
977
+ const payload = {
978
+ success: ok,
979
+ endpoint,
980
+ status,
981
+ statusText,
982
+ operationName,
983
+ responseHeaders
984
+ };
985
+ if (responseJson !== null) {
986
+ const responsePreview = serializeForPreview(responseJson, GRAPHQL_MAX_SCHEMA_CHARS);
987
+ payload.responseLength = responsePreview.totalLength;
988
+ payload.responsePreview = responsePreview.preview;
989
+ payload.responseTruncated = responsePreview.truncated;
990
+ if (!responsePreview.truncated) payload.response = responseJson;
991
+ }
992
+ return payload;
993
+ }
994
+ //#endregion
995
+ //#region src/server/domains/graphql/handlers.impl.ts
996
+ var GraphQLToolHandlers = class {
997
+ callGraph;
998
+ scriptReplace;
999
+ introspection;
1000
+ extract;
1001
+ replay;
1002
+ constructor(collector) {
1003
+ this.callGraph = new CallGraphHandlers(collector);
1004
+ this.scriptReplace = new ScriptReplaceHandlers(collector);
1005
+ this.introspection = new IntrospectionHandlers(collector);
1006
+ this.extract = new ExtractHandlers(collector);
1007
+ this.replay = new ReplayHandlers(collector);
1008
+ }
1009
+ async handleCallGraphAnalyze(args) {
1010
+ return this.callGraph.handleCallGraphAnalyze(args);
1011
+ }
1012
+ async handleScriptReplacePersist(args) {
1013
+ return this.scriptReplace.handleScriptReplacePersist(args);
1014
+ }
1015
+ async handleGraphqlIntrospect(args) {
1016
+ return this.introspection.handleGraphqlIntrospect(args);
1017
+ }
1018
+ async handleGraphqlExtractQueries(args) {
1019
+ return this.extract.handleGraphqlExtractQueries(args);
1020
+ }
1021
+ async handleGraphqlReplay(args) {
1022
+ return this.replay.handleGraphqlReplay(args);
1023
+ }
1024
+ };
1025
+ //#endregion
1026
+ export { GraphQLToolHandlers };