htpx-cli 0.1.2 → 0.2.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.
Files changed (252) hide show
  1. package/LICENSE +665 -21
  2. package/README.md +422 -116
  3. package/dist/cli/commands/clear.d.ts.map +1 -1
  4. package/dist/cli/commands/clear.js +11 -11
  5. package/dist/cli/commands/clear.js.map +1 -1
  6. package/dist/cli/commands/daemon.d.ts +3 -0
  7. package/dist/cli/commands/daemon.d.ts.map +1 -0
  8. package/dist/cli/commands/daemon.js +59 -0
  9. package/dist/cli/commands/daemon.js.map +1 -0
  10. package/dist/cli/commands/debug-dump.d.ts.map +1 -1
  11. package/dist/cli/commands/debug-dump.js +8 -10
  12. package/dist/cli/commands/debug-dump.js.map +1 -1
  13. package/dist/cli/commands/helpers.d.ts +18 -0
  14. package/dist/cli/commands/helpers.d.ts.map +1 -0
  15. package/dist/cli/commands/helpers.js +34 -0
  16. package/dist/cli/commands/helpers.js.map +1 -0
  17. package/dist/cli/commands/init.d.ts +1 -1
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +3 -4
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/intercept.d.ts +2 -1
  22. package/dist/cli/commands/intercept.d.ts.map +1 -1
  23. package/dist/cli/commands/intercept.js +74 -30
  24. package/dist/cli/commands/intercept.js.map +1 -1
  25. package/dist/cli/commands/interceptors.d.ts +3 -0
  26. package/dist/cli/commands/interceptors.d.ts.map +1 -0
  27. package/dist/cli/commands/interceptors.js +163 -0
  28. package/dist/cli/commands/interceptors.js.map +1 -0
  29. package/dist/cli/commands/mcp.d.ts +3 -0
  30. package/dist/cli/commands/mcp.d.ts.map +1 -0
  31. package/dist/cli/commands/mcp.js +24 -0
  32. package/dist/cli/commands/mcp.js.map +1 -0
  33. package/dist/cli/commands/off.d.ts +8 -0
  34. package/dist/cli/commands/off.d.ts.map +1 -0
  35. package/dist/cli/commands/off.js +34 -0
  36. package/dist/cli/commands/off.js.map +1 -0
  37. package/dist/cli/commands/on.d.ts +9 -0
  38. package/dist/cli/commands/on.d.ts.map +1 -0
  39. package/dist/cli/commands/on.js +121 -0
  40. package/dist/cli/commands/on.js.map +1 -0
  41. package/dist/cli/commands/project.d.ts.map +1 -1
  42. package/dist/cli/commands/project.js +5 -3
  43. package/dist/cli/commands/project.js.map +1 -1
  44. package/dist/cli/commands/restart.d.ts.map +1 -1
  45. package/dist/cli/commands/restart.js +5 -10
  46. package/dist/cli/commands/restart.js.map +1 -1
  47. package/dist/cli/commands/status.d.ts.map +1 -1
  48. package/dist/cli/commands/status.js +50 -20
  49. package/dist/cli/commands/status.js.map +1 -1
  50. package/dist/cli/commands/stop.d.ts.map +1 -1
  51. package/dist/cli/commands/stop.js +7 -10
  52. package/dist/cli/commands/stop.js.map +1 -1
  53. package/dist/cli/commands/tui.d.ts.map +1 -1
  54. package/dist/cli/commands/tui.js +6 -13
  55. package/dist/cli/commands/tui.js.map +1 -1
  56. package/dist/cli/index.js +12 -7
  57. package/dist/cli/index.js.map +1 -1
  58. package/dist/cli/tui/App.d.ts +7 -2
  59. package/dist/cli/tui/App.d.ts.map +1 -1
  60. package/dist/cli/tui/App.js +490 -33
  61. package/dist/cli/tui/App.js.map +1 -1
  62. package/dist/cli/tui/components/AccordionContent.d.ts +28 -0
  63. package/dist/cli/tui/components/AccordionContent.d.ts.map +1 -0
  64. package/dist/cli/tui/components/AccordionContent.js +87 -0
  65. package/dist/cli/tui/components/AccordionContent.js.map +1 -0
  66. package/dist/cli/tui/components/AccordionPanel.d.ts +38 -0
  67. package/dist/cli/tui/components/AccordionPanel.d.ts.map +1 -0
  68. package/dist/cli/tui/components/AccordionPanel.js +110 -0
  69. package/dist/cli/tui/components/AccordionPanel.js.map +1 -0
  70. package/dist/cli/tui/components/AccordionSection.d.ts +32 -0
  71. package/dist/cli/tui/components/AccordionSection.d.ts.map +1 -0
  72. package/dist/cli/tui/components/AccordionSection.js +41 -0
  73. package/dist/cli/tui/components/AccordionSection.js.map +1 -0
  74. package/dist/cli/tui/components/ExportModal.d.ts +34 -0
  75. package/dist/cli/tui/components/ExportModal.d.ts.map +1 -0
  76. package/dist/cli/tui/components/ExportModal.js +109 -0
  77. package/dist/cli/tui/components/ExportModal.js.map +1 -0
  78. package/dist/cli/tui/components/FilterBar.d.ts +21 -0
  79. package/dist/cli/tui/components/FilterBar.d.ts.map +1 -0
  80. package/dist/cli/tui/components/FilterBar.js +155 -0
  81. package/dist/cli/tui/components/FilterBar.js.map +1 -0
  82. package/dist/cli/tui/components/HelpModal.d.ts +13 -0
  83. package/dist/cli/tui/components/HelpModal.d.ts.map +1 -0
  84. package/dist/cli/tui/components/HelpModal.js +78 -0
  85. package/dist/cli/tui/components/HelpModal.js.map +1 -0
  86. package/dist/cli/tui/components/HintContent.d.ts +25 -0
  87. package/dist/cli/tui/components/HintContent.d.ts.map +1 -0
  88. package/dist/cli/tui/components/HintContent.js +44 -0
  89. package/dist/cli/tui/components/HintContent.js.map +1 -0
  90. package/dist/cli/tui/components/InfoModal.d.ts +15 -0
  91. package/dist/cli/tui/components/InfoModal.d.ts.map +1 -0
  92. package/dist/cli/tui/components/InfoModal.js +17 -0
  93. package/dist/cli/tui/components/InfoModal.js.map +1 -0
  94. package/dist/cli/tui/components/JsonExplorerModal.d.ts +24 -0
  95. package/dist/cli/tui/components/JsonExplorerModal.d.ts.map +1 -0
  96. package/dist/cli/tui/components/JsonExplorerModal.js +311 -0
  97. package/dist/cli/tui/components/JsonExplorerModal.js.map +1 -0
  98. package/dist/cli/tui/components/Modal.d.ts +26 -0
  99. package/dist/cli/tui/components/Modal.d.ts.map +1 -0
  100. package/dist/cli/tui/components/Modal.js +15 -0
  101. package/dist/cli/tui/components/Modal.js.map +1 -0
  102. package/dist/cli/tui/components/Panel.d.ts +19 -0
  103. package/dist/cli/tui/components/Panel.d.ts.map +1 -0
  104. package/dist/cli/tui/components/Panel.js +37 -0
  105. package/dist/cli/tui/components/Panel.js.map +1 -0
  106. package/dist/cli/tui/components/RequestDetails.d.ts +4 -1
  107. package/dist/cli/tui/components/RequestDetails.d.ts.map +1 -1
  108. package/dist/cli/tui/components/RequestDetails.js +9 -5
  109. package/dist/cli/tui/components/RequestDetails.js.map +1 -1
  110. package/dist/cli/tui/components/RequestList.d.ts +9 -3
  111. package/dist/cli/tui/components/RequestList.d.ts.map +1 -1
  112. package/dist/cli/tui/components/RequestList.js +24 -11
  113. package/dist/cli/tui/components/RequestList.js.map +1 -1
  114. package/dist/cli/tui/components/RequestListItem.d.ts +26 -3
  115. package/dist/cli/tui/components/RequestListItem.d.ts.map +1 -1
  116. package/dist/cli/tui/components/RequestListItem.js +86 -9
  117. package/dist/cli/tui/components/RequestListItem.js.map +1 -1
  118. package/dist/cli/tui/components/SaveModal.d.ts +30 -0
  119. package/dist/cli/tui/components/SaveModal.d.ts.map +1 -0
  120. package/dist/cli/tui/components/SaveModal.js +95 -0
  121. package/dist/cli/tui/components/SaveModal.js.map +1 -0
  122. package/dist/cli/tui/components/StatusBar.d.ts +31 -2
  123. package/dist/cli/tui/components/StatusBar.d.ts.map +1 -1
  124. package/dist/cli/tui/components/StatusBar.js +44 -9
  125. package/dist/cli/tui/components/StatusBar.js.map +1 -1
  126. package/dist/cli/tui/components/TextViewerModal.d.ts +19 -0
  127. package/dist/cli/tui/components/TextViewerModal.d.ts.map +1 -0
  128. package/dist/cli/tui/components/TextViewerModal.js +227 -0
  129. package/dist/cli/tui/components/TextViewerModal.js.map +1 -0
  130. package/dist/cli/tui/hooks/useBodyExport.d.ts +26 -0
  131. package/dist/cli/tui/hooks/useBodyExport.d.ts.map +1 -0
  132. package/dist/cli/tui/hooks/useBodyExport.js +173 -0
  133. package/dist/cli/tui/hooks/useBodyExport.js.map +1 -0
  134. package/dist/cli/tui/hooks/useExport.d.ts +13 -2
  135. package/dist/cli/tui/hooks/useExport.d.ts.map +1 -1
  136. package/dist/cli/tui/hooks/useExport.js +46 -40
  137. package/dist/cli/tui/hooks/useExport.js.map +1 -1
  138. package/dist/cli/tui/hooks/useRequests.d.ts +9 -3
  139. package/dist/cli/tui/hooks/useRequests.d.ts.map +1 -1
  140. package/dist/cli/tui/hooks/useRequests.js +61 -15
  141. package/dist/cli/tui/hooks/useRequests.js.map +1 -1
  142. package/dist/cli/tui/hooks/useSaveBinary.d.ts +26 -0
  143. package/dist/cli/tui/hooks/useSaveBinary.d.ts.map +1 -0
  144. package/dist/cli/tui/hooks/useSaveBinary.js +165 -0
  145. package/dist/cli/tui/hooks/useSaveBinary.js.map +1 -0
  146. package/dist/cli/tui/hooks/useSpinner.d.ts +5 -0
  147. package/dist/cli/tui/hooks/useSpinner.d.ts.map +1 -0
  148. package/dist/cli/tui/hooks/useSpinner.js +25 -0
  149. package/dist/cli/tui/hooks/useSpinner.js.map +1 -0
  150. package/dist/cli/tui/utils/binary.d.ts +24 -0
  151. package/dist/cli/tui/utils/binary.d.ts.map +1 -0
  152. package/dist/cli/tui/utils/binary.js +152 -0
  153. package/dist/cli/tui/utils/binary.js.map +1 -0
  154. package/dist/cli/tui/utils/clipboard.d.ts +9 -0
  155. package/dist/cli/tui/utils/clipboard.d.ts.map +1 -0
  156. package/dist/cli/tui/utils/clipboard.js +58 -0
  157. package/dist/cli/tui/utils/clipboard.js.map +1 -0
  158. package/dist/cli/tui/utils/content-type.d.ts +8 -0
  159. package/dist/cli/tui/utils/content-type.d.ts.map +1 -0
  160. package/dist/cli/tui/utils/content-type.js +10 -0
  161. package/dist/cli/tui/utils/content-type.js.map +1 -0
  162. package/dist/cli/tui/utils/curl.d.ts.map +1 -1
  163. package/dist/cli/tui/utils/curl.js +9 -2
  164. package/dist/cli/tui/utils/curl.js.map +1 -1
  165. package/dist/cli/tui/utils/filters.d.ts +6 -0
  166. package/dist/cli/tui/utils/filters.d.ts.map +1 -0
  167. package/dist/cli/tui/utils/filters.js +13 -0
  168. package/dist/cli/tui/utils/filters.js.map +1 -0
  169. package/dist/cli/tui/utils/formatters.d.ts +8 -0
  170. package/dist/cli/tui/utils/formatters.d.ts.map +1 -1
  171. package/dist/cli/tui/utils/formatters.js +85 -0
  172. package/dist/cli/tui/utils/formatters.js.map +1 -1
  173. package/dist/cli/tui/utils/har.d.ts.map +1 -1
  174. package/dist/cli/tui/utils/har.js +3 -25
  175. package/dist/cli/tui/utils/har.js.map +1 -1
  176. package/dist/cli/tui/utils/json-tree.d.ts +69 -0
  177. package/dist/cli/tui/utils/json-tree.d.ts.map +1 -0
  178. package/dist/cli/tui/utils/json-tree.js +339 -0
  179. package/dist/cli/tui/utils/json-tree.js.map +1 -0
  180. package/dist/cli/tui/utils/open-external.d.ts +17 -0
  181. package/dist/cli/tui/utils/open-external.d.ts.map +1 -0
  182. package/dist/cli/tui/utils/open-external.js +57 -0
  183. package/dist/cli/tui/utils/open-external.js.map +1 -0
  184. package/dist/cli/tui/utils/syntax-highlight.d.ts +16 -0
  185. package/dist/cli/tui/utils/syntax-highlight.d.ts.map +1 -0
  186. package/dist/cli/tui/utils/syntax-highlight.js +64 -0
  187. package/dist/cli/tui/utils/syntax-highlight.js.map +1 -0
  188. package/dist/daemon/control.d.ts +3 -49
  189. package/dist/daemon/control.d.ts.map +1 -1
  190. package/dist/daemon/control.js +183 -141
  191. package/dist/daemon/control.js.map +1 -1
  192. package/dist/daemon/htpx-client.d.ts +8 -0
  193. package/dist/daemon/htpx-client.d.ts.map +1 -0
  194. package/dist/daemon/htpx-client.js +25 -0
  195. package/dist/daemon/htpx-client.js.map +1 -0
  196. package/dist/daemon/index.js +50 -2
  197. package/dist/daemon/index.js.map +1 -1
  198. package/dist/daemon/interceptor-loader.d.ts +30 -0
  199. package/dist/daemon/interceptor-loader.d.ts.map +1 -0
  200. package/dist/daemon/interceptor-loader.js +249 -0
  201. package/dist/daemon/interceptor-loader.js.map +1 -0
  202. package/dist/daemon/interceptor-runner.d.ts +39 -0
  203. package/dist/daemon/interceptor-runner.d.ts.map +1 -0
  204. package/dist/daemon/interceptor-runner.js +312 -0
  205. package/dist/daemon/interceptor-runner.js.map +1 -0
  206. package/dist/daemon/proxy.d.ts +12 -0
  207. package/dist/daemon/proxy.d.ts.map +1 -1
  208. package/dist/daemon/proxy.js +121 -10
  209. package/dist/daemon/proxy.js.map +1 -1
  210. package/dist/daemon/storage.d.ts +64 -2
  211. package/dist/daemon/storage.d.ts.map +1 -1
  212. package/dist/daemon/storage.js +527 -12
  213. package/dist/daemon/storage.js.map +1 -1
  214. package/dist/interceptors.d.ts +2 -0
  215. package/dist/interceptors.d.ts.map +1 -0
  216. package/dist/interceptors.js +2 -0
  217. package/dist/interceptors.js.map +1 -0
  218. package/dist/mcp/server.d.ts +110 -0
  219. package/dist/mcp/server.d.ts.map +1 -0
  220. package/dist/mcp/server.js +806 -0
  221. package/dist/mcp/server.js.map +1 -0
  222. package/dist/shared/config.d.ts +21 -0
  223. package/dist/shared/config.d.ts.map +1 -0
  224. package/dist/shared/config.js +83 -0
  225. package/dist/shared/config.js.map +1 -0
  226. package/dist/shared/content-type.d.ts +64 -0
  227. package/dist/shared/content-type.d.ts.map +1 -0
  228. package/dist/shared/content-type.js +145 -0
  229. package/dist/shared/content-type.js.map +1 -0
  230. package/dist/shared/control-client.d.ts +144 -0
  231. package/dist/shared/control-client.d.ts.map +1 -0
  232. package/dist/shared/control-client.js +272 -0
  233. package/dist/shared/control-client.js.map +1 -0
  234. package/dist/shared/daemon.d.ts.map +1 -1
  235. package/dist/shared/daemon.js +17 -4
  236. package/dist/shared/daemon.js.map +1 -1
  237. package/dist/shared/logger.d.ts +21 -5
  238. package/dist/shared/logger.d.ts.map +1 -1
  239. package/dist/shared/logger.js +100 -21
  240. package/dist/shared/logger.js.map +1 -1
  241. package/dist/shared/project.d.ts +16 -3
  242. package/dist/shared/project.d.ts.map +1 -1
  243. package/dist/shared/project.js +45 -5
  244. package/dist/shared/project.js.map +1 -1
  245. package/dist/shared/proxy-info.d.ts +10 -0
  246. package/dist/shared/proxy-info.d.ts.map +1 -0
  247. package/dist/shared/proxy-info.js +15 -0
  248. package/dist/shared/proxy-info.js.map +1 -0
  249. package/dist/shared/types.d.ts +95 -0
  250. package/dist/shared/types.d.ts.map +1 -1
  251. package/package.json +24 -5
  252. package/skills/htpx/SKILL.md +228 -0
@@ -1,5 +1,9 @@
1
+ import type { Headers } from "mockttp";
1
2
  import type { RequestRepository } from "./storage.js";
3
+ import type { InterceptorRunner } from "./interceptor-runner.js";
2
4
  import { type LogLevel } from "../shared/logger.js";
5
+ /** Default maximum body size to capture (10MB) */
6
+ export declare const DEFAULT_MAX_BODY_SIZE: number;
3
7
  export interface ProxyOptions {
4
8
  port?: number;
5
9
  caKeyPath: string;
@@ -9,6 +13,10 @@ export interface ProxyOptions {
9
13
  label?: string;
10
14
  projectRoot?: string;
11
15
  logLevel?: LogLevel;
16
+ /** Maximum body size to capture in bytes. Bodies larger than this are not stored but still proxied. */
17
+ maxBodySize?: number;
18
+ /** Interceptor runner for mock/modify/observe interceptors */
19
+ interceptorRunner?: InterceptorRunner;
12
20
  }
13
21
  export interface ProxyServer {
14
22
  port: number;
@@ -19,4 +27,8 @@ export interface ProxyServer {
19
27
  * Create and start a MITM proxy server that captures all HTTP/HTTPS traffic.
20
28
  */
21
29
  export declare function createProxy(options: ProxyOptions): Promise<ProxyServer>;
30
+ /**
31
+ * Flatten mockttp headers (which may have array values) to simple string values.
32
+ */
33
+ export declare function flattenHeaders(headers: Headers): Record<string, string>;
22
34
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/daemon/proxy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAelE,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAoG7E"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/daemon/proxy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmC,OAAO,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAelE,kDAAkD;AAClD,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uGAAuG;IACvG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuP7E;AAkBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYvE"}
@@ -1,14 +1,17 @@
1
1
  import * as mockttp from "mockttp";
2
2
  import { createLogger } from "../shared/logger.js";
3
+ /** Default maximum body size to capture (10MB) */
4
+ export const DEFAULT_MAX_BODY_SIZE = 10 * 1024 * 1024;
3
5
  /**
4
6
  * Create and start a MITM proxy server that captures all HTTP/HTTPS traffic.
5
7
  */
6
8
  export async function createProxy(options) {
7
- const { storage, sessionId, label, projectRoot, logLevel } = options;
9
+ const { storage, sessionId, label, projectRoot, logLevel, interceptorRunner } = options;
8
10
  // Create logger if projectRoot is provided
9
11
  const logger = projectRoot ? createLogger("proxy", projectRoot, logLevel) : undefined;
10
12
  // Map to track request info for response correlation
11
13
  const requestInfo = new Map();
14
+ const maxBodySize = options.maxBodySize ?? DEFAULT_MAX_BODY_SIZE;
12
15
  const server = mockttp.getLocal({
13
16
  https: {
14
17
  keyPath: options.caKeyPath,
@@ -16,22 +19,45 @@ export async function createProxy(options) {
16
19
  },
17
20
  // Record traffic for potential debugging
18
21
  recordTraffic: false,
22
+ // Limit body capture to prevent memory bloat from large files
23
+ maxBodySize,
19
24
  });
20
25
  await server.start(options.port);
21
26
  // Set up passthrough rule that captures all traffic
27
+ // Clean up requestInfo entries for requests that are aborted before completion
28
+ await server.on("abort", (req) => {
29
+ const info = requestInfo.get(req.id);
30
+ if (info && interceptorRunner) {
31
+ interceptorRunner.cleanup(info.ourId);
32
+ }
33
+ requestInfo.delete(req.id);
34
+ });
22
35
  await server.forAnyRequest().thenPassThrough({
23
36
  // Ignore certificate errors when connecting to upstream servers
24
37
  ignoreHostHttpsErrors: true,
25
- beforeRequest: (request) => {
38
+ beforeRequest: async (request) => {
26
39
  const timestamp = Date.now();
27
40
  // Parse URL to extract host and path
28
41
  const url = new URL(request.url);
29
42
  // Convert headers to simple object
30
43
  const headers = flattenHeaders(request.headers);
44
+ // Detect if body was truncated due to maxBodySize
45
+ // Body is truncated if we got an empty buffer but Content-Length indicates data
46
+ const contentLength = parseInt(headers["content-length"] ?? "0", 10);
47
+ const requestBodyTruncated = request.body.buffer.length === 0 && contentLength > 0;
48
+ // Decode compressed request body (gzip, br, deflate) for storage.
49
+ // The actual request to the upstream server is unmodified.
50
+ const decodedBody = request.body.buffer.length > 0
51
+ ? ((await request.body.getDecodedBuffer()) ?? request.body.buffer)
52
+ : undefined;
53
+ // Strip content-encoding from stored headers since we store the decoded body
54
+ const storedHeaders = { ...headers };
55
+ delete storedHeaders["content-encoding"];
31
56
  logger?.trace("Request received", {
32
57
  method: request.method,
33
58
  url: request.url,
34
- headers,
59
+ headers: storedHeaders,
60
+ bodyTruncated: requestBodyTruncated,
35
61
  });
36
62
  // Save request to storage and track the ID
37
63
  const ourId = storage.saveRequest({
@@ -42,15 +68,49 @@ export async function createProxy(options) {
42
68
  url: request.url,
43
69
  host: url.host,
44
70
  path: url.pathname + url.search,
45
- requestHeaders: headers,
46
- requestBody: request.body.buffer.length > 0 ? request.body.buffer : undefined,
71
+ requestHeaders: storedHeaders,
72
+ requestBody: decodedBody,
73
+ requestBodyTruncated,
47
74
  });
48
75
  // Store mapping from mockttp ID to our ID and timestamp
49
- requestInfo.set(request.id, { ourId, timestamp });
76
+ requestInfo.set(request.id, { ourId, timestamp, requestBodyTruncated });
77
+ // Run interceptor if available
78
+ if (interceptorRunner) {
79
+ const interceptorRequest = {
80
+ method: request.method,
81
+ url: request.url,
82
+ host: url.host,
83
+ path: url.pathname + url.search,
84
+ headers: { ...storedHeaders },
85
+ body: decodedBody,
86
+ };
87
+ const result = await interceptorRunner.handleRequest(ourId, interceptorRequest);
88
+ if (result?.mockResponse && result.interception) {
89
+ // Mock — interceptor returned a response without calling forward()
90
+ storage.updateRequestInterception(ourId, result.interception.name, result.interception.type);
91
+ const mockBody = typeof result.mockResponse.body === "string"
92
+ ? Buffer.from(result.mockResponse.body)
93
+ : result.mockResponse.body;
94
+ storage.updateRequestResponse(ourId, {
95
+ status: result.mockResponse.status,
96
+ headers: result.mockResponse.headers ?? {},
97
+ body: mockBody,
98
+ durationMs: Date.now() - timestamp,
99
+ responseBodyTruncated: false,
100
+ });
101
+ return {
102
+ response: buildMockttpResponse(result.mockResponse),
103
+ };
104
+ }
105
+ if (result?.interception) {
106
+ // forward() was called — record interception metadata, let proxy continue
107
+ storage.updateRequestInterception(ourId, result.interception.name, result.interception.type);
108
+ }
109
+ }
50
110
  // Return undefined to pass through without modification
51
111
  return undefined;
52
112
  },
53
- beforeResponse: (response, request) => {
113
+ beforeResponse: async (response, request) => {
54
114
  const info = requestInfo.get(request.id);
55
115
  requestInfo.delete(request.id);
56
116
  if (!info) {
@@ -60,17 +120,58 @@ export async function createProxy(options) {
60
120
  const durationMs = Date.now() - info.timestamp;
61
121
  // Convert headers to simple object
62
122
  const headers = flattenHeaders(response.headers);
123
+ // Detect if body was truncated due to maxBodySize
124
+ const contentLength = parseInt(headers["content-length"] ?? "0", 10);
125
+ const responseBodyTruncated = response.body.buffer.length === 0 && contentLength > 0;
126
+ // Decode compressed body (gzip, br, deflate) for storage.
127
+ // The actual response to the client is unmodified.
128
+ const decodedBody = response.body.buffer.length > 0
129
+ ? ((await response.body.getDecodedBuffer()) ?? response.body.buffer)
130
+ : undefined;
131
+ // Strip content-encoding from stored headers since we store the decoded body
132
+ const storedHeaders = { ...headers };
133
+ delete storedHeaders["content-encoding"];
63
134
  logger?.trace("Response sent", {
64
135
  status: response.statusCode,
65
136
  durationMs,
66
137
  url: request.url,
138
+ bodyTruncated: responseBodyTruncated,
67
139
  });
140
+ // Run interceptor response handler if available
141
+ if (interceptorRunner) {
142
+ const upstreamResponse = {
143
+ status: response.statusCode,
144
+ headers: { ...storedHeaders },
145
+ body: decodedBody,
146
+ };
147
+ const interceptResult = await interceptorRunner.handleResponse(info.ourId, upstreamResponse);
148
+ if (interceptResult?.responseOverride && interceptResult.interception) {
149
+ // Handler modified the response after forward()
150
+ storage.updateRequestInterception(info.ourId, interceptResult.interception.name, interceptResult.interception.type);
151
+ const overrideBody = typeof interceptResult.responseOverride.body === "string"
152
+ ? Buffer.from(interceptResult.responseOverride.body)
153
+ : interceptResult.responseOverride.body;
154
+ storage.updateRequestResponse(info.ourId, {
155
+ status: interceptResult.responseOverride.status,
156
+ headers: interceptResult.responseOverride.headers ?? storedHeaders,
157
+ body: overrideBody,
158
+ durationMs,
159
+ responseBodyTruncated: false,
160
+ });
161
+ return buildMockttpResponse(interceptResult.responseOverride);
162
+ }
163
+ if (interceptResult?.interception) {
164
+ // Observe mode — record interception metadata but don't modify response
165
+ storage.updateRequestInterception(info.ourId, interceptResult.interception.name, interceptResult.interception.type);
166
+ }
167
+ }
68
168
  // Update request with response data using our ID
69
169
  storage.updateRequestResponse(info.ourId, {
70
170
  status: response.statusCode,
71
- headers,
72
- body: response.body.buffer.length > 0 ? response.body.buffer : undefined,
171
+ headers: storedHeaders,
172
+ body: decodedBody,
73
173
  durationMs,
174
+ responseBodyTruncated,
74
175
  });
75
176
  // Return undefined to pass through without modification
76
177
  return undefined;
@@ -84,10 +185,20 @@ export async function createProxy(options) {
84
185
  },
85
186
  };
86
187
  }
188
+ /**
189
+ * Convert an InterceptorResponse into the shape mockttp expects for mock/modified responses.
190
+ */
191
+ function buildMockttpResponse(response) {
192
+ return {
193
+ statusCode: response.status,
194
+ headers: response.headers,
195
+ body: response.body,
196
+ };
197
+ }
87
198
  /**
88
199
  * Flatten mockttp headers (which may have array values) to simple string values.
89
200
  */
90
- function flattenHeaders(headers) {
201
+ export function flattenHeaders(headers) {
91
202
  const result = {};
92
203
  for (const [key, value] of Object.entries(headers)) {
93
204
  if (Array.isArray(value)) {
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/daemon/proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/daemon/proxy.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,18 @@
1
- import type { CapturedRequest, Session } from "../shared/types.js";
1
+ import type { CapturedRequest, CapturedRequestSummary, InterceptionType, JsonQueryResult, RequestFilter, Session } from "../shared/types.js";
2
2
  import { type LogLevel } from "../shared/logger.js";
3
+ export interface RepositoryOptions {
4
+ maxStoredRequests?: number;
5
+ }
3
6
  export declare class RequestRepository {
4
7
  private db;
5
8
  private logger;
6
- constructor(dbPath: string, projectRoot?: string, logLevel?: LogLevel);
9
+ private maxStoredRequests;
10
+ private insertsSinceLastEvictionCheck;
11
+ constructor(dbPath: string, projectRoot?: string, logLevel?: LogLevel, options?: RepositoryOptions);
12
+ /**
13
+ * Apply pending database migrations using SQLite's user_version pragma for tracking.
14
+ */
15
+ private applyMigrations;
7
16
  /**
8
17
  * Register a new session.
9
18
  */
@@ -34,7 +43,12 @@ export declare class RequestRepository {
34
43
  headers: Record<string, string>;
35
44
  body?: Buffer;
36
45
  durationMs: number;
46
+ responseBodyTruncated?: boolean;
37
47
  }): void;
48
+ /**
49
+ * Update a request with interceptor metadata.
50
+ */
51
+ updateRequestInterception(id: string, interceptedBy: string, interceptionType: InterceptionType): void;
38
52
  /**
39
53
  * Get a request by ID.
40
54
  */
@@ -47,22 +61,70 @@ export declare class RequestRepository {
47
61
  label?: string;
48
62
  limit?: number;
49
63
  offset?: number;
64
+ filter?: RequestFilter;
50
65
  }): CapturedRequest[];
66
+ /**
67
+ * List request summaries (excludes body/header data for performance).
68
+ * Use this for list views where full request data isn't needed.
69
+ */
70
+ listRequestsSummary(options?: {
71
+ sessionId?: string;
72
+ label?: string;
73
+ limit?: number;
74
+ offset?: number;
75
+ filter?: RequestFilter;
76
+ }): CapturedRequestSummary[];
51
77
  /**
52
78
  * Count requests, optionally filtered by session or label.
53
79
  */
54
80
  countRequests(options?: {
55
81
  sessionId?: string;
56
82
  label?: string;
83
+ filter?: RequestFilter;
57
84
  }): number;
85
+ /**
86
+ * Search through request/response body content for a text pattern.
87
+ * Only searches text-based bodies (not binary).
88
+ */
89
+ searchBodies(options: {
90
+ query: string;
91
+ limit?: number;
92
+ offset?: number;
93
+ filter?: RequestFilter;
94
+ }): CapturedRequestSummary[];
95
+ /**
96
+ * Query JSON bodies using SQLite's json_extract.
97
+ * Only queries rows with JSON content types.
98
+ */
99
+ queryJsonBodies(options: {
100
+ jsonPath: string;
101
+ value?: string;
102
+ target?: "request" | "response" | "both";
103
+ limit?: number;
104
+ offset?: number;
105
+ filter?: RequestFilter;
106
+ }): JsonQueryResult[];
58
107
  /**
59
108
  * Delete all requests (useful for cleanup).
60
109
  */
61
110
  clearRequests(): void;
111
+ /**
112
+ * Reclaim disk space by checkpointing the WAL and vacuuming.
113
+ * Intended for use during shutdown — not suitable for the hot path.
114
+ */
115
+ compactDatabase(): void;
62
116
  /**
63
117
  * Close the database connection.
64
118
  */
65
119
  close(): void;
120
+ /**
121
+ * Check whether the request count exceeds the cap and evict oldest rows.
122
+ * Only runs the actual COUNT query every EVICTION_CHECK_INTERVAL inserts
123
+ * to keep the hot path cheap.
124
+ */
125
+ private evictIfNeeded;
126
+ private rowToSummary;
127
+ private safeParseHeaders;
66
128
  private rowToRequest;
67
129
  }
68
130
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/daemon/storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAgB,KAAK,QAAQ,EAAe,MAAM,qBAAqB,CAAC;AAkC/E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAUrE;;OAEG;IACH,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO;IAkBnE;;;;OAIG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO;IAkB7E;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAuB3C;;OAEG;IACH,YAAY,IAAI,OAAO,EAAE;IAsBzB;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,GAAG,MAAM;IAuCzD;;OAEG;IACH,qBAAqB,CACnB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,GACA,IAAI;IAgBP;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAUnD;;OAEG;IACH,YAAY,CACV,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GACpF,eAAe,EAAE;IAgCpB;;OAEG;IACH,aAAa,CAAC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,MAAM;IAyB3E;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,YAAY;CAsBrB"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/daemon/storage.ts"],"names":[],"mappings":"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"}