addon-dailer
lqqyt2423 4 years ago
parent 4ee3534d93
commit 3f5dd4bd52

@ -0,0 +1,33 @@
env:
browser: true
es2021: true
extends:
- 'eslint:recommended'
- 'plugin:react/recommended'
- 'plugin:@typescript-eslint/recommended'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaFeatures:
jsx: true
ecmaVersion: 12
sourceType: module
plugins:
- react
- '@typescript-eslint'
rules:
indent:
- error
- 2
linebreak-style:
- error
- unix
quotes:
- error
- single
semi:
- error
- never
'@typescript-eslint/explicit-module-boundary-types':
- 0
'@typescript-eslint/no-explicit-any':
- 0

@ -44,27 +44,3 @@ You dont have to ever use `eject`. The curated feature set is suitable for sm
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `yarn build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)

@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.cb45a0e0.chunk.css",
"main.js": "/static/js/main.6b681f56.chunk.js",
"main.js.map": "/static/js/main.6b681f56.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.48e80cd2.js",
"runtime-main.js.map": "/static/js/runtime-main.48e80cd2.js.map",
"main.css": "/static/css/main.451c1dcc.chunk.css",
"main.js": "/static/js/main.5904c112.chunk.js",
"main.js.map": "/static/js/main.5904c112.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.bcda7d85.js",
"runtime-main.js.map": "/static/js/runtime-main.bcda7d85.js.map",
"static/css/2.150d169a.chunk.css": "/static/css/2.150d169a.chunk.css",
"static/js/2.68265363.chunk.js": "/static/js/2.68265363.chunk.js",
"static/js/2.68265363.chunk.js.map": "/static/js/2.68265363.chunk.js.map",
"static/js/3.f3a1fc42.chunk.js": "/static/js/3.f3a1fc42.chunk.js",
"static/js/3.f3a1fc42.chunk.js.map": "/static/js/3.f3a1fc42.chunk.js.map",
"static/js/2.88d332b9.chunk.js": "/static/js/2.88d332b9.chunk.js",
"static/js/2.88d332b9.chunk.js.map": "/static/js/2.88d332b9.chunk.js.map",
"static/js/3.a88e738d.chunk.js": "/static/js/3.a88e738d.chunk.js",
"static/js/3.a88e738d.chunk.js.map": "/static/js/3.a88e738d.chunk.js.map",
"index.html": "/index.html",
"static/css/2.150d169a.chunk.css.map": "/static/css/2.150d169a.chunk.css.map",
"static/css/main.cb45a0e0.chunk.css.map": "/static/css/main.cb45a0e0.chunk.css.map",
"static/js/2.68265363.chunk.js.LICENSE.txt": "/static/js/2.68265363.chunk.js.LICENSE.txt"
"static/css/main.451c1dcc.chunk.css.map": "/static/css/main.451c1dcc.chunk.css.map",
"static/js/2.88d332b9.chunk.js.LICENSE.txt": "/static/js/2.88d332b9.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.48e80cd2.js",
"static/js/runtime-main.bcda7d85.js",
"static/css/2.150d169a.chunk.css",
"static/js/2.68265363.chunk.js",
"static/css/main.cb45a0e0.chunk.css",
"static/js/main.6b681f56.chunk.js"
"static/js/2.88d332b9.chunk.js",
"static/css/main.451c1dcc.chunk.css",
"static/js/main.5904c112.chunk.js"
]
}

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>go-mitmproxy</title><link href="/static/css/2.150d169a.chunk.css" rel="stylesheet"><link href="/static/css/main.cb45a0e0.chunk.css" rel="stylesheet"></head><body><a href="https://github.com/lqqyt2423/go-mitmproxy" target="_blank" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#70b7fd;color:#fff;position:absolute;top:0;border:0;right:0" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin:130px 106px" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"f3a1fc42"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.68265363.chunk.js"></script><script src="/static/js/main.6b681f56.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>go-mitmproxy</title><link href="/static/css/2.150d169a.chunk.css" rel="stylesheet"><link href="/static/css/main.451c1dcc.chunk.css" rel="stylesheet"></head><body><a href="https://github.com/lqqyt2423/go-mitmproxy" target="_blank" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#70b7fd;color:#fff;position:absolute;top:0;border:0;right:0" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin:130px 106px" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],p=0,s=[];p<a.length;p++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"a88e738d"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpmitmproxy-client"]=this["webpackJsonpmitmproxy-client"]||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.88d332b9.chunk.js"></script><script src="/static/js/main.5904c112.chunk.js"></script></body></html>

@ -1,2 +1,2 @@
.main-table-wrap{font-family:Menlo,Monaco;font-size:.8rem}.top-control{display:flex;align-items:center}.top-control>div{margin-right:20px}.main-table-wrap tbody tr.tr-selected{background-color:#2376e5;color:#fff}.main-table-wrap tbody tr.tr-wait-intercept{background-color:#d86e53;color:#fff}.flow-detail{position:fixed;top:0;right:0;height:100vh;background-color:#fff;min-width:500px;width:50%;overflow-y:auto;word-break:break-all}.flow-detail .header-tabs{display:flex}.flow-detail .header-tabs span{display:inline-block;line-height:1;padding:8px;cursor:pointer}.flow-detail .header-tabs .selected{border-bottom:2px solid #2376e5}.flow-detail .header-tabs .flow-wait-area button{margin-left:10px}.flow-detail .header-block{margin-bottom:20px}.flow-detail .header-block>p{font-weight:700}.flow-detail .header-block .header-block-content p{margin:5px 0}.flow-detail .header-block .header-block-content{margin-left:20px;line-height:1.5}
/*# sourceMappingURL=main.cb45a0e0.chunk.css.map */
/*# sourceMappingURL=main.451c1dcc.chunk.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["webpack://src/App.css"],"names":[],"mappings":"AAAA,iBACE,wBAAyB,CACzB,eACF,CAEA,aACE,YAAa,CACb,kBACF,CAEA,iBACE,iBACF,CAGA,sCACE,wBAAmC,CACnC,UACF,CAEA,4CACE,wBAAmC,CACnC,UACF,CAEA,aACE,cAAe,CACf,KAAM,CACN,OAAQ,CAER,YAAa,CACb,qBAAsB,CACtB,eAAgB,CAChB,SAAU,CACV,eAAgB,CAEhB,oBACF,CAEA,0BACE,YACF,CAEA,+BACE,oBAAqB,CACrB,aAAc,CACd,WAAY,CACZ,cACF,CAEA,oCACE,+BACF,CAEA,iDACE,gBACF,CAEA,2BACE,kBACF,CAEA,6BACE,eACF,CAEA,mDACE,YACF,CAEA,iDACE,gBAAiB,CACjB,eACF","file":"main.451c1dcc.chunk.css","sourcesContent":[".main-table-wrap {\n font-family: Menlo,Monaco;\n font-size: 0.8rem;\n}\n\n.top-control {\n display: flex;\n align-items: center;\n}\n\n.top-control > div {\n margin-right: 20px;\n}\n\n\n.main-table-wrap tbody tr.tr-selected {\n background-color: rgb(35, 118, 229);\n color: white;\n}\n\n.main-table-wrap tbody tr.tr-wait-intercept {\n background-color: rgb(216, 110, 83);\n color: white;\n}\n\n.flow-detail {\n position: fixed;\n top: 0;\n right: 0;\n\n height: 100vh;\n background-color: #fff;\n min-width: 500px;\n width: 50%;\n overflow-y: auto;\n\n word-break: break-all;\n}\n\n.flow-detail .header-tabs {\n display: flex;\n}\n\n.flow-detail .header-tabs span {\n display: inline-block;\n line-height: 1;\n padding: 8px;\n cursor: pointer;\n}\n\n.flow-detail .header-tabs .selected {\n border-bottom: 2px rgb(35, 118, 229) solid;\n}\n\n.flow-detail .header-tabs .flow-wait-area button {\n margin-left: 10px;\n}\n\n.flow-detail .header-block {\n margin-bottom: 20px;\n}\n\n.flow-detail .header-block > p {\n font-weight: bold;\n}\n\n.flow-detail .header-block .header-block-content p {\n margin: 5px 0;\n}\n\n.flow-detail .header-block .header-block-content {\n margin-left: 20px;\n line-height: 1.5;\n}\n"]}

@ -1 +0,0 @@
{"version":3,"sources":["webpack://src/App.css"],"names":[],"mappings":"AAAA,iBACI,wBAAyB,CACzB,eACJ,CAEA,aACI,YAAa,CACb,kBACJ,CAEA,iBACI,iBACJ,CAGA,sCACI,wBAAmC,CACnC,UACJ,CAEA,4CACI,wBAAmC,CACnC,UACJ,CAEA,aACI,cAAe,CACf,KAAM,CACN,OAAQ,CAER,YAAa,CACb,qBAAsB,CACtB,eAAgB,CAChB,SAAU,CACV,eAAgB,CAEhB,oBACJ,CAEA,0BACI,YACJ,CAEA,+BACI,oBAAqB,CACrB,aAAc,CACd,WAAY,CACZ,cACJ,CAEA,oCACI,+BACJ,CAEA,iDACI,gBACJ,CAEA,2BACI,kBACJ,CAEA,6BACI,eACJ,CAEA,mDACI,YACJ,CAEA,iDACI,gBAAiB,CACjB,eACJ","file":"main.cb45a0e0.chunk.css","sourcesContent":[".main-table-wrap {\n font-family: Menlo,Monaco;\n font-size: 0.8rem;\n}\n\n.top-control {\n display: flex;\n align-items: center;\n}\n\n.top-control > div {\n margin-right: 20px;\n}\n\n\n.main-table-wrap tbody tr.tr-selected {\n background-color: rgb(35, 118, 229);\n color: white;\n}\n\n.main-table-wrap tbody tr.tr-wait-intercept {\n background-color: rgb(216, 110, 83);\n color: white;\n}\n\n.flow-detail {\n position: fixed;\n top: 0;\n right: 0;\n\n height: 100vh;\n background-color: #fff;\n min-width: 500px;\n width: 50%;\n overflow-y: auto;\n\n word-break: break-all;\n}\n\n.flow-detail .header-tabs {\n display: flex;\n}\n\n.flow-detail .header-tabs span {\n display: inline-block;\n line-height: 1;\n padding: 8px;\n cursor: pointer;\n}\n\n.flow-detail .header-tabs .selected {\n border-bottom: 2px rgb(35, 118, 229) solid;\n}\n\n.flow-detail .header-tabs .flow-wait-area button {\n margin-left: 10px;\n}\n\n.flow-detail .header-block {\n margin-bottom: 20px;\n}\n\n.flow-detail .header-block > p {\n font-weight: bold;\n}\n\n.flow-detail .header-block .header-block-content p {\n margin: 5px 0;\n}\n\n.flow-detail .header-block .header-block-content {\n margin-left: 20px;\n line-height: 1.5;\n}"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,12 +5,12 @@ object-assign
*/
/*!
Copyright (c) 2017 Jed Watson.
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/** @license React v0.20.1
/** @license React v0.20.2
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
@ -19,7 +19,7 @@ object-assign
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
/** @license React v17.0.2
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
@ -28,7 +28,7 @@ object-assign
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
/** @license React v17.0.2
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
@ -37,7 +37,7 @@ object-assign
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
/** @license React v17.0.2
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
(this["webpackJsonpmitmproxy-client"]=this["webpackJsonpmitmproxy-client"]||[]).push([[3],{55:function(t,e,n){"use strict";n.r(e),n.d(e,"getCLS",(function(){return d})),n.d(e,"getFCP",(function(){return y})),n.d(e,"getFID",(function(){return F})),n.d(e,"getLCP",(function(){return k})),n.d(e,"getTTFB",(function(){return C}));var i,a,r,o,c=function(t,e){return{name:t,value:void 0===e?-1:e,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},s=function(t,e){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(t(i),e&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},f=function(t){addEventListener("pageshow",(function(e){e.persisted&&t(e)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,e,n){var i;return function(){e.value>=0&&(n||m.has(e)||"hidden"===document.visibilityState)&&(e.delta=e.value-(i||0),(e.delta||void 0===i)&&(i=e.value,t(e)))}},d=function(t,e){var n,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),n())},r=u("layout-shift",a);r&&(n=p(t,i,e),s((function(){r.takeRecords().map(a),n()})),f((function(){i=c("CLS",0),n=p(t,i,e)})))},v=-1,l=function(){return"hidden"===document.visibilityState?0:1/0},h=function(){s((function(t){var e=t.timeStamp;v=e}),!0)},S=function(){return v<0&&(v=l(),h(),f((function(){setTimeout((function(){v=l(),h()}),0)}))),{get timeStamp(){return v}}},y=function(t,e){var n,i=S(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),n()))}));r&&(n=p(t,a,e),f((function(i){a=c("FCP"),n=p(t,a,e),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),n()}))}))})))},g={passive:!0,capture:!0},w=new Date,E=function(t,e){i||(i=e,a=t,r=new Date,b(removeEventListener),L())},L=function(){if(a>=0&&a<r-w){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(e){e(t)})),o=[]}},T=function(t){if(t.cancelable){var e=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){E(t,e),a()},i=function(){a()},a=function(){removeEventListener("pointerup",n,g),removeEventListener("pointercancel",i,g)};addEventListener("pointerup",n,g),addEventListener("pointercancel",i,g)}(e,t):E(e,t)}},b=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,T,g)}))},F=function(t,e){var n,r=S(),d=c("FID"),v=function(t){t.startTime<r.timeStamp&&(d.value=t.processingStart-t.startTime,d.entries.push(t),m.add(d),n())},l=u("first-input",v);n=p(t,d,e),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&f((function(){var r;d=c("FID"),n=p(t,d,e),o=[],a=-1,i=null,b(addEventListener),r=v,o.push(r),L()}))},k=function(t,e){var n,i=S(),a=c("LCP"),r=function(t){var e=t.startTime;e<i.timeStamp&&(a.value=e,a.entries.push(t)),n()},o=u("largest-contentful-paint",r);if(o){n=p(t,a,e);var d=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),n())};["keydown","click"].forEach((function(t){addEventListener(t,d,{once:!0,capture:!0})})),s(d,!0),f((function(i){a=c("LCP"),n=p(t,a,e),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),n()}))}))}))}},C=function(t){var e,n=c("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);
//# sourceMappingURL=3.a88e738d.chunk.js.map

File diff suppressed because one or more lines are too long

@ -1,2 +0,0 @@
(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[3],{55:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return v})),e.d(n,"getFCP",(function(){return y})),e.d(n,"getFID",(function(){return k})),e.d(n,"getLCP",(function(){return C})),e.d(n,"getTTFB",(function(){return P}));var i,a,r,o,c=function(t,n){return{name:t,value:void 0===n?-1:n,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},f=!1,s=function(t,n){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function e(i){"hidden"===document.visibilityState&&(t(i),n&&removeEventListener("visibilitychange",e,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(n){n.persisted&&t(n)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,n,e){var i;return function(){n.value>=0&&(e||m.has(n)||"hidden"===document.visibilityState)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,t(n)))}},v=function(t,n){var e,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=u("layout-shift",a);r&&(e=p(t,i,n),s((function(){r.takeRecords().map(a),e()})),d((function(){i=c("CLS",0),e=p(t,i,n)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var n=t.timeStamp;l=n}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,n){var e,i=g(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),e()))}));r&&(e=p(t,a,n),d((function(i){a=c("FCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))})))},w={passive:!0,capture:!0},E=new Date,L=function(t,n){i||(i=n,a=t,r=new Date,F(removeEventListener),T())},T=function(){if(a>=0&&a<r-E){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(n){n(t)})),o=[]}},b=function(t){if(t.cancelable){var n=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,n){var e=function(){L(t,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",e,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",e,w),addEventListener("pointercancel",i,w)}(n,t):L(n,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return t(n,b,w)}))},k=function(t,n){var e,r=g(),f=c("FID"),v=function(t){t.startTime<r.timeStamp&&(f.value=t.processingStart-t.startTime,f.entries.push(t),m.add(f),e())},l=u("first-input",v);e=p(t,f,n),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&d((function(){var r;f=c("FID"),e=p(t,f,n),o=[],a=-1,i=null,F(addEventListener),r=v,o.push(r),T()}))},C=function(t,n){var e,i=g(),a=c("LCP"),r=function(t){var n=t.startTime;n<i.timeStamp&&(a.value=n,a.entries.push(t)),e()},o=u("largest-contentful-paint",r);if(o){e=p(t,a,n);var f=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),e())};["keydown","click"].forEach((function(t){addEventListener(t,f,{once:!0,capture:!0})})),s(f,!0),d((function(i){a=c("LCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))}))}},P=function(t){var n,e=c("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
//# sourceMappingURL=3.f3a1fc42.chunk.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,2 +1,2 @@
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"f3a1fc42"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
//# sourceMappingURL=runtime-main.48e80cd2.js.map
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],p=0,s=[];p<a.length;p++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"a88e738d"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpmitmproxy-client"]=this["webpackJsonpmitmproxy-client"]||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
//# sourceMappingURL=runtime-main.bcda7d85.js.map

File diff suppressed because it is too large Load Diff

@ -1,16 +1,21 @@
{
"name": "client",
"name": "mitmproxy-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"bootstrap": "^4.6.0",
"react": "^17.0.1",
"react-bootstrap": "^1.4.3",
"react-dom": "^17.0.1",
"react-scripts": "4.0.2",
"react": "^17.0.2",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
"scripts": {
@ -36,5 +41,11 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"eslint": "^7.25.0",
"eslint-plugin-react": "^7.23.2"
}
}

@ -1,74 +1,74 @@
.main-table-wrap {
font-family: Menlo,Monaco;
font-size: 0.8rem;
font-family: Menlo,Monaco;
font-size: 0.8rem;
}
.top-control {
display: flex;
align-items: center;
display: flex;
align-items: center;
}
.top-control > div {
margin-right: 20px;
margin-right: 20px;
}
.main-table-wrap tbody tr.tr-selected {
background-color: rgb(35, 118, 229);
color: white;
background-color: rgb(35, 118, 229);
color: white;
}
.main-table-wrap tbody tr.tr-wait-intercept {
background-color: rgb(216, 110, 83);
color: white;
background-color: rgb(216, 110, 83);
color: white;
}
.flow-detail {
position: fixed;
top: 0;
right: 0;
position: fixed;
top: 0;
right: 0;
height: 100vh;
background-color: #fff;
min-width: 500px;
width: 50%;
overflow-y: auto;
height: 100vh;
background-color: #fff;
min-width: 500px;
width: 50%;
overflow-y: auto;
word-break: break-all;
word-break: break-all;
}
.flow-detail .header-tabs {
display: flex;
display: flex;
}
.flow-detail .header-tabs span {
display: inline-block;
line-height: 1;
padding: 8px;
cursor: pointer;
display: inline-block;
line-height: 1;
padding: 8px;
cursor: pointer;
}
.flow-detail .header-tabs .selected {
border-bottom: 2px rgb(35, 118, 229) solid;
border-bottom: 2px rgb(35, 118, 229) solid;
}
.flow-detail .header-tabs .flow-wait-area button {
margin-left: 10px;
margin-left: 10px;
}
.flow-detail .header-block {
margin-bottom: 20px;
margin-bottom: 20px;
}
.flow-detail .header-block > p {
font-weight: bold;
font-weight: bold;
}
.flow-detail .header-block .header-block-content p {
margin: 5px 0;
margin: 5px 0;
}
.flow-detail .header-block .header-block-content {
margin-left: 20px;
line-height: 1.5;
}
margin-left: 20px;
line-height: 1.5;
}

@ -1,3 +1,4 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import App from './App'

@ -9,11 +9,19 @@ import EditFlow from './components/EditFlow'
import { FlowManager } from './flow'
import { isTextBody, getSize } from './utils'
import { parseMessage, sendMessageEnum, buildMessageMeta } from './message'
import { parseMessage, SendMessageType, buildMessageMeta, IFlow, MessageType, IRequest, IResponse } from './message'
class App extends React.Component {
interface IState {
flows: IFlow[]
flow: IFlow | null
flowTab: 'Headers' | 'Preview' | 'Response'
}
class App extends React.Component<any, IState> {
private flowMgr: FlowManager
private ws: WebSocket | null
constructor(props) {
constructor(props: any) {
super(props)
this.flowMgr = new FlowManager()
@ -59,30 +67,30 @@ class App extends React.Component {
}
// console.log('msg:', msg)
if (msg.type === 'request') {
const flow = { id: msg.id, request: msg.content, waitIntercept: msg.waitIntercept }
if (msg.type === MessageType.REQUEST) {
const flow = { id: msg.id, request: msg.content as IRequest, waitIntercept: msg.waitIntercept }
this.flowMgr.add(flow)
this.setState({ flows: this.flowMgr.showList() })
}
else if (msg.type === 'requestBody') {
else if (msg.type === MessageType.REQUEST_BODY) {
const flow = this.flowMgr.get(msg.id)
if (!flow) return
flow.waitIntercept = msg.waitIntercept
flow.request.body = msg.content
flow.request.body = msg.content as ArrayBuffer
this.setState({ flows: this.state.flows })
}
else if (msg.type === 'response') {
else if (msg.type === MessageType.RESPONSE) {
const flow = this.flowMgr.get(msg.id)
if (!flow) return
flow.waitIntercept = msg.waitIntercept
flow.response = msg.content
flow.response = msg.content as IResponse
this.setState({ flows: this.state.flows })
}
else if (msg.type === 'responseBody') {
else if (msg.type === MessageType.RESPONSE_BODY) {
const flow = this.flowMgr.get(msg.id)
if (!flow || !flow.response) return
flow.waitIntercept = msg.waitIntercept
flow.response.body = msg.content
flow.response.body = msg.content as ArrayBuffer
this.setState({ flows: this.state.flows })
}
}
@ -96,15 +104,15 @@ class App extends React.Component {
if (!flow) return null
const request = flow.request
const response = flow.response || {}
const response: IResponse = (flow.response || {}) as any
return (
<div className="flow-detail">
<div className="header-tabs">
<span onClick={() => { this.setState({ flow: null }) }}>x</span>
<span className={flowTab === 'Headers' ? 'selected' : null} onClick={() => { this.setState({ flowTab: 'Headers' }) }}>Headers</span>
<span className={flowTab === 'Preview' ? 'selected' : null} onClick={() => { this.setState({ flowTab: 'Preview' }) }}>Preview</span>
<span className={flowTab === 'Response' ? 'selected' : null} onClick={() => { this.setState({ flowTab: 'Response' }) }}>Response</span>
<span className={flowTab === 'Headers' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Headers' }) }}>Headers</span>
<span className={flowTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Preview' }) }}>Preview</span>
<span className={flowTab === 'Response' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Response' }) }}>Response</span>
<EditFlow
flow={flow}
@ -116,13 +124,15 @@ class App extends React.Component {
this.setState({ flows: this.state.flows })
}}
onChangeResponse={response => {
if (!flow.response) flow.response = {} as IResponse
flow.response.statusCode = response.statusCode
flow.response.header = response.header
if (isTextBody(flow.response)) flow.response.body = response.body
this.setState({ flows: this.state.flows })
}}
onMessage={msg => {
this.ws.send(msg)
if (this.ws) this.ws.send(msg)
flow.waitIntercept = false
this.setState({ flows: this.state.flows })
}}
@ -133,78 +143,78 @@ class App extends React.Component {
<div style={{ padding: '20px' }}>
{
!(flowTab === 'Headers') ? null :
<div>
<div className="header-block">
<p>General</p>
<div className="header-block-content">
<p>Request URL: {request.url}</p>
<p>Request Method: {request.method}</p>
<p>Status Code: {`${response.statusCode || '(pending)'}`}</p>
</div>
</div>
{
!(response.header) ? null :
<div>
<div className="header-block">
<p>Response Headers</p>
<p>General</p>
<div className="header-block-content">
{
Object.keys(response.header).map(key => {
return (
<p key={key}>{key}: {response.header[key].join(' ')}</p>
)
})
}
<p>Request URL: {request.url}</p>
<p>Request Method: {request.method}</p>
<p>Status Code: {`${response.statusCode || '(pending)'}`}</p>
</div>
</div>
}
<div className="header-block">
<p>Request Headers</p>
<div className="header-block-content">
{
!(request.header) ? null :
Object.keys(request.header).map(key => {
return (
<p key={key}>{key}: {request.header[key].join(' ')}</p>
)
})
}
</div>
</div>
{
!(request.body && request.body.byteLength) ? null :
{
!(response.header) ? null :
<div className="header-block">
<p>Response Headers</p>
<div className="header-block-content">
{
Object.keys(response.header).map(key => {
return (
<p key={key}>{key}: {response.header[key].join(' ')}</p>
)
})
}
</div>
</div>
}
<div className="header-block">
<p>Request Body</p>
<p>Request Headers</p>
<div className="header-block-content">
<p>
{
!(isTextBody(request)) ? "Not text" :
new TextDecoder().decode(request.body)
}
</p>
{
!(request.header) ? null :
Object.keys(request.header).map(key => {
return (
<p key={key}>{key}: {request.header[key].join(' ')}</p>
)
})
}
</div>
</div>
}
</div>
{
!(request.body && request.body.byteLength) ? null :
<div className="header-block">
<p>Request Body</p>
<div className="header-block-content">
<p>
{
!(isTextBody(request)) ? 'Not text' :
new TextDecoder().decode(request.body)
}
</p>
</div>
</div>
}
</div>
}
{
!(flowTab === 'Response') ? null :
!(response.body && response.body.byteLength) ? <div>No response</div> :
!(isTextBody(response)) ? <div>Not text response</div> :
<div>
{new TextDecoder().decode(response.body)}
</div>
!(response.body && response.body.byteLength) ? <div>No response</div> :
!(isTextBody(response)) ? <div>Not text response</div> :
<div>
{new TextDecoder().decode(response.body)}
</div>
}
</div>
</div>
)
}
render() {
const { flows } = this.state
return (
@ -228,8 +238,8 @@ class App extends React.Component {
</div>
<BreakPoint onSave={rules => {
const msg = buildMessageMeta(sendMessageEnum.changeBreakPointRules, rules)
this.ws.send(msg)
const msg = buildMessageMeta(SendMessageType.CHANGE_BREAK_POINT_RULES, rules)
if (this.ws) this.ws.send(msg)
}} />
</div>
@ -255,14 +265,14 @@ class App extends React.Component {
if (path.length > 65) path = path.slice(0, 65) + '...'
const request = f.request
const response = f.response || {}
const response: IResponse = (f.response || {}) as any
const classNames = []
if (this.state.flow && this.state.flow.id === f.id) classNames.push('tr-selected')
if (f.waitIntercept) classNames.push('tr-wait-intercept')
return (
<tr className={classNames.length ? classNames.join(' ') : null} key={f.id}
<tr className={classNames.length ? classNames.join(' ') : undefined} key={f.id}
onClick={() => {
this.setState({ flow: f })
}}

@ -5,8 +5,26 @@ import Form from 'react-bootstrap/Form'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
class BreakPoint extends React.Component {
constructor(props) {
type Method = 'ALL' | 'GET' | 'POST' | 'PUT' | 'DELETE' | ''
type Action = 1 | 2 | 3
interface IRule {
method: Method
url: string
action: Action
}
interface IState {
show: boolean
rule: IRule
haveRules: boolean
}
interface IProps {
onSave: (rules: IRule[]) => void
}
class BreakPoint extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props)
this.state = {
@ -15,7 +33,7 @@ class BreakPoint extends React.Component {
rule: {
method: 'ALL',
url: '',
action: '1',
action: 1,
},
haveRules: false,
@ -36,12 +54,12 @@ class BreakPoint extends React.Component {
handleSave() {
const { rule } = this.state
const rules = []
const rules: IRule[] = []
if (rule.url) {
rules.push({
method: rule.method === 'ALL' ? '' : rule.method,
url: rule.url,
action: parseInt(rule.action)
action: rule.action,
})
}
@ -68,7 +86,7 @@ class BreakPoint extends React.Component {
<Form.Group as={Row}>
<Form.Label column sm={2}>Method</Form.Label>
<Col sm={10}>
<Form.Control as="select" value={rule.method} onChange={e => { this.setState({ rule: { ...rule, method: e.target.value } }) }}>
<Form.Control as="select" value={rule.method} onChange={e => { this.setState({ rule: { ...rule, method: e.target.value as Method } }) }}>
<option>ALL</option>
<option>GET</option>
<option>POST</option>
@ -86,7 +104,7 @@ class BreakPoint extends React.Component {
<Form.Group as={Row}>
<Form.Label column sm={2}>Action</Form.Label>
<Col sm={10}>
<Form.Control as="select" value={rule.action} onChange={e => { this.setState({ rule: { ...rule, action: e.target.value } }) }}>
<Form.Control as="select" value={rule.action} onChange={e => { this.setState({ rule: { ...rule, action: parseInt(e.target.value) as Action } }) }}>
<option value="1">Request</option>
<option value="2">Response</option>
<option value="3">Both</option>

@ -4,11 +4,11 @@ import Modal from 'react-bootstrap/Modal'
import Form from 'react-bootstrap/Form'
import Alert from 'react-bootstrap/Alert'
import { sendMessageEnum, buildMessageEdit } from '../message'
import { SendMessageType, buildMessageEdit, IRequest, IResponse, Header, IFlow } from '../message'
import { isTextBody } from '../utils'
const stringifyRequest = request => {
const stringifyRequest = (request: IRequest) => {
const firstLine = `${request.method} ${request.url}`
const headerLines = Object.keys(request.header).map(key => {
const valstr = request.header[key].join(' \t ') // for parse convenience
@ -17,37 +17,38 @@ const stringifyRequest = request => {
let bodyLines = ''
if (request.body && isTextBody(request)) bodyLines = new TextDecoder().decode(request.body)
return `${firstLine}\n\n${headerLines}\n\n${bodyLines}`
}
const parseRequest = content => {
const parseRequest = (content: string): IRequest | undefined => {
const sections = content.split('\n\n')
if (sections.length !== 3) return
const [firstLine, headerLines, bodyLines] = sections
const [method, url] = firstLine.split(' ')
if (!method || !url) return
const header = {}
const header: Header = {}
for (const line of headerLines.split('\n')) {
const [key, vals] = line.split(': ')
if (!key || !vals) return
header[key] = vals.split(' \t ')
}
let body = null
let body: ArrayBuffer | undefined
if (bodyLines) body = new TextEncoder().encode(bodyLines)
return {
method,
url,
proto: '',
header,
body,
}
}
const stringifyResponse = response => {
const stringifyResponse = (response: IResponse) => {
const firstLine = `${response.statusCode}`
const headerLines = Object.keys(response.header).map(key => {
const valstr = response.header[key].join(' \t ') // for parse convenience
@ -56,11 +57,11 @@ const stringifyResponse = response => {
let bodyLines = ''
if (response.body && isTextBody(response)) bodyLines = new TextDecoder().decode(response.body)
return `${firstLine}\n\n${headerLines}\n\n${bodyLines}`
}
const parseResponse = content => {
const parseResponse = (content: string): IResponse | undefined => {
const sections = content.split('\n\n')
if (sections.length !== 3) return
@ -68,14 +69,14 @@ const parseResponse = content => {
const statusCode = parseInt(firstLine)
if (isNaN(statusCode)) return
const header = {}
const header: Header = {}
for (const line of headerLines.split('\n')) {
const [key, vals] = line.split(': ')
if (!key || !vals) return
header[key] = vals.split(' \t ')
}
let body = null
let body: ArrayBuffer | undefined
if (bodyLines) body = new TextEncoder().encode(bodyLines)
return {
@ -86,8 +87,21 @@ const parseResponse = content => {
}
class EditFlow extends React.Component {
constructor(props) {
interface IProps {
flow: IFlow
onChangeRequest: (request: IRequest) => void
onChangeResponse: (response: IResponse) => void
onMessage: (msg: ArrayBufferLike) => void
}
interface IState {
show: boolean
alertMsg: string
content: string
}
class EditFlow extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props)
this.state = {
@ -101,7 +115,7 @@ class EditFlow extends React.Component {
this.handleSave = this.handleSave.bind(this)
}
showAlert(msg) {
showAlert(msg: string) {
this.setState({ alertMsg: msg })
}
@ -117,7 +131,7 @@ class EditFlow extends React.Component {
if (when === 'request') {
content = stringifyRequest(flow.request)
} else {
content = stringifyResponse(flow.response)
content = stringifyResponse(flow.response as IResponse)
}
this.setState({ show: true, alertMsg: '', content })
@ -155,7 +169,7 @@ class EditFlow extends React.Component {
if (!flow.waitIntercept) return null
const { alertMsg } = this.state
const when = flow.response ? 'response' : 'request'
return (
@ -164,13 +178,13 @@ class EditFlow extends React.Component {
<Button size="sm" onClick={this.handleShow}>Edit</Button>
<Button size="sm" onClick={() => {
const msgType = when === 'response' ? sendMessageEnum.changeResponse : sendMessageEnum.changeRequest
const msgType = when === 'response' ? SendMessageType.CHANGE_RESPONSE : SendMessageType.CHANGE_REQUEST
const msg = buildMessageEdit(msgType, flow)
this.props.onMessage(msg)
}}>Continue</Button>
<Button size="sm" onClick={() => {
const msgType = when === 'response' ? sendMessageEnum.dropResponse : sendMessageEnum.dropRequest
const msgType = when === 'response' ? SendMessageType.DROP_RESPONSE : SendMessageType.DROP_REQUEST
const msg = buildMessageEdit(msgType, flow)
this.props.onMessage(msg)
}}>Drop</Button>

@ -1,4 +1,13 @@
import { IFlow } from './message'
export class FlowManager {
private items: IFlow[]
private _map: Map<string, IFlow>
private filterText: string
private filterTimer: number | null
private num: number
private max: number
constructor() {
this.items = []
this._map = new Map()
@ -16,26 +25,26 @@ export class FlowManager {
})
}
add(item) {
add(item: IFlow) {
item.no = ++this.num
this.items.push(item)
this._map.set(item.id, item)
if (this.items.length > this.max) {
const oldest = this.items.shift()
this._map.delete(oldest.id)
if (oldest) this._map.delete(oldest.id)
}
}
get(id) {
get(id: string) {
return this._map.get(id)
}
changeFilter(text) {
changeFilter(text: string) {
this.filterText = text
}
changeFilterLazy(text, callback) {
changeFilterLazy(text: string, callback: () => void) {
if (this.filterTimer) {
clearTimeout(this.filterTimer)
this.filterTimer = null
@ -44,7 +53,7 @@ export class FlowManager {
this.filterTimer = setTimeout(() => {
this.filterText = text
callback()
}, 300)
}, 300) as any
}
clear() {

@ -1,45 +1,77 @@
const messageEnum = {
'request': 1,
'requestBody': 2,
'response': 3,
'responseBody': 4,
export enum MessageType {
REQUEST = 1,
REQUEST_BODY = 2,
RESPONSE = 3,
RESPONSE_BODY = 4,
}
const allMessageBytes = Object.keys(messageEnum).map(k => messageEnum[k])
export type Header = Record<string, string[]>
const messageByteMap = Object.keys(messageEnum).reduce((m, k) => {
m[messageEnum[k]] = k
return m
}, {})
export interface IRequest {
method: string
url: string
proto: string
header: Header
body?: ArrayBuffer
}
export interface IResponse {
statusCode: number
header: Header
body?: ArrayBuffer
}
export interface IMessage {
type: MessageType
id: string
waitIntercept: boolean
content?: ArrayBuffer | IRequest | IResponse
}
export interface IFlow {
id: string
no?: number
waitIntercept: boolean
request: IRequest
response?: IResponse
}
const allMessageBytes = [
MessageType.REQUEST,
MessageType.REQUEST_BODY,
MessageType.RESPONSE,
MessageType.RESPONSE_BODY,
]
// type: 1/2/3/4
// messageFlow
// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes
export const parseMessage = data => {
export const parseMessage = (data: ArrayBuffer): IMessage | null => {
if (data.byteLength < 39) return null
const meta = new Int8Array(data.slice(0, 39))
const version = meta[0]
if (version !== 1) return null
const type = meta[1]
const type = meta[1] as MessageType
if (!allMessageBytes.includes(type)) return null
const id = new TextDecoder().decode(data.slice(2, 38))
const waitIntercept = meta[38] === 1
const resp = {
type: messageByteMap[type],
const resp: IMessage = {
type,
id,
waitIntercept,
}
if (data.byteLength === 39) return resp
if (type === messageEnum['requestBody'] || type === messageEnum['responseBody']) {
if (type === MessageType.REQUEST_BODY || type === MessageType.RESPONSE_BODY) {
resp.content = data.slice(39)
return resp
}
let content = new TextDecoder().decode(data.slice(39))
const contentStr = new TextDecoder().decode(data.slice(39))
let content: any
try {
content = JSON.parse(content)
content = JSON.parse(contentStr)
} catch (err) {
return null
}
@ -49,19 +81,19 @@ export const parseMessage = data => {
}
export const sendMessageEnum = {
'changeRequest': 11,
'changeResponse': 12,
'dropRequest': 13,
'dropResponse': 14,
'changeBreakPointRules': 21,
export enum SendMessageType {
CHANGE_REQUEST = 11,
CHANGE_RESPONSE = 12,
DROP_REQUEST = 13,
DROP_RESPONSE = 14,
CHANGE_BREAK_POINT_RULES = 21,
}
// type: 11/12/13/14
// messageEdit
// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes]
export const buildMessageEdit = (messageType, flow) => {
if (messageType === sendMessageEnum.dropRequest || messageType === sendMessageEnum.dropResponse) {
export const buildMessageEdit = (messageType: SendMessageType, flow: IFlow) => {
if (messageType === SendMessageType.DROP_REQUEST || messageType === SendMessageType.DROP_RESPONSE) {
const view = new Uint8Array(38)
view[0] = 1
view[1] = messageType
@ -69,16 +101,17 @@ export const buildMessageEdit = (messageType, flow) => {
return view
}
let header, body
if (messageType === sendMessageEnum.changeRequest) {
let header: Omit<IRequest, 'body'> | Omit<IResponse, 'body'>
let body: ArrayBuffer | undefined
if (messageType === SendMessageType.CHANGE_REQUEST) {
({ body, ...header } = flow.request)
} else if (messageType === sendMessageEnum.changeResponse) {
({ body, ...header } = flow.response)
} else if (messageType === SendMessageType.CHANGE_RESPONSE) {
({ body, ...header } = flow.response as IResponse)
} else {
throw new Error('invalid message type')
}
const bodyLen = (body && body.byteLength) ? body.byteLength : 0
const headerBytes = new TextEncoder().encode(JSON.stringify(header))
const len = 2 + 36 + 4 + headerBytes.byteLength + 4 + bodyLen
@ -88,7 +121,7 @@ export const buildMessageEdit = (messageType, flow) => {
view[1] = messageType
view.set(new TextEncoder().encode(flow.id), 2)
view.set(headerBytes, 2 + 36 + 4)
if (bodyLen) view.set(body, 2 + 36 + 4 + headerBytes.byteLength + 4)
if (bodyLen) view.set(body as any, 2 + 36 + 4 + headerBytes.byteLength + 4)
const view2 = new DataView(data)
view2.setUint32(2 + 36, headerBytes.byteLength)
@ -101,8 +134,8 @@ export const buildMessageEdit = (messageType, flow) => {
// type: 21
// messageMeta
// version 1 byte + type 1 byte + content left bytes
export const buildMessageMeta = (messageType, rules) => {
if (messageType !== sendMessageEnum.changeBreakPointRules) {
export const buildMessageMeta = (messageType: SendMessageType, rules: any) => {
if (messageType !== SendMessageType.CHANGE_BREAK_POINT_RULES) {
throw new Error('invalid message type')
}

@ -0,0 +1 @@
/// <reference types="react-scripts" />

@ -1,4 +1,6 @@
const reportWebVitals = onPerfEntry => {
import { ReportHandler } from 'web-vitals'
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry)

@ -1,4 +1,6 @@
export const isTextBody = payload => {
import { IRequest, IResponse } from './message'
export const isTextBody = (payload: IRequest | IResponse) => {
if (!payload) return false
if (!payload.header) return false
if (!payload.header['Content-Type']) return false
@ -6,7 +8,7 @@ export const isTextBody = payload => {
return /text|javascript|json/.test(payload.header['Content-Type'].join(''))
}
export const getSize = response => {
export const getSize = (response: IResponse) => {
if (!response) return '0'
if (!response.header) return '0'
@ -19,7 +21,7 @@ export const getSize = response => {
if (!len) return '0'
if (isNaN(len)) return '0'
if (len <= 0) return '0'
if (len < 1024) return `${len} B`
if (len < 1024*1024) return `${(len/1024).toFixed(2)} KB`
return `${(len/(1024*1024)).toFixed(2)} MB`

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save