@jonathanleelx/meddle 0.0.1

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 (361) hide show
  1. package/CONFIG_STRUCTURE.md +315 -0
  2. package/LICENSE +21 -0
  3. package/README.md +298 -0
  4. package/bin/commands/mock/add.js +92 -0
  5. package/bin/commands/mock/delete.js +58 -0
  6. package/bin/commands/mock/index.js +50 -0
  7. package/bin/commands/mock/list.js +68 -0
  8. package/bin/commands/mock/toggle.js +64 -0
  9. package/bin/commands/mock/update.js +94 -0
  10. package/bin/commands/route/active.js +141 -0
  11. package/bin/commands/route/add.js +127 -0
  12. package/bin/commands/route/create.js +77 -0
  13. package/bin/commands/route/delete.js +120 -0
  14. package/bin/commands/route/index.js +59 -0
  15. package/bin/commands/route/list.js +67 -0
  16. package/bin/commands/route/preview.js +159 -0
  17. package/bin/commands/route/show.js +111 -0
  18. package/bin/commands/route/update.js +126 -0
  19. package/bin/commands/session/create.js +166 -0
  20. package/bin/commands/session/delete.js +69 -0
  21. package/bin/commands/session/index.js +61 -0
  22. package/bin/commands/session/list.js +42 -0
  23. package/bin/commands/session/prune.js +31 -0
  24. package/bin/commands/start.js +43 -0
  25. package/bin/commands/status.js +115 -0
  26. package/bin/commands/supervise.js +106 -0
  27. package/bin/commands/url.js +30 -0
  28. package/bin/doctor.js +356 -0
  29. package/bin/index +130 -0
  30. package/bin/lib/api-client.js +72 -0
  31. package/bin/lib/file-access.js +337 -0
  32. package/bin/lib/meddle-home.js +20 -0
  33. package/bin/lib/output.js +146 -0
  34. package/bin/lib/parsers.js +127 -0
  35. package/bin/lib/proxy-detect.js +105 -0
  36. package/bin/lib/route-preview.js +180 -0
  37. package/bin/lib/session-args.js +54 -0
  38. package/bin/lib/sessions.js +213 -0
  39. package/dist/cert.d.ts +10 -0
  40. package/dist/cert.d.ts.map +1 -0
  41. package/dist/cert.js +184 -0
  42. package/dist/cert.js.map +1 -0
  43. package/dist/core/application-identity.d.ts +55 -0
  44. package/dist/core/application-identity.d.ts.map +1 -0
  45. package/dist/core/application-identity.js +321 -0
  46. package/dist/core/application-identity.js.map +1 -0
  47. package/dist/core/body-utils.d.ts +2 -0
  48. package/dist/core/body-utils.d.ts.map +1 -0
  49. package/dist/core/body-utils.js +21 -0
  50. package/dist/core/body-utils.js.map +1 -0
  51. package/dist/core/browser.d.ts +2 -0
  52. package/dist/core/browser.d.ts.map +1 -0
  53. package/dist/core/browser.js +92 -0
  54. package/dist/core/browser.js.map +1 -0
  55. package/dist/core/client-identity.d.ts +27 -0
  56. package/dist/core/client-identity.d.ts.map +1 -0
  57. package/dist/core/client-identity.js +136 -0
  58. package/dist/core/client-identity.js.map +1 -0
  59. package/dist/core/config-diagnostics.d.ts +14 -0
  60. package/dist/core/config-diagnostics.d.ts.map +1 -0
  61. package/dist/core/config-diagnostics.js +137 -0
  62. package/dist/core/config-diagnostics.js.map +1 -0
  63. package/dist/core/connect-tunnel.d.ts +5 -0
  64. package/dist/core/connect-tunnel.d.ts.map +1 -0
  65. package/dist/core/connect-tunnel.js +45 -0
  66. package/dist/core/connect-tunnel.js.map +1 -0
  67. package/dist/core/content-encoding.d.ts +2 -0
  68. package/dist/core/content-encoding.d.ts.map +1 -0
  69. package/dist/core/content-encoding.js +77 -0
  70. package/dist/core/content-encoding.js.map +1 -0
  71. package/dist/core/custom-plugin-loader.d.ts +18 -0
  72. package/dist/core/custom-plugin-loader.d.ts.map +1 -0
  73. package/dist/core/custom-plugin-loader.js +178 -0
  74. package/dist/core/custom-plugin-loader.js.map +1 -0
  75. package/dist/core/h2-pool.d.ts +4 -0
  76. package/dist/core/h2-pool.d.ts.map +1 -0
  77. package/dist/core/h2-pool.js +180 -0
  78. package/dist/core/h2-pool.js.map +1 -0
  79. package/dist/core/inspection-dispatch.d.ts +5 -0
  80. package/dist/core/inspection-dispatch.d.ts.map +1 -0
  81. package/dist/core/inspection-dispatch.js +146 -0
  82. package/dist/core/inspection-dispatch.js.map +1 -0
  83. package/dist/core/log-rate-limit.d.ts +34 -0
  84. package/dist/core/log-rate-limit.d.ts.map +1 -0
  85. package/dist/core/log-rate-limit.js +52 -0
  86. package/dist/core/log-rate-limit.js.map +1 -0
  87. package/dist/core/map-local.d.ts +4 -0
  88. package/dist/core/map-local.d.ts.map +1 -0
  89. package/dist/core/map-local.js +195 -0
  90. package/dist/core/map-local.js.map +1 -0
  91. package/dist/core/meddle-home.d.ts +13 -0
  92. package/dist/core/meddle-home.d.ts.map +1 -0
  93. package/dist/core/meddle-home.js +56 -0
  94. package/dist/core/meddle-home.js.map +1 -0
  95. package/dist/core/mock-gate.d.ts +3 -0
  96. package/dist/core/mock-gate.d.ts.map +1 -0
  97. package/dist/core/mock-gate.js +20 -0
  98. package/dist/core/mock-gate.js.map +1 -0
  99. package/dist/core/mock-handler.d.ts +5 -0
  100. package/dist/core/mock-handler.d.ts.map +1 -0
  101. package/dist/core/mock-handler.js +339 -0
  102. package/dist/core/mock-handler.js.map +1 -0
  103. package/dist/core/on-mode-gate.d.ts +4 -0
  104. package/dist/core/on-mode-gate.d.ts.map +1 -0
  105. package/dist/core/on-mode-gate.js +64 -0
  106. package/dist/core/on-mode-gate.js.map +1 -0
  107. package/dist/core/pipeline-gate.d.ts +3 -0
  108. package/dist/core/pipeline-gate.d.ts.map +1 -0
  109. package/dist/core/pipeline-gate.js +34 -0
  110. package/dist/core/pipeline-gate.js.map +1 -0
  111. package/dist/core/pipeline.d.ts +6 -0
  112. package/dist/core/pipeline.d.ts.map +1 -0
  113. package/dist/core/pipeline.js +228 -0
  114. package/dist/core/pipeline.js.map +1 -0
  115. package/dist/core/plugin-bootstrap-runner.d.ts +6 -0
  116. package/dist/core/plugin-bootstrap-runner.d.ts.map +1 -0
  117. package/dist/core/plugin-bootstrap-runner.js +148 -0
  118. package/dist/core/plugin-bootstrap-runner.js.map +1 -0
  119. package/dist/core/plugin-bootstrap.d.ts +3 -0
  120. package/dist/core/plugin-bootstrap.d.ts.map +1 -0
  121. package/dist/core/plugin-bootstrap.js +15 -0
  122. package/dist/core/plugin-bootstrap.js.map +1 -0
  123. package/dist/core/plugin-compiler.d.ts +37 -0
  124. package/dist/core/plugin-compiler.d.ts.map +1 -0
  125. package/dist/core/plugin-compiler.js +172 -0
  126. package/dist/core/plugin-compiler.js.map +1 -0
  127. package/dist/core/plugin-context-factory.d.ts +29 -0
  128. package/dist/core/plugin-context-factory.d.ts.map +1 -0
  129. package/dist/core/plugin-context-factory.js +206 -0
  130. package/dist/core/plugin-context-factory.js.map +1 -0
  131. package/dist/core/plugin-generator.d.ts +47 -0
  132. package/dist/core/plugin-generator.d.ts.map +1 -0
  133. package/dist/core/plugin-generator.js +697 -0
  134. package/dist/core/plugin-generator.js.map +1 -0
  135. package/dist/core/plugin-health.d.ts +3 -0
  136. package/dist/core/plugin-health.d.ts.map +1 -0
  137. package/dist/core/plugin-health.js +54 -0
  138. package/dist/core/plugin-health.js.map +1 -0
  139. package/dist/core/plugin-intercept.d.ts +17 -0
  140. package/dist/core/plugin-intercept.d.ts.map +1 -0
  141. package/dist/core/plugin-intercept.js +133 -0
  142. package/dist/core/plugin-intercept.js.map +1 -0
  143. package/dist/core/plugin-runtime.d.ts +33 -0
  144. package/dist/core/plugin-runtime.d.ts.map +1 -0
  145. package/dist/core/plugin-runtime.js +254 -0
  146. package/dist/core/plugin-runtime.js.map +1 -0
  147. package/dist/core/proxy-context.d.ts +3 -0
  148. package/dist/core/proxy-context.d.ts.map +1 -0
  149. package/dist/core/proxy-context.js +129 -0
  150. package/dist/core/proxy-context.js.map +1 -0
  151. package/dist/core/proxy-record.d.ts +3 -0
  152. package/dist/core/proxy-record.d.ts.map +1 -0
  153. package/dist/core/proxy-record.js +32 -0
  154. package/dist/core/proxy-record.js.map +1 -0
  155. package/dist/core/refactor-config.d.ts +6 -0
  156. package/dist/core/refactor-config.d.ts.map +1 -0
  157. package/dist/core/refactor-config.js +45 -0
  158. package/dist/core/refactor-config.js.map +1 -0
  159. package/dist/core/refactor-status.d.ts +3 -0
  160. package/dist/core/refactor-status.d.ts.map +1 -0
  161. package/dist/core/refactor-status.js +19 -0
  162. package/dist/core/refactor-status.js.map +1 -0
  163. package/dist/core/remote-access.d.ts +40 -0
  164. package/dist/core/remote-access.d.ts.map +1 -0
  165. package/dist/core/remote-access.js +281 -0
  166. package/dist/core/remote-access.js.map +1 -0
  167. package/dist/core/route-decision.d.ts +3 -0
  168. package/dist/core/route-decision.d.ts.map +1 -0
  169. package/dist/core/route-decision.js +20 -0
  170. package/dist/core/route-decision.js.map +1 -0
  171. package/dist/core/route-loader.d.ts +14 -0
  172. package/dist/core/route-loader.d.ts.map +1 -0
  173. package/dist/core/route-loader.js +94 -0
  174. package/dist/core/route-loader.js.map +1 -0
  175. package/dist/core/route-preview.d.ts +15 -0
  176. package/dist/core/route-preview.d.ts.map +1 -0
  177. package/dist/core/route-preview.js +91 -0
  178. package/dist/core/route-preview.js.map +1 -0
  179. package/dist/core/runtime-health.d.ts +92 -0
  180. package/dist/core/runtime-health.d.ts.map +1 -0
  181. package/dist/core/runtime-health.js +205 -0
  182. package/dist/core/runtime-health.js.map +1 -0
  183. package/dist/core/sessions.d.ts +19 -0
  184. package/dist/core/sessions.d.ts.map +1 -0
  185. package/dist/core/sessions.js +93 -0
  186. package/dist/core/sessions.js.map +1 -0
  187. package/dist/core/shadow-compare.d.ts +8 -0
  188. package/dist/core/shadow-compare.d.ts.map +1 -0
  189. package/dist/core/shadow-compare.js +83 -0
  190. package/dist/core/shadow-compare.js.map +1 -0
  191. package/dist/core/shadow-readiness.d.ts +4 -0
  192. package/dist/core/shadow-readiness.d.ts.map +1 -0
  193. package/dist/core/shadow-readiness.js +118 -0
  194. package/dist/core/shadow-readiness.js.map +1 -0
  195. package/dist/core/short-response.d.ts +5 -0
  196. package/dist/core/short-response.d.ts.map +1 -0
  197. package/dist/core/short-response.js +18 -0
  198. package/dist/core/short-response.js.map +1 -0
  199. package/dist/core/static-server.d.ts +9 -0
  200. package/dist/core/static-server.d.ts.map +1 -0
  201. package/dist/core/static-server.js +136 -0
  202. package/dist/core/static-server.js.map +1 -0
  203. package/dist/core/types.d.ts +590 -0
  204. package/dist/core/types.d.ts.map +1 -0
  205. package/dist/core/types.js +4 -0
  206. package/dist/core/types.js.map +1 -0
  207. package/dist/helpers.d.ts +36 -0
  208. package/dist/helpers.d.ts.map +1 -0
  209. package/dist/helpers.js +290 -0
  210. package/dist/helpers.js.map +1 -0
  211. package/dist/plugins/builtin/index.d.ts +3 -0
  212. package/dist/plugins/builtin/index.d.ts.map +1 -0
  213. package/dist/plugins/builtin/index.js +23 -0
  214. package/dist/plugins/builtin/index.js.map +1 -0
  215. package/dist/plugins/builtin/logger-plugin.d.ts +8 -0
  216. package/dist/plugins/builtin/logger-plugin.d.ts.map +1 -0
  217. package/dist/plugins/builtin/logger-plugin.js +121 -0
  218. package/dist/plugins/builtin/logger-plugin.js.map +1 -0
  219. package/dist/plugins/builtin/mock-plugin.d.ts +3 -0
  220. package/dist/plugins/builtin/mock-plugin.d.ts.map +1 -0
  221. package/dist/plugins/builtin/mock-plugin.js +99 -0
  222. package/dist/plugins/builtin/mock-plugin.js.map +1 -0
  223. package/dist/plugins/builtin/router-plugin.d.ts +3 -0
  224. package/dist/plugins/builtin/router-plugin.d.ts.map +1 -0
  225. package/dist/plugins/builtin/router-plugin.js +36 -0
  226. package/dist/plugins/builtin/router-plugin.js.map +1 -0
  227. package/dist/server/agent/model.d.ts +30 -0
  228. package/dist/server/agent/model.d.ts.map +1 -0
  229. package/dist/server/agent/model.js +143 -0
  230. package/dist/server/agent/model.js.map +1 -0
  231. package/dist/server/agent/routes.d.ts +4 -0
  232. package/dist/server/agent/routes.d.ts.map +1 -0
  233. package/dist/server/agent/routes.js +188 -0
  234. package/dist/server/agent/routes.js.map +1 -0
  235. package/dist/server/agent/runtime.d.ts +12 -0
  236. package/dist/server/agent/runtime.d.ts.map +1 -0
  237. package/dist/server/agent/runtime.js +208 -0
  238. package/dist/server/agent/runtime.js.map +1 -0
  239. package/dist/server/agent/tools.d.ts +13 -0
  240. package/dist/server/agent/tools.d.ts.map +1 -0
  241. package/dist/server/agent/tools.js +1201 -0
  242. package/dist/server/agent/tools.js.map +1 -0
  243. package/dist/server/agent/types.d.ts +56 -0
  244. package/dist/server/agent/types.d.ts.map +1 -0
  245. package/dist/server/agent/types.js +3 -0
  246. package/dist/server/agent/types.js.map +1 -0
  247. package/dist/server/config.d.ts +9 -0
  248. package/dist/server/config.d.ts.map +1 -0
  249. package/dist/server/config.js +124 -0
  250. package/dist/server/config.js.map +1 -0
  251. package/dist/server/health.d.ts +4 -0
  252. package/dist/server/health.d.ts.map +1 -0
  253. package/dist/server/health.js +22 -0
  254. package/dist/server/health.js.map +1 -0
  255. package/dist/server/index.d.ts +239 -0
  256. package/dist/server/index.d.ts.map +1 -0
  257. package/dist/server/index.js +44 -0
  258. package/dist/server/index.js.map +1 -0
  259. package/dist/server/logs.d.ts +4 -0
  260. package/dist/server/logs.d.ts.map +1 -0
  261. package/dist/server/logs.js +40 -0
  262. package/dist/server/logs.js.map +1 -0
  263. package/dist/server/mocks.d.ts +9 -0
  264. package/dist/server/mocks.d.ts.map +1 -0
  265. package/dist/server/mocks.js +103 -0
  266. package/dist/server/mocks.js.map +1 -0
  267. package/dist/server/pipeline.d.ts +16 -0
  268. package/dist/server/pipeline.d.ts.map +1 -0
  269. package/dist/server/pipeline.js +159 -0
  270. package/dist/server/pipeline.js.map +1 -0
  271. package/dist/server/plugins.d.ts +32 -0
  272. package/dist/server/plugins.d.ts.map +1 -0
  273. package/dist/server/plugins.js +795 -0
  274. package/dist/server/plugins.js.map +1 -0
  275. package/dist/server/refactor.d.ts +4 -0
  276. package/dist/server/refactor.d.ts.map +1 -0
  277. package/dist/server/refactor.js +86 -0
  278. package/dist/server/refactor.js.map +1 -0
  279. package/dist/server/rule-files.d.ts +34 -0
  280. package/dist/server/rule-files.d.ts.map +1 -0
  281. package/dist/server/rule-files.js +389 -0
  282. package/dist/server/rule-files.js.map +1 -0
  283. package/dist/server/rules.d.ts +4 -0
  284. package/dist/server/rules.d.ts.map +1 -0
  285. package/dist/server/rules.js +40 -0
  286. package/dist/server/rules.js.map +1 -0
  287. package/dist/server/sessions.d.ts +4 -0
  288. package/dist/server/sessions.d.ts.map +1 -0
  289. package/dist/server/sessions.js +20 -0
  290. package/dist/server/sessions.js.map +1 -0
  291. package/index.js +950 -0
  292. package/mcp-server.js +794 -0
  293. package/package.json +92 -0
  294. package/plugins/builtin/index.ts +25 -0
  295. package/plugins/builtin/logger-plugin.ts +126 -0
  296. package/plugins/builtin/mock-plugin.ts +112 -0
  297. package/plugins/builtin/router-plugin.ts +35 -0
  298. package/web/README.md +111 -0
  299. package/web/dist/assets/ai-config-store-DQXVJVn_.js +1 -0
  300. package/web/dist/assets/alert-COF-DIAE.js +1 -0
  301. package/web/dist/assets/arrow-right-B4Mrlj2-.js +1 -0
  302. package/web/dist/assets/babel-DsprIpXZ.js +15 -0
  303. package/web/dist/assets/body-diff-view-D7dCWajG.js +6 -0
  304. package/web/dist/assets/button-BTToMaBW.js +1 -0
  305. package/web/dist/assets/checkbox-DIBarrJx.js +1 -0
  306. package/web/dist/assets/chevron-down-CPngAx4M.js +1 -0
  307. package/web/dist/assets/chevron-right-V1DGIDbL.js +1 -0
  308. package/web/dist/assets/circle-alert-Q8cZk9Rv.js +1 -0
  309. package/web/dist/assets/circle-x-C9USji_R.js +1 -0
  310. package/web/dist/assets/code-5_eJ_XpJ.js +1 -0
  311. package/web/dist/assets/code-fixer-fQtWZ5He.js +20 -0
  312. package/web/dist/assets/copy-BYjq1hdN.js +1 -0
  313. package/web/dist/assets/detail-panel-BX_hxeI0.js +3 -0
  314. package/web/dist/assets/dist-B8XUKgXe.js +1 -0
  315. package/web/dist/assets/dist-Bb9TeEub.js +1 -0
  316. package/web/dist/assets/dist-C5nMErq8.js +1 -0
  317. package/web/dist/assets/dist-C6eaYCUo.js +1 -0
  318. package/web/dist/assets/dist-Cn0y0IRn.js +1 -0
  319. package/web/dist/assets/dist-CxdY_A67.js +5 -0
  320. package/web/dist/assets/dist-D5Dj17P8.js +1 -0
  321. package/web/dist/assets/dist-DZJ9SMlJ.js +1 -0
  322. package/web/dist/assets/es2015-CfXu88Y7.js +41 -0
  323. package/web/dist/assets/estree-BP7k0NIt.js +44 -0
  324. package/web/dist/assets/file-system-access-CtcvBfj4.js +1 -0
  325. package/web/dist/assets/global-panel-shell-ChdO0dWd.js +6 -0
  326. package/web/dist/assets/health-panel-CQeCQ7gr.js +1 -0
  327. package/web/dist/assets/html-6FIWbqxX.js +25 -0
  328. package/web/dist/assets/index-CjqaTnE_.css +2 -0
  329. package/web/dist/assets/index-L7uWxTnp.js +18 -0
  330. package/web/dist/assets/mobile-proxy-panel-Dj1iLami.js +8 -0
  331. package/web/dist/assets/mock-config-BTTCw7RK.js +1 -0
  332. package/web/dist/assets/mock-editor-panel-C-aVfFme.js +1 -0
  333. package/web/dist/assets/monaco-editor-B3brLg8j.js +11 -0
  334. package/web/dist/assets/pencil-line-Cqe41E4h.js +1 -0
  335. package/web/dist/assets/plugin-code-editor-CPjCbJ9g.js +2 -0
  336. package/web/dist/assets/plugin-config-BzmCkvz3.js +1 -0
  337. package/web/dist/assets/plugin-generator-BnEafDF9.js +2 -0
  338. package/web/dist/assets/plugin-test-dialog-BWoWsWV4.js +7 -0
  339. package/web/dist/assets/plus-tVxSydJ8.js +1 -0
  340. package/web/dist/assets/postcss-Dnf30fQU.js +61 -0
  341. package/web/dist/assets/refresh-cw-CG3HaiQT.js +1 -0
  342. package/web/dist/assets/rotate-ccw-CAYM6Vv0.js +1 -0
  343. package/web/dist/assets/route-preview-BX7sfY0O.js +1 -0
  344. package/web/dist/assets/rule-ai-assistant-panel-WBiOOUw5.js +47 -0
  345. package/web/dist/assets/rule-config-CHpVij2M.css +1 -0
  346. package/web/dist/assets/rule-config-fTIZVwg1.js +15 -0
  347. package/web/dist/assets/select-CkFOB61l.js +1 -0
  348. package/web/dist/assets/server-Cpj4KNwN.js +1 -0
  349. package/web/dist/assets/settings-panel-COCYiIUg.js +1 -0
  350. package/web/dist/assets/shield-check-OqUmVLQt.js +1 -0
  351. package/web/dist/assets/smartphone-DKeDuJTU.js +1 -0
  352. package/web/dist/assets/standalone-CjxtLKw-.js +29 -0
  353. package/web/dist/assets/switch-C-Xk56TK.js +1 -0
  354. package/web/dist/assets/syntax-highlight-DVhPdkuV.js +5 -0
  355. package/web/dist/assets/table-CT97lAYq.js +1 -0
  356. package/web/dist/assets/textarea-C6NooVK1.js +1 -0
  357. package/web/dist/assets/wand-sparkles-wkul5vje.js +1 -0
  358. package/web/dist/assets/wifi-D9M35Ajj.js +1 -0
  359. package/web/dist/assets/zap-Djo4cgux.js +1 -0
  360. package/web/dist/index.html +24 -0
  361. package/web/dist/vite.svg +1 -0
@@ -0,0 +1,92 @@
1
+ /**
2
+ * meddle mock add - Add a mock rule
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiPost } = require('../../lib/api-client')
8
+ const { addMockRule } = require('../../lib/file-access')
9
+
10
+ // Parse arguments
11
+ const args = process.argv.slice(3)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ function parseArgs(args) {
16
+ const options = {}
17
+ for (let i = 0; i < args.length; i++) {
18
+ if (args[i] === '--name') options.name = args[++i]
19
+ else if (args[i] === '--pattern') options.urlPattern = args[++i]
20
+ else if (args[i] === '--method') options.method = args[++i]
21
+ else if (args[i] === '--status') options.statusCode = parseInt(args[++i], 10)
22
+ else if (args[i] === '--body') options.body = args[++i]
23
+ else if (args[i] === '--delay') options.delay = parseInt(args[++i], 10)
24
+ else if (args[i] === '--headers') {
25
+ try {
26
+ options.headers = JSON.parse(args[++i])
27
+ } catch (_) {
28
+ options.headers = {}
29
+ }
30
+ }
31
+ }
32
+ return options
33
+ }
34
+
35
+ async function run() {
36
+ const options = parseArgs(args)
37
+
38
+ // Validate required fields
39
+ if (!options.name) {
40
+ output.error('Missing required option: --name')
41
+ process.exit(1)
42
+ }
43
+ if (!options.urlPattern) {
44
+ output.error('Missing required option: --pattern')
45
+ process.exit(1)
46
+ }
47
+
48
+ // Set defaults
49
+ const rule = {
50
+ name: options.name,
51
+ urlPattern: options.urlPattern,
52
+ method: options.method || '*',
53
+ statusCode: options.statusCode || 200,
54
+ delay: options.delay || 0,
55
+ bodyType: 'inline',
56
+ headers: options.headers || {},
57
+ body: options.body || '',
58
+ enabled: true
59
+ }
60
+
61
+ const running = await isProxyRunning()
62
+
63
+ let result
64
+ if (running) {
65
+ try {
66
+ result = await apiPost('/api/mocks', rule)
67
+ result = result.rule || result
68
+ } catch (e) {
69
+ // Fallback to file mode
70
+ result = addMockRule(rule)
71
+ }
72
+ } else {
73
+ result = addMockRule(rule)
74
+ }
75
+
76
+ if (jsonFlag) {
77
+ output.jsonRaw(result)
78
+ return
79
+ }
80
+
81
+ output.header('Mock Rule Added')
82
+ output.success(`#${result.id}: ${result.name}`)
83
+ output.kv('Pattern', result.urlPattern)
84
+ output.kv('Method', result.method)
85
+ output.kv('Status', result.statusCode)
86
+ output.kv('Delay', `${result.delay}ms`)
87
+ }
88
+
89
+ run().catch(e => {
90
+ output.error(e.message)
91
+ process.exit(1)
92
+ })
@@ -0,0 +1,58 @@
1
+ /**
2
+ * meddle mock delete - Delete a mock rule
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiDelete } = require('../../lib/api-client')
8
+ const { deleteMockRule } = require('../../lib/file-access')
9
+
10
+ // Parse arguments (skip 'mock' and 'delete' from argv)
11
+ const args = process.argv.slice(4)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ // Get id from positional argument
16
+ const idArg = args.find(a => !a.startsWith('--'))
17
+ const id = idArg ? parseInt(idArg, 10) : null
18
+
19
+ async function run() {
20
+ if (id === null) {
21
+ output.error('Missing required argument: <id>')
22
+ process.exit(1)
23
+ }
24
+
25
+ const running = await isProxyRunning()
26
+
27
+ if (running) {
28
+ try {
29
+ await apiDelete(`/api/mocks/${id}`)
30
+ } catch (e) {
31
+ // Fallback to file mode
32
+ const deleted = deleteMockRule(id)
33
+ if (!deleted) {
34
+ output.error(`Mock rule not found: id=${id}`)
35
+ process.exit(1)
36
+ }
37
+ }
38
+ } else {
39
+ const deleted = deleteMockRule(id)
40
+ if (!deleted) {
41
+ output.error(`Mock rule not found: id=${id}`)
42
+ process.exit(1)
43
+ }
44
+ }
45
+
46
+ if (jsonFlag) {
47
+ output.jsonRaw({ success: true, id })
48
+ return
49
+ }
50
+
51
+ output.header('Mock Rule Deleted')
52
+ output.success(`id=${id}`)
53
+ }
54
+
55
+ run().catch(e => {
56
+ output.error(e.message)
57
+ process.exit(1)
58
+ })
@@ -0,0 +1,50 @@
1
+ /**
2
+ * meddle mock - Mock rule subcommand router
3
+ */
4
+
5
+ const args = process.argv.slice(3)
6
+ const subcommand = args[0]
7
+
8
+ switch (subcommand) {
9
+ case 'list':
10
+ require('./list.js')
11
+ break
12
+ case 'add':
13
+ require('./add.js')
14
+ break
15
+ case 'update':
16
+ require('./update.js')
17
+ break
18
+ case 'delete':
19
+ require('./delete.js')
20
+ break
21
+ case 'enable':
22
+ case 'disable':
23
+ require('./toggle.js')
24
+ break
25
+ default:
26
+ console.log(`
27
+ Mock Commands:
28
+ meddle mock list [--json] List all mock rules
29
+ meddle mock add [options] Add a mock rule
30
+ meddle mock update <id> [options] Update a mock rule
31
+ meddle mock delete <id> Delete a mock rule
32
+ meddle mock enable <id> Enable a mock rule
33
+ meddle mock disable <id> Disable a mock rule
34
+
35
+ Add Options:
36
+ --name <n> Rule name
37
+ --pattern <p> URL pattern (regex or string)
38
+ --method <m> HTTP method (GET, POST, *, default: *)
39
+ --status <s> Response status code (default: 200)
40
+ --body <b> Response body content
41
+ --delay <d> Response delay in ms (default: 0)
42
+
43
+ Examples:
44
+ meddle mock list
45
+ meddle mock add --name "API Mock" --pattern "example.com/api" --status 200
46
+ meddle mock update 1 --status 404
47
+ meddle mock delete 1
48
+ `)
49
+ process.exit(1)
50
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * meddle mock list - List all mock rules
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiGet } = require('../../lib/api-client')
8
+ const { loadMockRules } = require('../../lib/file-access')
9
+
10
+ // Check for --json flag
11
+ const args = process.argv.slice(3)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ async function run() {
16
+ const running = await isProxyRunning()
17
+
18
+ let rules = []
19
+
20
+ if (running) {
21
+ try {
22
+ rules = await apiGet('/api/mocks')
23
+ } catch (e) {
24
+ // Fallback to file mode
25
+ rules = loadMockRules()
26
+ }
27
+ } else {
28
+ rules = loadMockRules()
29
+ }
30
+
31
+ if (jsonFlag) {
32
+ output.jsonRaw(rules)
33
+ return
34
+ }
35
+
36
+ output.header(`Mock Rules (${rules.length} total)`)
37
+
38
+ if (rules.length === 0) {
39
+ output.info('No mock rules found')
40
+ return
41
+ }
42
+
43
+ // Separate active and inactive
44
+ const active = rules.filter(r => r.enabled)
45
+ const inactive = rules.filter(r => !r.enabled)
46
+
47
+ if (active.length > 0) {
48
+ output.section('Active Rules')
49
+ active.forEach(rule => {
50
+ output.success(`#${rule.id}: ${rule.name} (${rule.urlPattern})`)
51
+ output.kv('Status', rule.statusCode, 4)
52
+ output.kv('Method', rule.method || '*', 4)
53
+ output.kv('Delay', `${rule.delay || 0}ms`, 4)
54
+ })
55
+ }
56
+
57
+ if (inactive.length > 0) {
58
+ output.section('Inactive Rules')
59
+ inactive.forEach(rule => {
60
+ output.bullet(`#${rule.id}: ${rule.name} (${rule.urlPattern})`, false)
61
+ })
62
+ }
63
+ }
64
+
65
+ run().catch(e => {
66
+ output.error(e.message)
67
+ process.exit(1)
68
+ })
@@ -0,0 +1,64 @@
1
+ /**
2
+ * meddle mock enable/disable - Toggle mock rule enabled status
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiPut } = require('../../lib/api-client')
8
+ const { updateMockRule } = require('../../lib/file-access')
9
+
10
+ // Parse arguments
11
+ const args = process.argv.slice(2) // Full args: ['mock', 'enable'/'disable', '<id>']
12
+ const subcommand = args[1] // 'enable' or 'disable' (at index 1)
13
+ const jsonFlag = args.includes('--json')
14
+ output.setJsonMode(jsonFlag)
15
+
16
+ // Get id from positional argument
17
+ const idArg = args.find(a => !a.startsWith('--') && a !== 'mock' && a !== 'enable' && a !== 'disable')
18
+ const id = idArg ? parseInt(idArg, 10) : null
19
+
20
+ async function run() {
21
+ if (id === null) {
22
+ output.error('Missing required argument: <id>')
23
+ process.exit(1)
24
+ }
25
+
26
+ const enabled = subcommand === 'enable'
27
+
28
+ const running = await isProxyRunning()
29
+
30
+ let result
31
+ if (running) {
32
+ try {
33
+ result = await apiPut(`/api/mocks/${id}`, { enabled })
34
+ result = result.rule || result
35
+ } catch (e) {
36
+ // Fallback to file mode
37
+ result = updateMockRule(id, { enabled })
38
+ if (!result) {
39
+ output.error(`Mock rule not found: id=${id}`)
40
+ process.exit(1)
41
+ }
42
+ }
43
+ } else {
44
+ result = updateMockRule(id, { enabled })
45
+ if (!result) {
46
+ output.error(`Mock rule not found: id=${id}`)
47
+ process.exit(1)
48
+ }
49
+ }
50
+
51
+ if (jsonFlag) {
52
+ output.jsonRaw(result)
53
+ return
54
+ }
55
+
56
+ output.header('Mock Rule Updated')
57
+ output.success(`#${result.id}: ${result.name}`)
58
+ output.kv('Enabled', enabled ? 'Yes' : 'No')
59
+ }
60
+
61
+ run().catch(e => {
62
+ output.error(e.message)
63
+ process.exit(1)
64
+ })
@@ -0,0 +1,94 @@
1
+ /**
2
+ * meddle mock update - Update a mock rule
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiPut } = require('../../lib/api-client')
8
+ const { updateMockRule, loadMockRules, saveMockRules } = require('../../lib/file-access')
9
+
10
+ // Parse arguments (skip 'mock' and 'update' from argv)
11
+ const args = process.argv.slice(4)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ function parseArgs(args) {
16
+ // First positional arg is id
17
+ let id = null
18
+ const options = {}
19
+
20
+ for (let i = 0; i < args.length; i++) {
21
+ if (args[i] === '--name') options.name = args[++i]
22
+ else if (args[i] === '--pattern') options.urlPattern = args[++i]
23
+ else if (args[i] === '--method') options.method = args[++i]
24
+ else if (args[i] === '--status') options.statusCode = parseInt(args[++i], 10)
25
+ else if (args[i] === '--body') options.body = args[++i]
26
+ else if (args[i] === '--delay') options.delay = parseInt(args[++i], 10)
27
+ else if (args[i] === '--headers') {
28
+ try {
29
+ options.headers = JSON.parse(args[++i])
30
+ } catch (_) {
31
+ options.headers = {}
32
+ }
33
+ }
34
+ else if (!args[i].startsWith('--') && id === null) {
35
+ id = parseInt(args[i], 10)
36
+ }
37
+ }
38
+
39
+ return { id, options }
40
+ }
41
+
42
+ async function run() {
43
+ const { id, options } = parseArgs(args)
44
+
45
+ if (id === null) {
46
+ output.error('Missing required argument: <id>')
47
+ process.exit(1)
48
+ }
49
+
50
+ if (Object.keys(options).length === 0) {
51
+ output.error('No update options provided')
52
+ process.exit(1)
53
+ }
54
+
55
+ const running = await isProxyRunning()
56
+
57
+ let result
58
+ if (running) {
59
+ try {
60
+ result = await apiPut(`/api/mocks/${id}`, options)
61
+ result = result.rule || result
62
+ } catch (e) {
63
+ // Fallback to file mode
64
+ result = updateMockRule(id, options)
65
+ if (!result) {
66
+ output.error(`Mock rule not found: id=${id}`)
67
+ process.exit(1)
68
+ }
69
+ }
70
+ } else {
71
+ result = updateMockRule(id, options)
72
+ if (!result) {
73
+ output.error(`Mock rule not found: id=${id}`)
74
+ process.exit(1)
75
+ }
76
+ }
77
+
78
+ if (jsonFlag) {
79
+ output.jsonRaw(result)
80
+ return
81
+ }
82
+
83
+ output.header('Mock Rule Updated')
84
+ output.success(`#${result.id}: ${result.name}`)
85
+ if (options.urlPattern) output.kv('Pattern', result.urlPattern)
86
+ if (options.method) output.kv('Method', result.method)
87
+ if (options.statusCode) output.kv('Status', result.statusCode)
88
+ if (options.delay) output.kv('Delay', `${result.delay}ms`)
89
+ }
90
+
91
+ run().catch(e => {
92
+ output.error(e.message)
93
+ process.exit(1)
94
+ })
@@ -0,0 +1,141 @@
1
+ /**
2
+ * meddle route active - Show or set active route files
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiGet, apiPut } = require('../../lib/api-client')
8
+ const { listRuleFiles, getActiveRuleFileNames, setActiveRuleFileNames, setRuleFileEnabled } = require('../../lib/file-access')
9
+
10
+ // Parse arguments (skip 'route' and 'active' from argv)
11
+ const args = process.argv.slice(4)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ // Check for 'set' subcommand - now 'set' would be at args[0] if present
16
+ const isSet = args[0] === 'set'
17
+ const targetFile = isSet ? args[1] : null
18
+
19
+ async function run() {
20
+ const running = await isProxyRunning()
21
+
22
+ if (isSet) {
23
+ if (!targetFile) {
24
+ output.error('Missing required argument: <file>')
25
+ process.exit(1)
26
+ }
27
+
28
+ // Set active route file (disable others, enable this one)
29
+ if (running) {
30
+ try {
31
+ const files = await apiGet('/api/rule-files')
32
+ if (!Array.isArray(files)) {
33
+ throw new Error('规则文件列表返回格式错误')
34
+ }
35
+
36
+ const target = files.find(f => f && f.name === targetFile)
37
+ if (!target) {
38
+ output.error(`Route file not found: ${targetFile}`)
39
+ process.exit(1)
40
+ }
41
+
42
+ for (const f of files) {
43
+ const nextEnabled = f.name === targetFile
44
+ if (!!f.enabled === nextEnabled) continue
45
+ await apiPut(`/api/rule-files/${encodeURIComponent(f.name)}`, { enabled: nextEnabled })
46
+ }
47
+
48
+ if (jsonFlag) {
49
+ output.jsonRaw({ success: true, activeFile: targetFile })
50
+ return
51
+ }
52
+
53
+ output.header('Active Route File Set')
54
+ output.success(targetFile)
55
+ } catch (e) {
56
+ // Fallback to file mode
57
+ const files = listRuleFiles()
58
+ const target = files.find(f => f.name === targetFile)
59
+ if (!target) {
60
+ output.error(`Route file not found: ${targetFile}`)
61
+ process.exit(1)
62
+ }
63
+
64
+ // Disable all, then enable target
65
+ files.forEach(f => setRuleFileEnabled(f.name, f.name === targetFile))
66
+
67
+ if (jsonFlag) {
68
+ output.jsonRaw({ success: true, activeFile: targetFile })
69
+ return
70
+ }
71
+
72
+ output.header('Active Route File Set')
73
+ output.success(targetFile)
74
+ }
75
+ } else {
76
+ // File mode
77
+ const files = listRuleFiles()
78
+ const target = files.find(f => f.name === targetFile)
79
+ if (!target) {
80
+ output.error(`Route file not found: ${targetFile}`)
81
+ process.exit(1)
82
+ }
83
+
84
+ files.forEach(f => setRuleFileEnabled(f.name, f.name === targetFile))
85
+
86
+ if (jsonFlag) {
87
+ output.jsonRaw({ success: true, activeFile: targetFile })
88
+ return
89
+ }
90
+
91
+ output.header('Active Route File Set')
92
+ output.success(targetFile)
93
+ }
94
+ return
95
+ }
96
+
97
+ // Show active route files
98
+ let files = []
99
+ let activeFiles = []
100
+
101
+ if (running) {
102
+ try {
103
+ files = await apiGet('/api/rule-files')
104
+ activeFiles = Array.isArray(files) ? files.filter(f => f && f.enabled).map(f => f.name) : []
105
+ } catch (e) {
106
+ activeFiles = getActiveRuleFileNames()
107
+ }
108
+ } else {
109
+ activeFiles = getActiveRuleFileNames()
110
+ }
111
+
112
+ const currentRuleFile = activeFiles.length === 1 ? activeFiles[0] : null
113
+
114
+ if (jsonFlag) {
115
+ output.jsonRaw({
116
+ currentRuleFile,
117
+ activeRuleFiles: activeFiles,
118
+ count: activeFiles.length
119
+ })
120
+ return
121
+ }
122
+
123
+ output.header('Active Route Files')
124
+
125
+ if (activeFiles.length === 0) {
126
+ output.info('No active route files')
127
+ return
128
+ }
129
+
130
+ if (currentRuleFile) {
131
+ output.kv('Current', currentRuleFile)
132
+ } else {
133
+ output.kv('Active Files', activeFiles.length)
134
+ activeFiles.forEach(f => output.bullet(f, true))
135
+ }
136
+ }
137
+
138
+ run().catch(e => {
139
+ output.error(e.message)
140
+ process.exit(1)
141
+ })
@@ -0,0 +1,127 @@
1
+ /**
2
+ * meddle route add - Add a rule to a route file
3
+ */
4
+
5
+ const output = require('../../lib/output')
6
+ const { isProxyRunning } = require('../../lib/proxy-detect')
7
+ const { apiGet, apiPut } = require('../../lib/api-client')
8
+ const { getRuleFileContent, saveRuleFileContent, parseEprc, ruleMapToEprcText } = require('../../lib/file-access')
9
+
10
+ // Parse arguments (skip 'route' and 'add' from argv)
11
+ const args = process.argv.slice(4)
12
+ const jsonFlag = args.includes('--json')
13
+ output.setJsonMode(jsonFlag)
14
+
15
+ // Get positional arguments: file, pattern, target
16
+ const positionalArgs = args.filter(a => !a.startsWith('--'))
17
+ const fileName = positionalArgs[0]
18
+ const pattern = positionalArgs[1]
19
+ const target = positionalArgs[2]
20
+
21
+ async function run() {
22
+ if (!fileName) {
23
+ output.error('Missing required argument: <file>')
24
+ process.exit(1)
25
+ }
26
+ if (!pattern) {
27
+ output.error('Missing required argument: <pattern>')
28
+ process.exit(1)
29
+ }
30
+ if (!target) {
31
+ output.error('Missing required argument: <target>')
32
+ process.exit(1)
33
+ }
34
+
35
+ const running = await isProxyRunning()
36
+
37
+ const pat = pattern.trim()
38
+ const tgt = target.trim()
39
+
40
+ if (running) {
41
+ try {
42
+ // Get current content
43
+ let content = await apiGet(`/api/rule-files/${encodeURIComponent(fileName)}/content`)
44
+ const text = typeof content === 'string' ? content : String(content)
45
+ const ruleMap = parseEprc(text)
46
+
47
+ // Handle [marker] syntax
48
+ const bm = pat.match(/\[([^\]]+)\]/)
49
+ if (bm) {
50
+ ruleMap[pat.replace(bm[0], bm[1])] = tgt + bm[0]
51
+ } else {
52
+ ruleMap[pat] = tgt
53
+ }
54
+
55
+ const newContent = ruleMapToEprcText(ruleMap)
56
+ await apiPut(`/api/rule-files/${encodeURIComponent(fileName)}/content`, { content: newContent })
57
+
58
+ if (jsonFlag) {
59
+ output.jsonRaw({ success: true, file: fileName, pattern: pat, target: tgt })
60
+ return
61
+ }
62
+
63
+ output.header('Route Rule Added')
64
+ output.success(`${pat} -> ${tgt}`)
65
+ output.kv('File', fileName)
66
+ } catch (e) {
67
+ // Fallback to file mode
68
+ const content = getRuleFileContent(fileName)
69
+ if (!content) {
70
+ output.error(`Route file not found: ${fileName}`)
71
+ process.exit(1)
72
+ }
73
+
74
+ const ruleMap = parseEprc(content)
75
+ const bm = pat.match(/\[([^\]]+)\]/)
76
+ if (bm) {
77
+ ruleMap[pat.replace(bm[0], bm[1])] = tgt + bm[0]
78
+ } else {
79
+ ruleMap[pat] = tgt
80
+ }
81
+
82
+ const newContent = ruleMapToEprcText(ruleMap)
83
+ saveRuleFileContent(fileName, newContent)
84
+
85
+ if (jsonFlag) {
86
+ output.jsonRaw({ success: true, file: fileName, pattern: pat, target: tgt })
87
+ return
88
+ }
89
+
90
+ output.header('Route Rule Added')
91
+ output.success(`${pat} -> ${tgt}`)
92
+ output.kv('File', fileName)
93
+ }
94
+ } else {
95
+ // File mode
96
+ const content = getRuleFileContent(fileName)
97
+ if (!content) {
98
+ output.error(`Route file not found: ${fileName}`)
99
+ process.exit(1)
100
+ }
101
+
102
+ const ruleMap = parseEprc(content)
103
+ const bm = pat.match(/\[([^\]]+)\]/)
104
+ if (bm) {
105
+ ruleMap[pat.replace(bm[0], bm[1])] = tgt + bm[0]
106
+ } else {
107
+ ruleMap[pat] = tgt
108
+ }
109
+
110
+ const newContent = ruleMapToEprcText(ruleMap)
111
+ saveRuleFileContent(fileName, newContent)
112
+
113
+ if (jsonFlag) {
114
+ output.jsonRaw({ success: true, file: fileName, pattern: pat, target: tgt })
115
+ return
116
+ }
117
+
118
+ output.header('Route Rule Added')
119
+ output.success(`${pat} -> ${tgt}`)
120
+ output.kv('File', fileName)
121
+ }
122
+ }
123
+
124
+ run().catch(e => {
125
+ output.error(e.message)
126
+ process.exit(1)
127
+ })