You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 line
42 KiB
Plaintext
1 line
42 KiB
Plaintext
{"version":3,"sources":["message.ts","components/BreakPoint.tsx","utils.ts","components/EditFlow.tsx","flow.ts","App.tsx","reportWebVitals.ts","index.tsx"],"names":["MessageType","BreakPoint","props","state","show","rule","method","url","action","haveRules","handleClose","bind","handleShow","handleSave","this","setState","rules","push","onSave","length","variant","Button","size","onClick","Modal","onHide","Header","closeButton","Title","Body","Form","Group","as","Row","Label","column","sm","Col","Control","value","onChange","e","target","parseInt","Footer","React","Component","SendMessageType","allMessageBytes","REQUEST","REQUEST_BODY","RESPONSE","RESPONSE_BODY","buildMessageEdit","messageType","flow","DROP_REQUEST","DROP_RESPONSE","view","Uint8Array","set","TextEncoder","encode","id","header","body","CHANGE_REQUEST","request","CHANGE_RESPONSE","Error","response","bodyLen","byteLength","headerBytes","JSON","stringify","len","data","ArrayBuffer","view2","DataView","setUint32","isTextBody","payload","test","join","getSize","isNaN","toFixed","EditFlow","alertMsg","content","msg","firstLine","headerLines","Object","keys","map","key","valstr","bodyLines","TextDecoder","decode","stringifyRequest","statusCode","stringifyResponse","when","sections","split","vals","proto","parseRequest","showAlert","onChangeRequest","parseResponse","onChangeResponse","waitIntercept","className","msgType","onMessage","rows","Alert","FlowManager","items","_map","filterText","filterTimer","num","max","Map","filter","item","includes","no","oldest","shift","delete","get","text","callback","clearTimeout","setTimeout","App","flowMgr","ws","flows","showList","flowTab","initWs","close","host","URL","document","WebSocket","binaryType","onopen","console","log","onclose","onmessage","evt","meta","Int8Array","slice","type","resp","contentStr","parse","err","parseMessage","add","error","onerror","undefined","send","style","padding","clear","placeholder","changeFilterLazy","CHANGE_BREAK_POINT_RULES","rulesBytes","buildMessageMeta","Table","striped","bordered","f","u","path","pathname","search","classNames","renderFlow","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.5904c112.chunk.js","sourcesContent":["export enum MessageType {\n REQUEST = 1,\n REQUEST_BODY = 2,\n RESPONSE = 3,\n RESPONSE_BODY = 4,\n}\n\nexport type Header = Record<string, string[]>\n\nexport interface IRequest {\n method: string\n url: string\n proto: string\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IResponse {\n statusCode: number\n header: Header\n body?: ArrayBuffer\n}\n\nexport interface IMessage {\n type: MessageType\n id: string\n waitIntercept: boolean\n content?: ArrayBuffer | IRequest | IResponse\n}\n\nexport interface IFlow {\n id: string\n no?: number\n waitIntercept: boolean\n request: IRequest\n response?: IResponse\n}\n\nconst allMessageBytes = [\n MessageType.REQUEST,\n MessageType.REQUEST_BODY,\n MessageType.RESPONSE,\n MessageType.RESPONSE_BODY,\n]\n\n\n// type: 1/2/3/4\n// messageFlow\n// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes\nexport const parseMessage = (data: ArrayBuffer): IMessage | null => {\n if (data.byteLength < 39) return null\n const meta = new Int8Array(data.slice(0, 39))\n const version = meta[0]\n if (version !== 1) return null\n const type = meta[1] as MessageType\n if (!allMessageBytes.includes(type)) return null\n const id = new TextDecoder().decode(data.slice(2, 38))\n const waitIntercept = meta[38] === 1\n\n const resp: IMessage = {\n type,\n id,\n waitIntercept,\n }\n if (data.byteLength === 39) return resp\n if (type === MessageType.REQUEST_BODY || type === MessageType.RESPONSE_BODY) {\n resp.content = data.slice(39)\n return resp\n }\n\n const contentStr = new TextDecoder().decode(data.slice(39))\n let content: any\n try {\n content = JSON.parse(contentStr)\n } catch (err) {\n return null\n }\n\n resp.content = content\n return resp\n}\n\n\nexport enum SendMessageType {\n CHANGE_REQUEST = 11,\n CHANGE_RESPONSE = 12,\n DROP_REQUEST = 13,\n DROP_RESPONSE = 14,\n CHANGE_BREAK_POINT_RULES = 21,\n}\n\n// type: 11/12/13/14\n// messageEdit\n// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes]\nexport const buildMessageEdit = (messageType: SendMessageType, flow: IFlow) => {\n if (messageType === SendMessageType.DROP_REQUEST || messageType === SendMessageType.DROP_RESPONSE) {\n const view = new Uint8Array(38)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n return view\n }\n\n let header: Omit<IRequest, 'body'> | Omit<IResponse, 'body'>\n let body: ArrayBuffer | undefined\n\n if (messageType === SendMessageType.CHANGE_REQUEST) {\n ({ body, ...header } = flow.request)\n } else if (messageType === SendMessageType.CHANGE_RESPONSE) {\n ({ body, ...header } = flow.response as IResponse)\n } else {\n throw new Error('invalid message type')\n }\n\n const bodyLen = (body && body.byteLength) ? body.byteLength : 0\n const headerBytes = new TextEncoder().encode(JSON.stringify(header))\n const len = 2 + 36 + 4 + headerBytes.byteLength + 4 + bodyLen\n const data = new ArrayBuffer(len)\n const view = new Uint8Array(data)\n view[0] = 1\n view[1] = messageType\n view.set(new TextEncoder().encode(flow.id), 2)\n view.set(headerBytes, 2 + 36 + 4)\n if (bodyLen) view.set(body as any, 2 + 36 + 4 + headerBytes.byteLength + 4)\n\n const view2 = new DataView(data)\n view2.setUint32(2 + 36, headerBytes.byteLength)\n view2.setUint32(2 + 36 + 4 + headerBytes.byteLength, bodyLen)\n\n return view\n}\n\n\n// type: 21\n// messageMeta\n// version 1 byte + type 1 byte + content left bytes\nexport const buildMessageMeta = (messageType: SendMessageType, rules: any) => {\n if (messageType !== SendMessageType.CHANGE_BREAK_POINT_RULES) {\n throw new Error('invalid message type')\n }\n\n const rulesBytes = new TextEncoder().encode(JSON.stringify(rules))\n const view = new Uint8Array(2 + rulesBytes.byteLength)\n view[0] = 1\n view[1] = messageType\n view.set(rulesBytes, 2)\n\n return view\n}\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Row from 'react-bootstrap/Row'\nimport Col from 'react-bootstrap/Col'\n\ntype Method = 'ALL' | 'GET' | 'POST' | 'PUT' | 'DELETE' | ''\ntype Action = 1 | 2 | 3\ninterface IRule {\n method: Method\n url: string\n action: Action\n}\n\ninterface IState {\n show: boolean\n rule: IRule\n haveRules: boolean\n}\n\ninterface IProps {\n onSave: (rules: IRule[]) => void\n}\n\nclass BreakPoint extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n\n rule: {\n method: 'ALL',\n url: '',\n action: 1,\n },\n\n haveRules: false,\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n this.setState({ show: true })\n }\n\n handleSave() {\n const { rule } = this.state\n const rules: IRule[] = []\n if (rule.url) {\n rules.push({\n method: rule.method === 'ALL' ? '' : rule.method,\n url: rule.url,\n action: rule.action,\n })\n }\n\n this.props.onSave(rules)\n this.handleClose()\n\n this.setState({ haveRules: rules.length ? true : false })\n }\n\n render() {\n const { rule, haveRules } = this.state\n const variant = haveRules ? 'success' : 'primary'\n\n return (\n <div>\n <Button variant={variant} size=\"sm\" onClick={this.handleShow}>BreakPoint</Button>\n\n <Modal show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Set BreakPoint</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Method</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.method} onChange={e => { this.setState({ rule: { ...rule, method: e.target.value as Method } }) }}>\n <option>ALL</option>\n <option>GET</option>\n <option>POST</option>\n <option>PUT</option>\n <option>DELETE</option>\n </Form.Control>\n </Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>URL</Form.Label>\n <Col sm={10}><Form.Control value={rule.url} onChange={e => { this.setState({ rule: { ...rule, url: e.target.value } }) }} /></Col>\n </Form.Group>\n\n <Form.Group as={Row}>\n <Form.Label column sm={2}>Action</Form.Label>\n <Col sm={10}>\n <Form.Control as=\"select\" value={rule.action} onChange={e => { this.setState({ rule: { ...rule, action: parseInt(e.target.value) as Action } }) }}>\n <option value=\"1\">Request</option>\n <option value=\"2\">Response</option>\n <option value=\"3\">Both</option>\n </Form.Control>\n </Col>\n </Form.Group>\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n </div>\n )\n }\n}\n\nexport default BreakPoint\n","import { IRequest, IResponse } from './message'\n\nexport const isTextBody = (payload: IRequest | IResponse) => {\n if (!payload) return false\n if (!payload.header) return false\n if (!payload.header['Content-Type']) return false\n\n return /text|javascript|json/.test(payload.header['Content-Type'].join(''))\n}\n\nexport const getSize = (response: IResponse) => {\n if (!response) return '0'\n if (!response.header) return '0'\n\n let len\n if (response.header['Content-Length']) {\n len = parseInt(response.header['Content-Length'][0])\n } else if (response && response.body) {\n len = response.body.byteLength\n }\n if (!len) return '0'\n if (isNaN(len)) return '0'\n if (len <= 0) return '0'\n\n if (len < 1024) return `${len} B`\n if (len < 1024*1024) return `${(len/1024).toFixed(2)} KB`\n return `${(len/(1024*1024)).toFixed(2)} MB`\n}\n","import React from 'react'\nimport Button from 'react-bootstrap/Button'\nimport Modal from 'react-bootstrap/Modal'\nimport Form from 'react-bootstrap/Form'\nimport Alert from 'react-bootstrap/Alert'\n\nimport { SendMessageType, buildMessageEdit, IRequest, IResponse, Header, IFlow } from '../message'\nimport { isTextBody } from '../utils'\n\n\nconst stringifyRequest = (request: IRequest) => {\n const firstLine = `${request.method} ${request.url}`\n const headerLines = Object.keys(request.header).map(key => {\n const valstr = request.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (request.body && isTextBody(request)) bodyLines = new TextDecoder().decode(request.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseRequest = (content: string): IRequest | undefined => {\n const sections = content.split('\\n\\n')\n if (sections.length !== 3) return\n\n const [firstLine, headerLines, bodyLines] = sections\n const [method, url] = firstLine.split(' ')\n if (!method || !url) return\n\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n method,\n url,\n proto: '',\n header,\n body,\n }\n}\n\nconst stringifyResponse = (response: IResponse) => {\n const firstLine = `${response.statusCode}`\n const headerLines = Object.keys(response.header).map(key => {\n const valstr = response.header[key].join(' \\t ') // for parse convenience\n return `${key}: ${valstr}`\n }).join('\\n')\n\n let bodyLines = ''\n if (response.body && isTextBody(response)) bodyLines = new TextDecoder().decode(response.body)\n\n return `${firstLine}\\n\\n${headerLines}\\n\\n${bodyLines}`\n}\n\nconst parseResponse = (content: string): IResponse | undefined => {\n const sections = content.split('\\n\\n')\n if (sections.length !== 3) return\n\n const [firstLine, headerLines, bodyLines] = sections\n const statusCode = parseInt(firstLine)\n if (isNaN(statusCode)) return\n\n const header: Header = {}\n for (const line of headerLines.split('\\n')) {\n const [key, vals] = line.split(': ')\n if (!key || !vals) return\n header[key] = vals.split(' \\t ')\n }\n\n let body: ArrayBuffer | undefined\n if (bodyLines) body = new TextEncoder().encode(bodyLines)\n\n return {\n statusCode,\n header,\n body,\n }\n}\n\n\ninterface IProps {\n flow: IFlow\n onChangeRequest: (request: IRequest) => void\n onChangeResponse: (response: IResponse) => void\n onMessage: (msg: ArrayBufferLike) => void\n}\n\ninterface IState {\n show: boolean\n alertMsg: string\n content: string\n}\n\nclass EditFlow extends React.Component<IProps, IState> {\n constructor(props: IProps) {\n super(props)\n\n this.state = {\n show: false,\n alertMsg: '',\n content: '',\n }\n\n this.handleClose = this.handleClose.bind(this)\n this.handleShow = this.handleShow.bind(this)\n this.handleSave = this.handleSave.bind(this)\n }\n\n showAlert(msg: string) {\n this.setState({ alertMsg: msg })\n }\n\n handleClose() {\n this.setState({ show: false })\n }\n\n handleShow() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n let content = ''\n if (when === 'request') {\n content = stringifyRequest(flow.request)\n } else {\n content = stringifyResponse(flow.response as IResponse)\n }\n\n this.setState({ show: true, alertMsg: '', content })\n }\n\n handleSave() {\n const { flow } = this.props\n const when = flow.response ? 'response' : 'request'\n\n const { content } = this.state\n\n if (when === 'request') {\n const request = parseRequest(content)\n if (!request) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeRequest(request)\n this.handleClose()\n } else {\n const response = parseResponse(content)\n if (!response) {\n this.showAlert('parse error')\n return\n }\n\n this.props.onChangeResponse(response)\n this.handleClose()\n }\n }\n\n render() {\n const { flow } = this.props\n if (!flow.waitIntercept) return null\n\n const { alertMsg } = this.state\n\n const when = flow.response ? 'response' : 'request'\n\n return (\n <div className=\"flow-wait-area\">\n\n <Button size=\"sm\" onClick={this.handleShow}>Edit</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.CHANGE_RESPONSE : SendMessageType.CHANGE_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Continue</Button>\n\n <Button size=\"sm\" onClick={() => {\n const msgType = when === 'response' ? SendMessageType.DROP_RESPONSE : SendMessageType.DROP_REQUEST\n const msg = buildMessageEdit(msgType, flow)\n this.props.onMessage(msg)\n }}>Drop</Button>\n\n\n <Modal size=\"lg\" show={this.state.show} onHide={this.handleClose}>\n <Modal.Header closeButton>\n <Modal.Title>Edit {when === 'request' ? 'Request' : 'Response'}</Modal.Title>\n </Modal.Header>\n\n <Modal.Body>\n <Form.Group>\n <Form.Control as=\"textarea\" rows={10} value={this.state.content} onChange={e => { this.setState({ content: e.target.value }) }} />\n </Form.Group>\n {\n !alertMsg ? null : <Alert variant=\"danger\">{alertMsg}</Alert>\n }\n </Modal.Body>\n\n <Modal.Footer>\n <Button variant=\"secondary\" onClick={this.handleClose}>\n Close\n </Button>\n <Button variant=\"primary\" onClick={this.handleSave}>\n Save\n </Button>\n </Modal.Footer>\n </Modal>\n\n </div>\n )\n }\n}\n\nexport default EditFlow\n","import { IFlow } from './message'\n\nexport class FlowManager {\n private items: IFlow[]\n private _map: Map<string, IFlow>\n private filterText: string\n private filterTimer: number | null\n private num: number\n private max: number\n\n constructor() {\n this.items = []\n this._map = new Map()\n this.filterText = ''\n this.filterTimer = null\n this.num = 0\n\n this.max = 1000\n }\n\n showList() {\n if (!this.filterText) return this.items\n return this.items.filter(item => {\n return item.request.url.includes(this.filterText)\n })\n }\n\n add(item: IFlow) {\n item.no = ++this.num\n this.items.push(item)\n this._map.set(item.id, item)\n\n if (this.items.length > this.max) {\n const oldest = this.items.shift()\n if (oldest) this._map.delete(oldest.id)\n }\n }\n\n get(id: string) {\n return this._map.get(id)\n }\n\n changeFilter(text: string) {\n this.filterText = text\n }\n\n changeFilterLazy(text: string, callback: () => void) {\n if (this.filterTimer) {\n clearTimeout(this.filterTimer)\n this.filterTimer = null\n }\n\n this.filterTimer = setTimeout(() => {\n this.filterText = text\n callback()\n }, 300) as any\n }\n\n clear() {\n this.items = []\n this._map = new Map()\n }\n}\n","import React from 'react'\nimport Table from 'react-bootstrap/Table'\nimport Form from 'react-bootstrap/Form'\nimport Button from 'react-bootstrap/Button'\nimport './App.css'\n\nimport BreakPoint from './components/BreakPoint'\nimport EditFlow from './components/EditFlow'\n\nimport { FlowManager } from './flow'\nimport { isTextBody, getSize } from './utils'\nimport { parseMessage, SendMessageType, buildMessageMeta, IFlow, MessageType, IRequest, IResponse } from './message'\n\ninterface IState {\n flows: IFlow[]\n flow: IFlow | null\n flowTab: 'Headers' | 'Preview' | 'Response'\n}\n\nclass App extends React.Component<any, IState> {\n private flowMgr: FlowManager\n private ws: WebSocket | null\n\n constructor(props: any) {\n super(props)\n\n this.flowMgr = new FlowManager()\n\n this.state = {\n flows: this.flowMgr.showList(),\n flow: null,\n\n flowTab: 'Headers', // Headers, Preview, Response\n }\n\n this.ws = null\n }\n\n componentDidMount() {\n this.initWs()\n }\n\n componentWillUnmount() {\n if (this.ws) {\n this.ws.close()\n }\n }\n\n initWs() {\n if (this.ws) return\n\n let host\n if (process.env.NODE_ENV === 'development') {\n host = 'localhost:9081'\n } else {\n host = new URL(document.URL).host\n }\n this.ws = new WebSocket(`ws://${host}/echo`)\n this.ws.binaryType = 'arraybuffer'\n this.ws.onopen = () => { console.log('OPEN') }\n this.ws.onclose = () => { console.log('CLOSE') }\n this.ws.onmessage = evt => {\n const msg = parseMessage(evt.data)\n if (!msg) {\n console.error('parse error:', evt.data)\n return\n }\n // console.log('msg:', msg)\n\n if (msg.type === MessageType.REQUEST) {\n const flow = { id: msg.id, request: msg.content as IRequest, waitIntercept: msg.waitIntercept }\n this.flowMgr.add(flow)\n this.setState({ flows: this.flowMgr.showList() })\n }\n else if (msg.type === MessageType.REQUEST_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.waitIntercept = msg.waitIntercept\n flow.request.body = msg.content as ArrayBuffer\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow) return\n flow.waitIntercept = msg.waitIntercept\n flow.response = msg.content as IResponse\n this.setState({ flows: this.state.flows })\n }\n else if (msg.type === MessageType.RESPONSE_BODY) {\n const flow = this.flowMgr.get(msg.id)\n if (!flow || !flow.response) return\n flow.waitIntercept = msg.waitIntercept\n flow.response.body = msg.content as ArrayBuffer\n this.setState({ flows: this.state.flows })\n }\n }\n this.ws.onerror = evt => {\n console.log('ERROR:', evt)\n }\n }\n\n renderFlow() {\n const { flow, flowTab } = this.state\n if (!flow) return null\n\n const request = flow.request\n const response: IResponse = (flow.response || {}) as any\n\n return (\n <div className=\"flow-detail\">\n <div className=\"header-tabs\">\n <span onClick={() => { this.setState({ flow: null }) }}>x</span>\n <span className={flowTab === 'Headers' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Headers' }) }}>Headers</span>\n <span className={flowTab === 'Preview' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Preview' }) }}>Preview</span>\n <span className={flowTab === 'Response' ? 'selected' : undefined} onClick={() => { this.setState({ flowTab: 'Response' }) }}>Response</span>\n\n <EditFlow\n flow={flow}\n onChangeRequest={request => {\n flow.request.method = request.method\n flow.request.url = request.url\n flow.request.header = request.header\n if (isTextBody(flow.request)) flow.request.body = request.body\n this.setState({ flows: this.state.flows })\n }}\n onChangeResponse={response => {\n if (!flow.response) flow.response = {} as IResponse\n\n flow.response.statusCode = response.statusCode\n flow.response.header = response.header\n if (isTextBody(flow.response)) flow.response.body = response.body\n this.setState({ flows: this.state.flows })\n }}\n onMessage={msg => {\n if (this.ws) this.ws.send(msg)\n flow.waitIntercept = false\n this.setState({ flows: this.state.flows })\n }}\n />\n\n </div>\n\n <div style={{ padding: '20px' }}>\n {\n !(flowTab === 'Headers') ? null :\n <div>\n <div className=\"header-block\">\n <p>General</p>\n <div className=\"header-block-content\">\n <p>Request URL: {request.url}</p>\n <p>Request Method: {request.method}</p>\n <p>Status Code: {`${response.statusCode || '(pending)'}`}</p>\n </div>\n </div>\n\n {\n !(response.header) ? null :\n <div className=\"header-block\">\n <p>Response Headers</p>\n <div className=\"header-block-content\">\n {\n Object.keys(response.header).map(key => {\n return (\n <p key={key}>{key}: {response.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n }\n\n <div className=\"header-block\">\n <p>Request Headers</p>\n <div className=\"header-block-content\">\n {\n !(request.header) ? null :\n Object.keys(request.header).map(key => {\n return (\n <p key={key}>{key}: {request.header[key].join(' ')}</p>\n )\n })\n }\n </div>\n </div>\n\n {\n !(request.body && request.body.byteLength) ? null :\n <div className=\"header-block\">\n <p>Request Body</p>\n <div className=\"header-block-content\">\n <p>\n {\n !(isTextBody(request)) ? 'Not text' :\n new TextDecoder().decode(request.body)\n }\n </p>\n </div>\n </div>\n }\n\n </div>\n }\n\n {\n !(flowTab === 'Response') ? null :\n !(response.body && response.body.byteLength) ? <div>No response</div> :\n !(isTextBody(response)) ? <div>Not text response</div> :\n <div>\n {new TextDecoder().decode(response.body)}\n </div>\n }\n </div>\n\n </div>\n )\n }\n\n render() {\n const { flows } = this.state\n return (\n <div className=\"main-table-wrap\">\n <div className=\"top-control\">\n <div><Button size=\"sm\" onClick={() => {\n this.flowMgr.clear()\n this.setState({ flows: this.flowMgr.showList(), flow: null })\n }}>Clear</Button></div>\n <div>\n <Form.Control\n size=\"sm\" placeholder=\"Filter\"\n onChange={(e) => {\n const value = e.target.value\n this.flowMgr.changeFilterLazy(value, () => {\n this.setState({ flows: this.flowMgr.showList() })\n })\n }}\n >\n </Form.Control>\n </div>\n\n <BreakPoint onSave={rules => {\n const msg = buildMessageMeta(SendMessageType.CHANGE_BREAK_POINT_RULES, rules)\n if (this.ws) this.ws.send(msg)\n }} />\n </div>\n\n <Table striped bordered size=\"sm\">\n <thead>\n <tr>\n <th>No</th>\n <th>Host</th>\n <th>Path</th>\n <th>Method</th>\n <th>Status</th>\n <th>Size</th>\n </tr>\n </thead>\n <tbody>\n {\n flows.map(f => {\n const url = f.request.url\n const u = new URL(url)\n let host = u.host\n if (host.length > 35) host = host.slice(0, 35) + '...'\n let path = u.pathname + u.search\n if (path.length > 65) path = path.slice(0, 65) + '...'\n\n const request = f.request\n const response: IResponse = (f.response || {}) as any\n\n const classNames = []\n if (this.state.flow && this.state.flow.id === f.id) classNames.push('tr-selected')\n if (f.waitIntercept) classNames.push('tr-wait-intercept')\n\n return (\n <tr className={classNames.length ? classNames.join(' ') : undefined} key={f.id}\n onClick={() => {\n this.setState({ flow: f })\n }}\n >\n <td>{f.no}</td>\n <td>{host}</td>\n <td>{path}</td>\n <td>{request.method}</td>\n <td>{response.statusCode || '(pending)'}</td>\n <td>{getSize(response)}</td>\n </tr>\n )\n })\n }\n </tbody>\n </Table>\n\n {this.renderFlow()}\n </div>\n )\n }\n}\n\nexport default App\n","import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry)\n getFID(onPerfEntry)\n getFCP(onPerfEntry)\n getLCP(onPerfEntry)\n getTTFB(onPerfEntry)\n })\n }\n}\n\nexport default reportWebVitals\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport 'bootstrap/dist/css/bootstrap.min.css'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals()\n"],"sourceRoot":""} |