@buoy-gg/network 7.0.78 → 7.0.80
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.
- package/README.md +76 -2
- package/lib/commonjs/expo-network.js +1 -0
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.web.js +1 -1
- package/lib/commonjs/netinfo.js +1 -0
- package/lib/commonjs/network/components/NetworkEventDetailView.js +2 -2
- package/lib/commonjs/network/components/NetworkEventDetailView.web.js +2 -2
- package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -2
- package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +1 -1
- package/lib/commonjs/network/components/NetworkModal.js +1 -1
- package/lib/commonjs/network/components/sockets/NetworkSocketsButton.js +1 -0
- package/lib/commonjs/network/components/sockets/NetworkSocketsScreen.js +1 -0
- package/lib/commonjs/network/components/sockets/SocketFrameView.js +1 -0
- package/lib/commonjs/network/components/sockets/SocketListView.js +1 -0
- package/lib/commonjs/network/components/sockets/SocketRows.js +1 -0
- package/lib/commonjs/network/components/sockets/SocketTricksView.js +1 -0
- package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -1
- package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +1 -1
- package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +1 -1
- package/lib/commonjs/network/conditions/NetworkFloatingTool.js +1 -1
- package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +1 -1
- package/lib/commonjs/network/conditions/connectivity/netInfoFacade.js +1 -0
- package/lib/commonjs/network/conditions/connectivity/patchNetwork.js +1 -0
- package/lib/commonjs/network/conditions/pacer.js +1 -0
- package/lib/commonjs/network/conditions/profiles.js +1 -0
- package/lib/commonjs/network/conditions/remoteState.js +1 -0
- package/lib/commonjs/network/conditions/store.js +1 -1
- package/lib/commonjs/network/conditions/wait.js +1 -1
- package/lib/commonjs/network/conditions/xhr.js +1 -1
- package/lib/commonjs/network/hooks/useSocketsState.js +1 -0
- package/lib/commonjs/network/overrides/engine.js +1 -1
- package/lib/commonjs/network/overrides/matchRule.js +1 -1
- package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -1
- package/lib/commonjs/network/sockets/findProblems.js +1 -0
- package/lib/commonjs/network/sockets/foldFrames.js +1 -0
- package/lib/commonjs/network/sockets/format.js +1 -0
- package/lib/commonjs/network/sockets/readMessage.js +1 -0
- package/lib/commonjs/network/sockets/socketMoments.js +1 -0
- package/lib/commonjs/network/sockets/socketStore.js +1 -0
- package/lib/commonjs/network/sockets/socketsSyncAdapter.js +1 -0
- package/lib/commonjs/network/sockets/types.js +1 -0
- package/lib/commonjs/network/sockets/webSocketPatch.js +1 -0
- package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -1
- package/lib/commonjs/network/utils/generateNetworkCopyText.js +1 -0
- package/lib/commonjs/network/utils/networkEventStore.js +1 -1
- package/lib/commonjs/network/utils/networkListener.js +4 -4
- package/lib/commonjs/network/utils/startNetworkCapture.js +1 -1
- package/lib/commonjs/preset.js +1 -1
- package/lib/module/expo-network.js +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.web.js +1 -1
- package/lib/module/netinfo.js +1 -0
- package/lib/module/network/components/NetworkEventDetailView.js +2 -2
- package/lib/module/network/components/NetworkEventDetailView.web.js +2 -2
- package/lib/module/network/components/NetworkEventItemCompact.js +2 -2
- package/lib/module/network/components/NetworkEventItemCompact.web.js +1 -1
- package/lib/module/network/components/NetworkModal.js +1 -1
- package/lib/module/network/components/sockets/NetworkSocketsButton.js +1 -0
- package/lib/module/network/components/sockets/NetworkSocketsScreen.js +1 -0
- package/lib/module/network/components/sockets/SocketFrameView.js +1 -0
- package/lib/module/network/components/sockets/SocketListView.js +1 -0
- package/lib/module/network/components/sockets/SocketRows.js +1 -0
- package/lib/module/network/components/sockets/SocketTricksView.js +1 -0
- package/lib/module/network/conditions/NetworkConditionsControl.js +1 -1
- package/lib/module/network/conditions/NetworkConditionsControl.test.js +1 -1
- package/lib/module/network/conditions/NetworkConditionsIcon.js +1 -1
- package/lib/module/network/conditions/NetworkFloatingTool.js +1 -1
- package/lib/module/network/conditions/NetworkFloatingTool.test.js +1 -1
- package/lib/module/network/conditions/connectivity/netInfoFacade.js +1 -0
- package/lib/module/network/conditions/connectivity/patchNetwork.js +1 -0
- package/lib/module/network/conditions/pacer.js +1 -0
- package/lib/module/network/conditions/profiles.js +1 -0
- package/lib/module/network/conditions/remoteState.js +1 -0
- package/lib/module/network/conditions/store.js +1 -1
- package/lib/module/network/conditions/wait.js +1 -1
- package/lib/module/network/conditions/xhr.js +1 -1
- package/lib/module/network/hooks/useSocketsState.js +1 -0
- package/lib/module/network/overrides/engine.js +1 -1
- package/lib/module/network/overrides/matchRule.js +1 -1
- package/lib/module/network/overrides/overrideRulesStore.js +1 -1
- package/lib/module/network/sockets/findProblems.js +1 -0
- package/lib/module/network/sockets/foldFrames.js +1 -0
- package/lib/module/network/sockets/format.js +1 -0
- package/lib/module/network/sockets/readMessage.js +1 -0
- package/lib/module/network/sockets/socketMoments.js +1 -0
- package/lib/module/network/sockets/socketStore.js +1 -0
- package/lib/module/network/sockets/socketsSyncAdapter.js +1 -0
- package/lib/module/network/sockets/types.js +1 -0
- package/lib/module/network/sockets/webSocketPatch.js +1 -0
- package/lib/module/network/sync/networkSyncAdapter.js +1 -1
- package/lib/module/network/utils/generateNetworkCopyText.js +23 -22
- package/lib/module/network/utils/networkEventStore.js +1 -1
- package/lib/module/network/utils/networkListener.js +4 -4
- package/lib/module/network/utils/startNetworkCapture.js +1 -1
- package/lib/module/preset.js +1 -1
- package/lib/typescript/expo-network.d.ts +2 -0
- package/lib/typescript/index.d.ts +14 -2
- package/lib/typescript/index.web.d.ts +7 -2
- package/lib/typescript/netinfo.d.ts +3 -0
- package/lib/typescript/network/components/sockets/NetworkSocketsButton.d.ts +17 -0
- package/lib/typescript/network/components/sockets/NetworkSocketsScreen.d.ts +19 -0
- package/lib/typescript/network/components/sockets/SocketFrameView.d.ts +9 -0
- package/lib/typescript/network/components/sockets/SocketListView.d.ts +9 -0
- package/lib/typescript/network/components/sockets/SocketRows.d.ts +19 -0
- package/lib/typescript/network/components/sockets/SocketTricksView.d.ts +23 -0
- package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts +5 -2
- package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts +4 -3
- package/lib/typescript/network/conditions/connectivity/netInfoFacade.d.ts +3 -0
- package/lib/typescript/network/conditions/connectivity/patchNetwork.d.ts +24 -0
- package/lib/typescript/network/conditions/pacer.d.ts +16 -0
- package/lib/typescript/network/conditions/profiles.d.ts +57 -0
- package/lib/typescript/network/conditions/remoteState.d.ts +4 -0
- package/lib/typescript/network/conditions/store.d.ts +45 -19
- package/lib/typescript/network/conditions/xhr.d.ts +1 -1
- package/lib/typescript/network/hooks/useSocketsState.d.ts +3 -0
- package/lib/typescript/network/overrides/engine.d.ts +14 -0
- package/lib/typescript/network/overrides/matchRule.d.ts +3 -0
- package/lib/typescript/network/overrides/overrideRulesStore.d.ts +22 -0
- package/lib/typescript/network/overrides/types.d.ts +33 -0
- package/lib/typescript/network/sockets/findProblems.d.ts +31 -0
- package/lib/typescript/network/sockets/foldFrames.d.ts +50 -0
- package/lib/typescript/network/sockets/format.d.ts +19 -0
- package/lib/typescript/network/sockets/readMessage.d.ts +41 -0
- package/lib/typescript/network/sockets/socketMoments.d.ts +24 -0
- package/lib/typescript/network/sockets/socketStore.d.ts +94 -0
- package/lib/typescript/network/sockets/socketsSyncAdapter.d.ts +66 -0
- package/lib/typescript/network/sockets/types.d.ts +139 -0
- package/lib/typescript/network/sockets/webSocketPatch.d.ts +57 -0
- package/lib/typescript/network/sync/networkSyncAdapter.d.ts +29 -12
- package/lib/typescript/network/types/index.d.ts +6 -0
- package/lib/typescript/network/utils/networkListener.d.ts +10 -0
- package/lib/web/index.mjs +60 -59
- package/package.json +26 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export function throwIfAborted(e){if(!e?.aborted)return;if(e.reason!==void 0)throw e.reason;const r=new Error("The request was aborted.");r.name="AbortError";throw r}export function waitBeforeDispatch(e,r){return new Promise((
|
|
1
|
+
"use strict";import{realSetTimeout as i,realClearTimeout as s}from"../utils/realNow";export function throwIfAborted(e){if(!e?.aborted)return;if(e.reason!==void 0)throw e.reason;const r=new Error("The request was aborted.");r.name="AbortError";throw r}export function waitBeforeDispatch(e,r){return new Promise((c,o)=>{try{throwIfAborted(r)}catch(t){o(t);return}const n=()=>r?.removeEventListener("abort",a);const a=()=>{s(u);n();try{throwIfAborted(r)}catch(t){o(t)}};const u=i(()=>{n();c()},e);r?.addEventListener("abort",a,{once:true})})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{canSynthesize as
|
|
1
|
+
"use strict";import{bodyByteLength as A,chunkSize as $,createBytePacer as ee,paceByteCount as B,uploadSize as te}from"./pacer";import{canSynthesize as re,completeNativeOverride as ne,runOverride as se}from"../overrides/applyToXhr";import{realClearTimeout as x,realNow as C,realSetTimeout as U}from"../utils/realNow";export function runConditionXhr(O,v,i,a,T,W){if(!re(O)){if(i.downloadBytesPerSecond)throw new Error("Byte caps need RN XHR. This XHR only supports waits and Offline.");const t={id:"condition",enabled:true,urlPattern:v,kind:"delay",hits:0,seen:0,createdAt:Date.now()};const n=i.profile==="offline"?{kind:"fail",rule:t,failKind:"network",delayMs:0}:a?{...a,delayMs:i.delayMs+a.delayMs}:{kind:"delay",rule:t,delayMs:i.delayMs};if(!se(O,v,n,T))throw new Error("Network conditions are unavailable for this XMLHttpRequest implementation.");return}const e=O;if(e.readyState!==1||e._sent)throw new Error("Request is not open or has already been sent.");const q=C();let u=e.timeout;let s=false;const g=new AbortController;const L=[];let D=false;let k;let N;const z=e.abort;const K=e.open;const F=Object.getOwnPropertyDescriptor(e,"abort");const G=Object.getOwnPropertyDescriptor(e,"open");const J=Object.getOwnPropertyDescriptor(e,"timeout");const R=(t,n)=>{if(n)Object.defineProperty(e,t,n);else delete e[t]};const b=()=>{if(s)return;s=true;x(N);g.abort();L.forEach(t=>t());x(k);e.removeEventListener("loadend",b);R("abort",F);R("open",G);R("timeout",J);e.timeout=u};const _=(t,n)=>{if(s)return;Object.assign(e,{readyState:4});z.call(e);e._aborted=false;e._hasError=true;e._timedOut=t;e._response=n??(t?"Request timed out (Buoy conditions)":"Network request failed (Buoy Offline)");e.setReadyState(4);b()};const Q=()=>u>0&&C()-q>=u;const X=()=>{x(k);if(u>0)k=U(()=>_(true),Math.max(0,u-(C()-q)))};Object.defineProperty(e,"timeout",{configurable:true,get:()=>D?0:u,set:t=>{u=Math.max(0,Number(t)||0);X()}});Object.defineProperty(e,"abort",{configurable:true,value:()=>{if(!s){z.call(e);b()}}});Object.defineProperty(e,"open",{configurable:true,value:(...t)=>{const n=Reflect.apply(K,e,t);b();return n}});e._sent=true;e._requestId=null;e.addEventListener("loadend",b);X();const l=e;const w=(t,n)=>{const d=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(e,t,{configurable:true,writable:true,value:n});L.push(()=>R(t,d))};const V=(t,n,d)=>{const m=new Event("progress");Object.defineProperties(m,{loaded:{value:n},total:{value:d},lengthComputable:{value:true}});t.dispatchEvent(m)};const y=i.downloadBytesPerSecond;if(y&&typeof l.__didReceiveData==="function"&&typeof l.__didCompleteResponse==="function"){const t=l.__didReceiveData.bind(e);const n=l.__didReceiveIncrementalData?.bind(e);const d=l.__didCompleteResponse.bind(e);const m=l.__didReceiveDataProgress?.bind(e);let H=Promise.resolve();let h=0;const Y=ee(y);const S=o=>{H=H.then(async()=>{if(!s)await o()}).catch(r=>{if(!s)_(false,r instanceof Error?r.message:String(r))})};const I=async(o,r,c=-1)=>{const j=!e.responseType||e.responseType==="text"||e.responseType==="json";if(j&&typeof r==="string"&&n){const f=new TextEncoder().encode(r);const M=new TextDecoder;for(let p=0;p<f.byteLength;){const P=Math.min($(y),f.byteLength-p);await Y(P,g.signal);if(s)return;const Z=M.decode(f.subarray(p,p+P),{stream:p+P<f.byteLength});p+=P;h+=P;n(o,Z,h,c);m?.(o,h,c)}}else{const f=typeof r==="object"&&r?r.size:e.responseType==="arraybuffer"&&typeof r==="string"?Math.max(0,r.length*3/4-(r.endsWith("==")?2:r.endsWith("=")?1:0)):A(r);if(typeof f!=="number")throw new Error("Cannot read this response size.");const M=h;await B(f,y,g.signal,p=>{h=M+p;m?.(o,h,c<0?f:c)});if(!s)t(o,r)}};w("__didReceiveData",(o,r)=>S(()=>I(o,r)));w("__didReceiveIncrementalData",(o,r,c,j)=>S(()=>I(o,r,j)));w("__didReceiveDataProgress",()=>{});w("__didCompleteResponse",(o,r,c)=>{if(r){d(o,r,c);return}S(async()=>{if(!s)d(o,r,c)})})}else if(y){b();throw new Error("This XHR lacks the RN byte hooks.")}const E=typeof l.__didUploadProgress==="function"?l.__didUploadProgress.bind(e):void 0;if(i.uploadBytesPerSecond&&E)w("__didUploadProgress",()=>{});N=U(()=>{void(async()=>{if(s)return;if(Q()){_(true);return}if(i.profile==="offline"){_(false);return}if(i.uploadBytesPerSecond){const t=(i.uploadCap??te(W)).knownBytes;await B(t,i.uploadBytesPerSecond,g.signal,(n,d)=>{if(E)E(e._requestId,n,d);else if(e.upload)V(e.upload,n,d)})}if(s)return;if(a&&a.kind!=="delay"){if(y&&a.kind==="respond")await B(A(a.body)??0,y,g.signal);if(!s)ne(e,v,a);return}e._sent=false;D=true;try{T()}finally{D=false}})().catch(t=>{if(!s)_(false,t instanceof Error?t.message:String(t))})},i.delayMs+(a?.delayMs??0))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{useEffect as i,useState as S}from"react";import{socketStore as e}from"../sockets/socketStore";const f=100;export function useSocketsState(r=false){const[a,s]=S(()=>e.getState());i(()=>{if(r)return;s(e.getState());let t=null;let o=0;const n=()=>{t=null;o=Date.now();s(e.getState())};const u=e.subscribeState(()=>{if(t)return;const c=Math.max(0,f-(Date.now()-o));t=setTimeout(n,c)});return()=>{u();if(t)clearTimeout(t)}},[r]);return a}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getAccountAccess as
|
|
1
|
+
"use strict";import{getAccountAccess as f,hasAccountAccess as d,subscribeAccountAccess as _}from"@buoy-gg/shared-ui";import{findMatchingRule as c,shouldApply as a,toOutcome as p}from"./resolveOverride";import{realClearTimeout as R,realSetTimeout as g}from"../utils/realNow";let e=null;export function setOverrideHooks(t){e=t}export function overrideRulesReady(){return e?.ready?.()??Promise.resolve()}export function overrideRulesLoaded(){return e?.isReady?.()??true}export function overrideRulesNeedBody(){return!!e?.getRules().some(t=>t.enabled&&(t.bodyIncludes||t.graphqlOperation||t.bodyJson!==void 0))}export function overridesCanApply(){return d()&&!(typeof __DEV__!=="undefined"&&!__DEV__)}export const OVERRIDES_INACTIVE_REASON="Response overrides never apply in a release build \u2014 the rule is saved but will not affect any request.";export function inspectEngine(t,o){return{hooksInstalled:e!==null,devFlag:typeof __DEV__==="undefined"?"undefined":__DEV__,ruleCount:e?e.getRules().length:0,matches:e?c(t,o,e.getRules())!==null:false}}const m=3e3;export function accountCheckFor(t,o,i,l){if(!e||d())return null;if(typeof __DEV__!=="undefined"&&!__DEV__)return null;if(f().status!=="initializing")return null;if(!c(t,o,e.getRules(),i,l))return null;return new Promise(r=>{let n=()=>{};const u=()=>{R(s);n();r()};const s=g(u,m);n=_(()=>{if(f().status!=="initializing")u()})})}export function overrideForRequest(t,o,i,l){if(!e)return null;if(typeof __DEV__!=="undefined"&&!__DEV__)return null;let r=e.getRules();if(r.length===0)return null;if(!d()){r=r.filter(s=>s.sandbox===true);if(r.length===0)return null}const n=c(t,o,r,i,l);if(!n)return null;const u=a(n);e.recordMatch(n.id);if(!u)return null;e.recordHit(n.id);return p(n)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const f="[]{}()\\.^$+|-,?";export function escapeRegex(e){let r="";for(let t=0;t<e.length;t++){const n=e.charAt(t);if(f.indexOf(n)!==-1){r+="\\"}r+=n}return r.split("*").join(".*")}const a=new Map;export function compilePattern(e){const r=a.get(e);if(r)return r;const t=e.startsWith("/")?`[a-zA-Z][a-zA-Z0-9+.-]*://[^/]*${escapeRegex(e)}`:escapeRegex(e);const n=new RegExp(`^${t}$`);if(a.size>200)a.clear();a.set(e,n);return n}function c(e,r){if(!e)return false;const t=r.toLowerCase();for(const n of Object.keys(e)){if(n.toLowerCase()===t&&e[n]!==void 0&&e[n]!=="")return true}return false}export function canonicalJson(e){const r=t=>Array.isArray(t)?t.map(r):t&&typeof t==="object"?Object.fromEntries(Object.keys(t).sort().map(n=>[n,r(t[n])])):t;return JSON.stringify(r(e))??"null"}function u(e,r,t,n){if(typeof e!=="string"||!e.includes(r))return false;try{const s=JSON.parse(e);if(n&&Array.isArray(s))return false;const o=Array.isArray(s)?s:[s];return o.some(i=>{if(!i||typeof i!=="object"||i.operationName!==r)return false;return t===void 0||canonicalJson(i.variables??{})===t})}catch{return false}}function l(e,r){if(typeof e!=="string")return false;try{return canonicalJson(JSON.parse(e))===r}catch{return JSON.stringify(e)===r}}export function ruleMatches(e,r,t,n,s){if(e.methods&&e.methods.length>0){if(!e.methods.includes(t.toUpperCase()))return false}if(e.requireHeader&&!c(n,e.requireHeader))return false;if(e.bodyIncludes&&(typeof s!=="string"||!s.includes(e.bodyIncludes)))return false;if(e.graphqlOperation&&!u(s,e.graphqlOperation,e.graphqlVariables,e.graphqlSingle))return false;if(e.bodyJson!==void 0&&!l(s,e.bodyJson))return false;try{return compilePattern(e.urlPattern).test(r)}catch{return false}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{devToolsStorageKeys as
|
|
1
|
+
"use strict";import{devToolsStorageKeys as a,persistentStorage as d,setItemChecked as k}from"@buoy-gg/shared-ui";import{addNetworkListener as S,getNetworkListenerCount as h,startNetworkListener as v,stopNetworkListener as c}from"../utils/networkListener";import{setOverrideHooks as E}from"./engine";import{isSpent as T}from"./resolveOverride";import{MAX_RULES as u,STATUS_MAX as R,STATUS_MIN as A}from"./types";import{realNow as f}from"../utils/realNow";const w=800;const x=3;function C(){const r=`${a.network.overrides()}_launch`;try{const t=globalThis.sessionStorage;if(!t)return false;if(t.getItem(r))return true;t.setItem(r,"1")}catch{}return false}const m=Object.freeze([]);const b=()=>`${a.base}_bug_links_loaded`;function p(){if(typeof navigator!=="undefined"&&navigator.product==="ReactNative")return null;try{return globalThis.localStorage??null}catch{return null}}let o={raw:null,blocks:false};function L(){let r;try{r=p()?.getItem(b())??null}catch{return false}if(r===o.raw)return o.blocks;o={raw:r,blocks:P(r)};return o.blocks}function P(r){try{if(!r)return false;const t=JSON.parse(r);if(t.block===void 0)return t.options?.replay!==false&&t.report?.replay?.active===true;return t.block===true}catch{return true}}const _=5e3;const O=Object.freeze([Object.freeze({id:"bug-case-other-tab",name:"Bug case (loaded in another tab)",enabled:true,sandbox:true,urlPattern:"*",kind:"fail",failKind:"network"})]);const I=250;const M=["respond","fail","delay"];function y(r){if(!Array.isArray(r))return[];const t=[];for(const s of r){if(!s||typeof s!=="object")continue;const e=s;if(typeof e.id!=="string"||typeof e.urlPattern!=="string"){continue}if(!e.urlPattern)continue;const i=M.includes(e.kind)?e.kind:"respond";t.push({id:e.id,enabled:e.enabled!==false,name:typeof e.name==="string"?e.name:void 0,urlPattern:e.urlPattern,methods:Array.isArray(e.methods)?e.methods.filter(n=>typeof n==="string"):void 0,requireHeader:typeof e.requireHeader==="string"&&e.requireHeader?e.requireHeader:void 0,bodyIncludes:typeof e.bodyIncludes==="string"&&e.bodyIncludes?e.bodyIncludes:void 0,graphqlOperation:typeof e.graphqlOperation==="string"&&e.graphqlOperation?e.graphqlOperation:void 0,graphqlVariables:typeof e.graphqlVariables==="string"?e.graphqlVariables:void 0,bodyJson:typeof e.bodyJson==="string"?e.bodyJson:void 0,graphqlSingle:e.graphqlSingle===true?true:void 0,sandbox:e.sandbox===true?true:void 0,kind:i,status:typeof e.status==="number"?Math.min(R,Math.max(A,e.status)):void 0,statusText:typeof e.statusText==="string"?e.statusText:void 0,headers:e.headers&&typeof e.headers==="object"?e.headers:void 0,body:typeof e.body==="string"?e.body:void 0,failKind:e.failKind==="timeout"?"timeout":void 0,delayMs:typeof e.delayMs==="number"?e.delayMs:void 0,times:typeof e.times==="number"?e.times:null,alternate:e.alternate===true,hits:0,seen:0,createdAt:typeof e.createdAt==="number"?e.createdAt:0})}return t.slice(0,u)}class H{rules=[];enabled=true;listeners=new Set;loaded=false;loadPromise=null;dirty=false;idCounter=0;state={enabled:true,rules:[],autoPaused:false};launchStreak=0;autoPaused=false;keepAlive=null;hitEmitTimer=null;engineDisabled=false;remote=null;remoteEchoUntil=0;enableRemoteMode(t){this.remote=t;this.disableEngine()}disableRemoteMode(){this.remote=null}replaceRules(t,s=false){if(!this.remote)return;if(!s&&f()<this.remoteEchoUntil)return;this.enabled=t.enabled;this.rules=t.rules;this.rebuild();this.emit()}markLocalEdit(){if(this.remote)this.remoteEchoUntil=f()+w}disableEngine(){this.engineDisabled=true;if(this.keepAlive){this.keepAlive();this.keepAlive=null;if(h()===0)c()}}getState(){return this.state}getRules(){if(this.engineDisabled)return m;if(this.otherTabCase())return O;if(!this.enabled)return this.sandboxOnly();return this.rules}otherTabCase(){if(this.remote||this.sandboxOnly().length)return false;if(!p())return false;return L()}caseLockChanged(){this.syncKeepAlive();this.emit()}sandboxCache=null;sandboxOnly(){if(this.sandboxCache?.from!==this.rules){const t=this.rules.filter(s=>s.sandbox===true);this.sandboxCache={from:this.rules,rules:t.length?t:m}}return this.sandboxCache.rules}async fetchRuleBody(t){const s=this.rules.find(e=>e.id===t);if(!s)return null;if(!s.bodyOmitted)return s.body??null;if(!this.remote?.getRuleBody)return null;try{return await this.remote.getRuleBody(t)}catch{return null}}activeCount(){return(this.enabled?this.rules:this.sandboxOnly()).filter(t=>t.enabled&&!T(t)).length}subscribe(t){this.listeners.add(t);void this.ensureLoaded();return()=>{this.listeners.delete(t)}}setEnabled(t){if(this.enabled===t)return;this.remote?.setEnabled(t);this.markLocalEdit();this.markTouched();this.enabled=t;this.commit(this.rules)}addRule(t){if(this.rules.length>=u)return null;const s={...t,id:`ovr_${Date.now().toString(36)}_${++this.idCounter}`,hits:0,seen:0,createdAt:Date.now()};this.commit([s,...this.rules]);return s}upsertRule(t){this.remote?.upsertRule(t);this.markLocalEdit();this.markTouched();const{id:s,...e}=t;if(s&&this.rules.some(i=>i.id===s)){this.updateRule(s,e);return this.rules.find(i=>i.id===s)??null}return this.addRule(e)}replaceAllRules(t,s){if(this.remote)return null;this.markTouched();const e=t.map(i=>i&&typeof i==="object"&&typeof i.id==="string"?i:{...i,id:`ovr_${Date.now().toString(36)}_${++this.idCounter}`,createdAt:Date.now()});this.enabled=s;this.commit(y(e));return this.rules.slice()}updateRule(t,s){const e=this.rules.findIndex(n=>n.id===t);if(e===-1)return;const i=[...this.rules];i[e]={...i[e],...s,hits:0,seen:0};this.commit(i)}setRuleEnabled(t,s){const e=this.rules.findIndex(n=>n.id===t);if(e===-1||this.rules[e].enabled===s)return;this.remote?.setRuleEnabled(t,s);this.markLocalEdit();this.markTouched();const i=[...this.rules];i[e]={...i[e],enabled:s,hits:s?0:i[e].hits,seen:s?0:i[e].seen};this.commit(i)}removeRule(t){const s=this.rules.filter(e=>e.id!==t);if(s.length===this.rules.length)return;this.remote?.removeRule(t);this.markLocalEdit();this.markTouched();this.commit(s)}clearRules(){if(this.rules.length===0)return;this.remote?.clearRules();this.markLocalEdit();this.markTouched();this.commit([])}recordMatch(t){const s=this.rules.findIndex(i=>i.id===t);if(s===-1)return;const e=[...this.rules];e[s]={...e[s],seen:e[s].seen+1};this.rules=e;this.rebuild()}recordHit(t){const s=this.rules.findIndex(g=>g.id===t);if(s===-1)return;const e=this.rules[s];const i=e.hits+1;const n=typeof e.times==="number"&&i>=e.times;const l=[...this.rules];l[s]={...e,hits:i,enabled:n?false:e.enabled};if(n){this.commit(l);return}this.rules=l;this.rebuild();this.scheduleHitEmit()}isLoaded(){return!!this.remote||this.loaded}ensureLoaded(){if(this.remote)return Promise.resolve();if(this.loaded)return Promise.resolve();if(this.loadPromise)return this.loadPromise;this.loadPromise=(async()=>{let t=null;try{t=await d.getItem(a.network.overrides())}catch{}this.hydrate(t)})();return this.loadPromise}loadNow(){if(this.remote||this.loaded||this.loadPromise)return;let t;try{t=globalThis.localStorage?.getItem(a.network.overrides())??null}catch{return}if(t===null)return;this.hydrate(t)}hydrate(t){try{if(t&&!this.dirty){const s=JSON.parse(t);this.enabled=s?.enabled!==false;this.rules=y(s?.rules);this.launchStreak=typeof s?.launchStreak==="number"?s.launchStreak:0;this.autoPaused=s?.autoPaused===true&&!this.enabled;this.applyLaunchGuard();this.rebuild()}}catch{}finally{this.loaded=true;this.syncKeepAlive();this.emit()}}applyLaunchGuard(){if(!this.enabled||this.activeCount()===0||this.rules.some(t=>t.enabled&&t.sandbox)){this.launchStreak=0;return}if(C())return;this.launchStreak+=1;if(this.launchStreak>=x){this.enabled=false;this.autoPaused=true;this.launchStreak=0}this.persist()}syncKeepAlive(){const t=!this.engineDisabled&&(this.activeCount()>0||this.otherTabCase());if(t&&!this.keepAlive){v();this.keepAlive=S(()=>{});return}if(!t&&this.keepAlive){this.keepAlive();this.keepAlive=null;if(h()===0)c()}}scheduleHitEmit(){if(this.hitEmitTimer!==null)return;this.hitEmitTimer=setTimeout(()=>{this.hitEmitTimer=null;this.emit()},I)}commit(t){this.dirty=true;this.rules=t.slice(0,u);this.rebuild();this.syncKeepAlive();this.emit();this.persist()}rebuild(){this.state={enabled:this.enabled,rules:this.rules,autoPaused:this.autoPaused}}markTouched(){this.launchStreak=0;this.autoPaused=false}noteHealthyLaunch(){if(this.launchStreak===0&&!this.autoPaused)return;this.markTouched();this.persist();this.rebuild();this.emit()}persisted(){return JSON.stringify({enabled:this.enabled,rules:this.rules,launchStreak:this.launchStreak,autoPaused:this.autoPaused})}writes=Promise.resolve();persist(){if(this.remote)return;const t=this.persisted();this.writes=this.writes.then(()=>d.setItem(a.network.overrides(),t)).catch(()=>{})}async saveChecked(){if(this.remote)return false;const t=this.persisted();const s=this.writes.then(()=>k(a.network.overrides(),t));this.writes=s.catch(()=>{});let e;const i=new Promise(n=>{e=setTimeout(()=>n(false),_)});return Promise.race([s.catch(()=>false),i]).finally(()=>clearTimeout(e))}emit(){this.listeners.forEach(t=>t())}}export const overrideRulesStore=new H;E({getRules:()=>overrideRulesStore.getRules(),ready:()=>overrideRulesStore.ensureLoaded(),isReady:()=>overrideRulesStore.isLoaded(),recordHit:r=>overrideRulesStore.recordHit(r),recordMatch:r=>overrideRulesStore.recordMatch(r)});if(typeof window!=="undefined"&&typeof document!=="undefined"&&!(typeof navigator!=="undefined"&&navigator.product==="ReactNative")){overrideRulesStore.loadNow();overrideRulesStore.caseLockChanged();window.addEventListener?.("storage",r=>{if(r.key===null||r.key===b())overrideRulesStore.caseLockChanged()})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{socketKey as m}from"./readMessage";export const REPLY_TIMEOUT_MS=1e4;export const STORM_OPENS=3;export const STORM_WINDOW_MS=15e3;export const CANT_CONNECT_TRIES=3;export const AUTH_FAILURES=3;export const AUTH_WINDOW_MS=12e4;export const SIGNED_IN_MS=3e4;const T=1008;const $=/(^|[._:-])(auth[._:-]?(expired|fail(ed|ure)?|error|invalid|rejected)|unauthori[sz]ed|token[._:-]?expired)$/i;export function answeredTypes(i,f){const u=new Map(i.map(c=>[c.id,c]));const d=new Map;for(const c of i){if(!c.replyTo)continue;const r=u.get(c.replyTo);const a=f.get(c.socketId);if(!r?.type||!a)continue;const l=m(a.url);let p=d.get(l);if(!p)d.set(l,p=new Set);p.add(r.type)}return d}function S(i,f,u){const d=[...i].sort((a,l)=>a.at-l.at);let c=0;let r=null;for(let a=0;a<d.length;a++){while(d[a].at-d[c].at>u)c++;const l=a-c+1;if(l>f&&l>(r?.length??0))r=d.slice(c,a+1)}return r}const x=(i,f)=>`${i} ${f}${i===1?"":"s"}`;export function findProblems(i,f,u,d){const c=[];const r=new Map(f.map(t=>[t.id,t]));const a=answeredTypes(i,r);if(d){for(const[t,e]of d){const n=a.get(t)??new Set;e.forEach(s=>n.add(s));a.set(t,n)}}const l=new Map;for(const t of i){if(t.kind==="message"&&t.direction==="in"&&t.held){l.set(t.socketId,[...l.get(t.socketId)??[],t.timestamp])}}for(const t of i){if(t.kind!=="message"||t.direction!=="out"||t.held||t.ping)continue;if(t.sentWhileClosed)continue;if(!t.type||!t.correlationId||t.replyId)continue;const e=r.get(t.socketId);if(!e||!a.get(m(e.url))?.has(t.type))continue;if(e.frozen||l.get(t.socketId)?.some(s=>s>=t.timestamp))continue;const n=e.closedAt!==void 0&&e.closedAt>=t.timestamp?e.closedAt:u;if(n-t.timestamp<REPLY_TIMEOUT_MS)continue;c.push({kind:"no-reply",message:`${t.type} got no reply after ${REPLY_TIMEOUT_MS/1e3}s`,socketId:t.socketId,url:e.url,frameIds:[t.id],at:t.timestamp})}const p=new Map;for(const t of[...f].sort((e,n)=>e.createdAt-n.createdAt)){const e=m(t.url);p.set(e,[...p.get(e)??[],t])}const _=new Set;for(const t of p.values()){for(let e=1;e<t.length;e++){const n=t[e-1];if(n.closedByBuoy&&n.closedAt!==void 0&&t[e].createdAt>=n.closedAt)_.add(t[e].id)}}const k=new Map;const h=new Map;for(const t of i){const e=r.get(t.socketId);if(!e)continue;const n=m(e.url);if(t.kind==="open"&&!_.has(e.id)){k.set(n,[...k.get(n)??[],{at:t.timestamp,id:t.id}])}const s=t.kind==="close"&&t.code===T&&!t.byBuoy;const o=t.kind==="message"&&t.direction==="in"&&!t.fake&&!!t.type&&$.test(t.type);if(!s&&!o)continue;const g=h.get(t.socketId);if(!g||t.timestamp<g.at)h.set(t.socketId,{at:t.timestamp,id:t.id,url:n})}const I=new Map;for(const t of h.values())I.set(t.url,[...I.get(t.url)??[],{at:t.at,id:t.id}]);for(const[t,e]of k){const n=S(e,STORM_OPENS,STORM_WINDOW_MS);if(!n)continue;const s=Math.max(1,Math.round((n[n.length-1].at-n[0].at)/1e3));c.push({kind:"reconnect-storm",message:`Opened ${n.length} times in ${s}s`,url:t,frameIds:n.map(o=>o.id),at:n[n.length-1].at})}for(const[t,e]of I){let n=-Infinity;for(const o of p.get(t)??[]){if(o.openedAt===void 0)continue;const g=h.get(o.id)?.at??o.closedAt??u;if(g-o.openedAt>=SIGNED_IN_MS)n=Math.max(n,g)}const s=S(e.filter(o=>o.at>n),AUTH_FAILURES-1,AUTH_WINDOW_MS);if(!s)continue;c.push({kind:"auth-loop",message:`Sign-in failed ${x(s.length,"time")} in a row`,url:t,frameIds:s.map(o=>o.id),at:s[s.length-1].at})}const y=new Map;const M=new Map;for(const t of[...f].sort((e,n)=>e.createdAt-n.createdAt)){if(t.state!=="closed"&&t.openedAt===void 0)continue;const e=m(t.url);const n=t.state==="closed"&&t.openedAt===void 0&&!t.closedByBuoy;if(!n){y.set(e,[]);M.delete(e);continue}const s=[...y.get(e)??[],t];y.set(e,s);if(s.length>=CANT_CONNECT_TRIES)M.set(e,s)}for(const[t,e]of M){const n=new Set(e.map(o=>o.id));const s=i.filter(o=>o.kind==="close"&&n.has(o.socketId));c.push({kind:"cant-connect",message:`Couldn't connect: ${e.length} tries in a row failed`,url:t,frameIds:s.map(o=>o.id),at:Math.max(...e.map(o=>o.closedAt??o.createdAt))})}const A=new Map;for(const t of f){if(t.state!=="open")continue;const e=m(t.url);A.set(e,[...A.get(e)??[],t])}for(const[t,e]of A){if(e.length<2)continue;c.push({kind:"two-sockets",message:`${e.length} sockets open to the same URL`,url:t,frameIds:[],at:Math.max(...e.map(n=>n.openedAt??n.createdAt))})}const w=new Map;for(const t of i){if(!t.sentWhileClosed)continue;w.set(t.socketId,[...w.get(t.socketId)??[],t])}for(const[t,e]of w){const n=[...e].sort((s,o)=>s.timestamp-o.timestamp);c.push({kind:"sent-while-closed",message:`Sent ${x(n.length,"message")} while the socket was not open`,socketId:t,url:r.get(t)?.url,frameIds:n.map(s=>s.id),at:n[0].timestamp})}return c.sort((t,e)=>e.at-t.at)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export const BURST_GAP_MS=1500;export const FOLD_MIN=3;function d(s,n,o){if(n.socketId&&s.socketId!==n.socketId)return false;if(s.ping&&!n.showPings)return false;const t=n.filter??{kind:"all"};if(t.kind==="problems"&&!o.has(s.id))return false;if(t.kind==="direction"&&s.direction!==t.direction)return false;if(t.kind==="type"&&!matchesPrefix(s.type,t.prefix))return false;if(n.search){const i=n.search.toLowerCase();if(!`${s.type??""} ${s.data??""} ${s.reason??""}`.toLowerCase().includes(i))return false}return true}export function foldFrames(s,n={}){const o=new Map;for(const e of s.problems)for(const r of e.frameIds)if(!o.has(r))o.set(r,e);const t=[];for(const e of s.frames){if(!d(e,n,o))continue;const r=o.get(e.id);const c=t[t.length-1];const f=c?.frames[c.frames.length-1];const a=f&&!r&&!c.problem&&e.kind==="message"&&f.kind==="message"&&!e.fake&&!f.fake&&!e.replyId&&!f.replyId&&e.type!==void 0&&e.type===f.type&&e.direction===f.direction&&e.socketId===f.socketId&&f.timestamp-e.timestamp<=BURST_GAP_MS;if(a)c.frames.push(e);else t.push({frames:[e],...r?{problem:r}:{}})}const i=[];for(const e of t){const r=e.frames[e.frames.length-1].id;if(e.frames.length>=FOLD_MIN&&!n.expanded?.has(r)){i.push({frame:e.frames[0],count:e.frames.length,foldKey:r});continue}for(const c of e.frames)i.push({frame:c,count:1,...e.problem?{problem:e.problem}:{}})}return i}export function matchesPrefix(s,n){if(!s)return false;return s.startsWith(n)||/[.:/]$/.test(n)&&s===n.slice(0,-1)}export function topTypePrefixes(s,n=4){const o=new Map;for(const t of s){if(t.kind!=="message"||t.ping||!t.type)continue;const i=t.type.search(/[.:/]/);const e=i>0?`${t.type.slice(0,i+1)}`:t.type;o.set(e,(o.get(e)??0)+1)}for(const[t,i]of[...o]){const e=[".",":","/"].map(r=>t+r).find(r=>o.has(r));if(!e)continue;o.set(e,o.get(e)+i);o.delete(t)}return[...o.entries()].sort((t,i)=>i[1]-t[1]).slice(0,n).map(([t])=>t)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function clockTime(t){const n=new Date(t);return[n.getHours(),n.getMinutes(),n.getSeconds()].map(e=>String(e).padStart(2,"0")).join(":")}export function shortDuration(t){if(t<1e3)return`${Math.max(0,Math.round(t))}ms`;if(t<1e4)return`${(t/1e3).toFixed(1)}s`;const n=Math.round(t/1e3);if(n<60)return`${n}s`;const e=Math.floor(n/60);if(e<60)return`${e}m ${n%60}s`;return`${Math.floor(e/60)}h ${e%60}m`}export function shortUrl(t){return t.replace(/^wss?:\/\//,"")}const u={1e3:"normal",1001:"going away",1006:"lost connection",1008:"rejected",1011:"server error",1012:"server restart",4999:"Buoy"};export function closeLabel(t,n=false){if(t===void 0)return"Closed";const e=t===1006&&n?"couldn't connect":u[t];return e?`Closed ${t} \xB7 ${e}`:`Closed ${t}`}export function connectionStatus(t,n){switch(t.state){case"connecting":return"Connecting";case"open":return`Open ${shortDuration(n-(t.openedAt??t.createdAt))}`;case"closing":return"Closing";case"closed":return`${closeLabel(t.closeCode,t.openedAt===void 0)}${t.closedByBuoy?" (Buoy)":""}`}}const d=["payload","data","body","d"];const f=["content","text","message","body"];function y(t){if(!t||typeof t!=="object"||Array.isArray(t))return void 0;for(const n of f){const e=t[n];if(typeof e==="string"&&e.trim())return e.trim().slice(0,80)}return void 0}export function previewText(t){if(t.binary)return t.data??"[binary]";const n=(t.data??"").replace(/\s+/g," ").trim();if(!t.json||!t.type)return n;try{const e=JSON.parse(t.data??"");if(e&&typeof e==="object"&&!Array.isArray(e)){const{type:l,event:p,op:g,action:$,method:h,...r}=e;for(const a of["requestId","request_id","correlationId","correlation_id","ref","id"]){if(String(r[a])===t.correlationId)delete r[a]}const o=Object.keys(r);const s=o.length===1&&d.includes(o[0])?r[o[0]]:void 0;const i=s&&typeof s==="object"?s:r;const c=y(i);return`${c?`"${c}" \xB7 `:""}${JSON.stringify(i)}`}}catch{}return n}export function prettyData(t){if(!t.json||!t.data)return t.data??"";try{return JSON.stringify(JSON.parse(t.data),null,2)}catch{return t.data}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{classifyKey as g}from"@buoy-gg/shared-ui";export const MAX_FRAME_CHARS=64*1024;export const HIDDEN="[hidden]";const x=["type","event","op","action","method"];const I=["requestId","request_id","correlationId","correlation_id","ref","id"];const T=["success","ok","result","error","status"];const O=/^(ping|pong|heartbeat|hb|keep-?alive)$/i;const P=new Set(["2","3","ping","pong","heartbeat","primus::ping","primus::pong"]);const S=/^(auth|authenticate|authorize|login|sign-?in|connection_init)$/i;const d=/\beyJ[\w-]{6,}\.[\w-]{6,}\.[\w-]*/g;const N=/^4[0-6](?:\/[^,]*,)?(\d*)([[{].*)$/s;export const MAX_PARSE_CHARS=256*1024;const B=/("?)([\w.-]{2,64})\1(\s*[:=]\s*)("(?:[^"\\]|\\.)*(?:"|$)|(?:(?:Bearer|Basic|Token)\s+)?[^\s,;&}\]"]+)/gi;const Y=/\b(Bearer|Basic|Token)\s+[\w.~+/=-]{8,}/g;const j=/("payload"\s*:\s*)("(?:[^"\\]|\\.)*(?:"|$)|[^\s,}\]]+)/;const L=/"(?:type|event|op|action|method)"\s*:\s*"([^"\\]{1,80})"/;function k(e){if(typeof ArrayBuffer!=="undefined"){if(e instanceof ArrayBuffer)return e.byteLength;if(ArrayBuffer.isView(e))return e.byteLength}if(typeof Blob!=="undefined"&&e instanceof Blob)return e.size;return null}function R(e){try{const t=e instanceof ArrayBuffer?new Uint8Array(e):ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):null;if(!t)return"";const i=Array.from(t.subarray(0,32),s=>s.toString(16).padStart(2,"0")).join(" ");return t.byteLength>32?`${i} \u2026`:i}catch{return""}}export function hideSecrets(e,t=0){if(t>20)return e!==null&&typeof e==="object"?HIDDEN:typeof e==="string"?e.replace(d,HIDDEN):e;if(typeof e==="string")return e.replace(d,HIDDEN);if(Array.isArray(e))return e.map(i=>hideSecrets(i,t+1));if(e&&typeof e==="object"){const i={};for(const[s,n]of Object.entries(e)){i[s]=g(s)==="secret"&&n!=null&&n!==""?HIDDEN:hideSecrets(n,t+1)}return i}return e}export function scrubText(e,t=0){return e.replace(B,(i,s,n,r,c)=>{if(g(n)==="secret")return`${s}${n}${s}${r}${c.startsWith('"')?`"${HIDDEN}"`:HIDDEN}`;if(c.startsWith('"')&&c.length>2&&t<3){const u=c.endsWith('"')&&c.length>1;const y=c.slice(1,u?-1:void 0);return`${s}${n}${s}${r}"${scrubText(y,t+1)}${u?'"':""}`}return i}).replace(Y,`$1 ${HIDDEN}`).replace(d,HIDDEN)}export function hideUrlSecrets(e){const t=e.replace(/^([a-z][\w+.-]*:\/\/[^/@:?#]*):[^/@?#]*@/i,`$1:${HIDDEN}@`);const i=t.indexOf("?");if(i===-1)return t.replace(d,HIDDEN);const s=t.slice(i+1).split("&").map(n=>{const r=n.indexOf("=");if(r===-1)return n;let c=n.slice(0,r);try{c=decodeURIComponent(c)}catch{}return g(c)==="secret"?`${n.slice(0,r)}=${HIDDEN}`:n}).join("&");return`${t.slice(0,i)}?${s}`.replace(d,HIDDEN)}export function socketKey(e){const t=e.search(/[?#]/);return t===-1?e:e.slice(0,t)}function m(e,t){for(const i of t){const s=e[i];if(typeof s==="string"&&s)return s;if(typeof s==="number"&&Number.isFinite(s))return String(s)}return void 0}const E="phx_reply";function H(e){const t=m(e,x);return{type:t,correlationId:m(e,I),replyShaped:t===E||T.some(i=>i in e)}}function J(e){if(e.length!==5||typeof e[2]!=="string"||typeof e[3]!=="string")return null;const t=e[1];return{type:e[3],correlationId:typeof t==="string"||typeof t==="number"?String(t):void 0,replyShaped:e[3]===E}}export function readMessage(e){const t=k(e);if(t!==null){const f=R(e);return{data:`[binary, ${t} bytes]${f?` ${f}`:""}`,size:t,binary:true}}const i=typeof e==="string"?e:String(e);const s=i.length;if(s>MAX_PARSE_CHARS){const f=i.slice(0,MAX_FRAME_CHARS);const p=f.trimStart()[0];const l=L.exec(f.slice(0,4096))?.[1];const A=l?scrubText(l):void 0;const _=l&&S.test(l)?f.replace(j,`$1"${HIDDEN}"`):f;return{data:scrubText(_).replace(/\beyJ[\w-]{6,}(?:\.[\w-]*)?$/,HIDDEN),size:s,truncated:true,...p==="{"||p==="["?{json:true}:{},...A?{type:A}:{}}}const n=i.trim();if(P.has(n.toLowerCase()))return{data:i,size:s,ping:true,type:n};let r;let c=false;let u;const y=N.exec(n);try{if(y){r=JSON.parse(y[2]);u=y[1]||void 0}else if(n.startsWith("{")||n.startsWith("[")){r=JSON.parse(n);c=true}}catch{r=void 0}let o={};let $=false;let a;if(y&&r&&typeof r==="object"){const f=n[1]==="3"||n[1]==="6";if(Array.isArray(r)){o=f?{correlationId:u,replyShaped:true}:{type:typeof r[0]==="string"?r[0]:void 0,correlationId:u}}a=`${n.slice(0,n.length-y[2].length)}${JSON.stringify(hideSecrets(r))}`}else if(r&&typeof r==="object"&&!Array.isArray(r)){const f=r;o=H(f);let p=hideSecrets(f);if(o.type&&S.test(o.type)&&"payload"in p&&p.payload!=null){p={...p,payload:HIDDEN}}a=JSON.stringify(p)}else if(c){if(Array.isArray(r)){o=J(r)??{};$=o.type!==void 0&&r[2]==="phoenix"}a=JSON.stringify(hideSecrets(r))}else{a=scrubText(i)}if(o.correlationId)o.correlationId=scrubText(o.correlationId);if(o.type)o.type=scrubText(o.type);const b=$||!!o.type&&O.test(o.type);const h=a.length>MAX_FRAME_CHARS;return{data:h?a.slice(0,MAX_FRAME_CHARS):a,size:s,...h?{truncated:h}:{},...c||y?{json:true}:{},...o,...b?{ping:b}:{}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{closeLabel as r,shortUrl as i}from"./format";import{socketStore as n}from"./socketStore";export function toSocketMoment(t,o){const e={id:`socket-${t.id}`,source:"socket",timestamp:t.timestamp,subtitle:i(o),originalEvent:t,correlationId:t.socketId};switch(t.kind){case"open":return{...e,title:"Socket opened",status:"success"};case"error":return{...e,title:"Socket error",status:"error"};case"close":return{...e,title:`Socket ${r(t.code,t.neverOpened).toLowerCase()}${t.byBuoy?" (Buoy)":""}`,status:t.code===1e3||t.code===1001?"neutral":"error"};case"message":if(t.fake!=="inject")return null;return{...e,title:`Buoy pushed ${t.type??"a message"}`,status:"neutral"}}}export function onSocketMoment(t){return n.onEvent(o=>{const e=n.getState().connections.find(c=>c.id===o.socketId);const s=toSocketMoment(o,e?.url??"");if(s)t(s)})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{BaseEventStore as I,getAccountAccess as p,isBuoyRequest as S,subscribeAccountAccess as A}from"@buoy-gg/shared-ui";import{conditionsCanApply as C,getEffectiveNetworkConnection as z,getNetworkCondition as E,subscribeNetworkConditions as M}from"../conditions/store";import{findProblems as O,REPLY_TIMEOUT_MS as w}from"./findProblems";const m=2*6e4;import{hideUrlSecrets as R,readMessage as T,socketKey as y}from"./readMessage";import{installWebSocketPatch as _}from"./webSocketPatch";const x=1e3;const v=50;const $=50;const F=200;const L=3e4;const N=/\/(hot|message|inspector\/(device|debug)|debugger-proxy|__expo[^/?]*)(?:[/?]|$)/;const D=/^wss?:\/\/[^/]+:8097(?:\/|$)/;export function isToolingSocket(u){return S(u)||N.test(u)||D.test(u)}class B extends I{connections=new Map;controls=new Map;pending=new Map;answered=new Map;socketSeq=0;frameSeq=0;blocked=false;offline=false;installed=false;mirror=false;remote=null;capturingSince=null;mirrored=null;cache=null;version=0;recheck=null;retryOnAccess=null;constructor(){super({storeName:"sockets",maxEvents:x})}install(){if(this.installed||this.mirror)return this.installed;if(p().status==="locked"){this.retryOnAccess??=A(()=>{if(p().status!=="locked"&&this.install()){this.retryOnAccess?.();this.retryOnAccess=null}});return false}this.installed=_(this);if(this.installed){this.capturingSince=Date.now();M(()=>this.syncOffline());this.syncOffline()}return this.installed}startCapturing(){this.install()}stopCapturing(){}isCapturing(){return this.installed}disableCapture(){this.mirror=true;super.disableCapture()}bump(){this.notifyArrayListeners()}nextFrameId(){return`f${++this.frameSeq}`}setConnection(e,t){const n=this.connections.get(e);if(n)this.connections.set(e,{...n,...t})}push(e){this.addEvent(e)}register(e,t,n){if(this.mirror||isToolingSocket(e)||p().status==="locked")return null;const s=`s${++this.socketSeq}`;const i=R(e);const o=y(i);let r;for(const c of this.connections.values())if(y(c.url)===o)r=c;const a=r?.openedAt!==void 0&&(r.closedAt??Date.now())-r.openedAt>=L;const f=r?.state==="closed"&&r.closeCode!==1e3&&!a;const d=f?r.attempt+1:1;this.connections.set(s,{id:s,url:i,...t?.length?{protocols:t}:{},attempt:d,state:"connecting",createdAt:Date.now(),sent:0,received:0,bytesSent:0,bytesReceived:0,pings:0});this.controls.set(s,n);this.trimConnections();this.bump();return s}trimConnections(){if(this.connections.size<=v)return;for(const e of this.connections.values()){if(this.connections.size<=v)break;if(e.state!=="closed")continue;this.connections.delete(e.id);this.controls.delete(e.id);this.pending.delete(e.id)}}open(e){const t=Date.now();this.setConnection(e,{state:"open",openedAt:t});this.push({id:this.nextFrameId(),socketId:e,kind:"open",timestamp:t})}close(e,t,n,s){const i=this.connections.get(e);if(!i||i.state==="closed")return;const o=Date.now();this.setConnection(e,{state:"closed",closedAt:o,closeCode:t,closeReason:n||void 0,...s?{closedByBuoy:true}:{},frozen:false});this.controls.delete(e);this.pending.delete(e);this.trimConnections();this.push({id:this.nextFrameId(),socketId:e,kind:"close",timestamp:o,...t!==void 0?{code:t}:{},...n?{reason:n}:{},...s?{byBuoy:s}:{},...i.openedAt===void 0?{neverOpened:true}:{}})}error(e){this.push({id:this.nextFrameId(),socketId:e,kind:"error",timestamp:Date.now()})}message(e,t,n,s){const i=this.connections.get(e);if(!i||p().status==="locked")return void 0;const o=T(n);const r=Date.now();const a=this.nextFrameId();const f={id:a,socketId:e,kind:"message",direction:t,timestamp:r,data:o.data,size:o.size,...o.binary?{binary:true}:{},...o.truncated?{truncated:true}:{},...o.json?{json:true}:{},...o.type?{type:o.type}:{},...o.correlationId?{correlationId:o.correlationId}:{},...o.ping?{ping:true}:{},...s?.fake?{fake:s.fake}:{},...s?.held?{held:true}:{},...s?.sentWhileClosed?{sentWhileClosed:true}:{}};const d=t==="out";this.setConnection(e,{lastMessageAt:r,...o.ping?{pings:i.pings+1}:d?{sent:i.sent+1,bytesSent:i.bytesSent+o.size}:{received:i.received+1,bytesReceived:i.bytesReceived+o.size}});if(o.correlationId&&!s?.held&&!(d&&s?.sentWhileClosed)){let c=this.pending.get(e);if(d){if(!c)this.pending.set(e,c=new Map);c.set(o.correlationId,{frameId:a,at:r});this.scheduleRecheck()}else{const h=c?.get(o.correlationId);if(h&&r-h.at>m)c.delete(o.correlationId);const b=h&&r-h.at<=m?h.frameId:void 0;const l=b?this.events.find(k=>k.id===b):void 0;if(l&&(o.replyShaped||o.type&&o.type===l.type)){c.delete(o.correlationId);f.replyTo=l.id;const k=r-l.timestamp;this.events=this.events.map(g=>g.id===l.id?{...g,replyId:a,replyMs:k}:g);if(l.type)this.rememberAnswered(y(i.url),l.type)}}}this.push(f);return a}rememberAnswered(e,t){let n=this.answered.get(e);if(n)this.answered.delete(e);else n=new Set;this.answered.set(e,n);n.delete(t);n.add(t);while(n.size>F)n.delete(n.values().next().value);while(this.answered.size>$)this.answered.delete(this.answered.keys().next().value)}scheduleRecheck(){if(this.recheck)clearTimeout(this.recheck);this.recheck=null;const e=Date.now();let t=Infinity;for(const[n,s]of this.pending){for(const[i,o]of s){const r=e-o.at;if(r>m)s.delete(i);else t=Math.min(t,r<w?o.at+w:o.at+m+1)}if(s.size===0)this.pending.delete(n)}if(t===Infinity)return;this.recheck=setTimeout(()=>{this.recheck=null;this.bump();this.scheduleRecheck()},Math.max(0,t-e)+100)}cutOff(){if(this.offline)return"Offline (Buoy)";return this.blocked?"Blocked by Buoy":null}isFrozen(e){return this.connections.get(e)?.frozen===true}syncOffline(){const e=C()&&(E()==="offline"||["offline","noInternet"].includes(z()));if(e===this.offline)return;this.offline=e;if(e){for(const t of[...this.controls.values()])t.fakeClose(1006,"Offline (Buoy)")}this.bump()}getState(){if(this.mirrored)return this.mirrored;if(this.cache?.version===this.version&&this.cache.state.frames===this.events)return this.cache.state;const e=[...this.connections.values()].reverse();const t=this.getEvents();const n={connections:e,frames:t,problems:O(t,e,Date.now(),this.answered),tests:{blocked:this.blocked,offline:this.offline,frozen:e.filter(s=>s.frozen).map(s=>s.id)},capturingSince:this.capturingSince};this.cache={version:this.version,state:n};return n}getFrame(e){return this.getState().frames.find(t=>t.id===e)}subscribeState(e){return this.subscribeToEvents(()=>e())}setRemote(e){this.remote=e}async loadFrame(e){if(this.remote)return this.remote.getFrame(e);const t=this.getFrame(e);if(!t)return null;const n=t.replyId??t.replyTo;return{frame:t,partner:n?this.getFrame(n)??null:null}}applySnapshot(e){this.mirrored=e;this.notifyArrayListeners()}async act(e){if(this.remote)return this.remote.act(e);return this.actLocal(e)}actLocal(e){const t="socketId"in e?this.controls.get(e.socketId):void 0;const n=s=>({ok:false,message:this.connections.has(s)?`Socket ${s} is closed.`:`No socket ${s}. Read get_sockets for ids.`});switch(e.action){case"inject":{if(!t)return n(e.socketId);const s=t.inject(e.data);return{ok:true,frameId:s,message:`Pushed the message into the app on ${e.socketId}, as if the server sent it.`}}case"send":{if(!t)return n(e.socketId);const s=this.connections.get(e.socketId)?.state==="connecting";const i=t.send(e.data);const o=i?this.getFrame(i)?.held:false;return o?{ok:false,frameId:i,message:s?`Held back: ${e.socketId} is still connecting, so the server did not get it. Try again once it's open.`:`Held back: ${e.socketId} is frozen, blocked or offline, so the server did not get it.`}:{ok:true,frameId:i,message:`Sent to the server on ${e.socketId}.`}}case"close":{if(!t)return n(e.socketId);const s=e.code??1006;if(!Number.isInteger(s)||s<1e3||s>4999){return{ok:false,message:`Close code ${s} isn't a WebSocket close code. Use 1000-4999, like 1006, 1008 or 1001.`}}const i=e.reason??(s===1006?"Dropped by Buoy":"Closed by Buoy");t.fakeClose(s,i);return{ok:true,message:`Closed ${e.socketId} with code ${s}. The app got the close; watch for its reconnect.`}}case"freeze":{if(!t)return n(e.socketId);this.setConnection(e.socketId,{frozen:e.frozen});this.bump();return{ok:true,message:e.frozen?`Froze ${e.socketId}: it still looks open, but no messages get through either way.`:`Unfroze ${e.socketId}. Messages held while frozen are lost.`}}case"block":{this.blocked=e.blocked;if(e.blocked)for(const s of[...this.controls.values()])s.fakeClose(1006,"Blocked by Buoy");this.bump();return{ok:true,message:e.blocked?"Blocked: open sockets dropped, and every new one fails until you unblock.":"Unblocked: new sockets can connect again."}}case"reset":{this.blocked=false;for(const s of this.connections.values())if(s.frozen)this.setConnection(s.id,{frozen:false});this.bump();return{ok:true,message:"Reset: no socket is frozen or blocked. The app reconnects on its own schedule."}}case"clear":{this.clearEvents();return{ok:true,message:"Cleared the message list."}}}}clearEvents(){for(const[e,t]of this.connections)if(t.state==="closed")this.connections.delete(e);this.pending.clear();this.answered.clear();super.clearEvents()}notifyArrayListeners(){this.version++;super.notifyArrayListeners()}}export const socketStore=new B;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{matchesPrefix as p}from"./foldFrames";import{socketKey as s}from"./readMessage";import{socketStore as c}from"./socketStore";export const SNAPSHOT_FRAMES=300;export const SNAPSHOT_TEXT=1e3;const m=200;export const LIST_BODY_TEXT=4e3;function d(t,e){if(!t.data||t.data.length<=e)return t;return{...t,data:t.data.slice(0,e),dataCut:true}}export function matchesType(t,e){if(!t)return false;const r=e.toLowerCase();const o=t.toLowerCase();return r.endsWith("*")?p(o,r.slice(0,-1)):o.includes(r)}export function querySockets(t,e={}){const r=new Set(t.problems.flatMap(n=>n.frameIds));let o=t.frames;if(e.frameId)o=o.filter(n=>n.id===e.frameId||n.replyTo===e.frameId||n.replyId===e.frameId);if(e.socketId)o=o.filter(n=>n.socketId===e.socketId);if(!e.includePings&&!e.frameId)o=o.filter(n=>!n.ping);if(e.type)o=o.filter(n=>matchesType(n.type,e.type));if(e.direction==="lifecycle")o=o.filter(n=>n.kind!=="message");else if(e.direction)o=o.filter(n=>n.direction===e.direction);if(e.problems)o=o.filter(n=>r.has(n.id));if(e.since)o=o.filter(n=>n.timestamp>=e.since);const l=o.length;const a=typeof e.limit==="number"&&e.limit>=0?Math.min(e.limit,500):50;const f=o.slice(0,a).map(n=>e.frameId?n:d(n,e.includeBodies?LIST_BODY_TEXT:m));const i=e.socketId?t.connections.find(n=>n.id===e.socketId):void 0;const u=i?s(i.url):void 0;return{connections:e.socketId?t.connections.filter(n=>n.id===e.socketId):t.connections,problems:e.socketId?t.problems.filter(n=>n.socketId?n.socketId===e.socketId:!!n.url&&s(n.url)===u):t.problems,tests:t.tests,capturingSince:t.capturingSince,frames:f,total:l,flagged:[...r]}}function I(t){if(!t||typeof t!=="object")return null;const e=t;const r=typeof e.socketId==="string"?e.socketId:"";const o=typeof e.data==="string"?e.data:e.data!==void 0?JSON.stringify(e.data):void 0;switch(e.action){case"inject":case"send":return r&&o!==void 0?{action:e.action,socketId:r,data:o}:null;case"close":return r?{action:"close",socketId:r,...typeof e.code==="number"?{code:e.code}:{},...typeof e.reason==="string"?{reason:e.reason}:{}}:null;case"freeze":return r?{action:"freeze",socketId:r,frozen:e.frozen!==false}:null;case"block":return{action:"block",blocked:e.blocked!==false};case"reset":case"clear":return{action:e.action};default:return null}}export const socketsSyncAdapter={version:1,getSnapshot:()=>{const t=c.getState();return{...t,frames:t.frames.slice(0,SNAPSHOT_FRAMES).map(e=>d(e,SNAPSHOT_TEXT))}},subscribe:t=>c.subscribeState(t),actions:{getFrame:t=>{const e=t&&typeof t==="object"?t.id:void 0;if(typeof e!=="string")return null;const r=c.getFrame(e);if(!r)return null;const o=r.replyId??r.replyTo;return{frame:r,partner:o?c.getFrame(o)??null:null}},query:t=>querySockets(c.getState(),t??{}),act:t=>{const e=I(t);if(!e){return{ok:false,message:"Unknown or incomplete action. inject/send need socketId and data; close/freeze need socketId."}}return c.actLocal(e)}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const A=["open","message","close","error"];const V=0;const P=1;const z=3;const w=Symbol.for("buoy.websocket.patched");const G=4999;function Y(n,c,y){try{if(typeof c==="function")c.call(n,y);else if(c&&typeof c.handleEvent==="function"){c.handleEvent(y)}}catch(m){const h=globalThis.reportError;if(typeof h==="function")h(m);else console.error(m)}}function l(n){try{return n()}catch(c){if(typeof __DEV__!=="undefined"&&__DEV__)console.warn("[Buoy] Couldn't record a socket event:",c);return void 0}}function D(n,c,y){return{type:n,target:c,currentTarget:c,isTrusted:false,timeStamp:Date.now(),defaultPrevented:false,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){},...y}}export function isWebSocketPatched(){const n=globalThis.WebSocket;return typeof n==="function"&&n[w]===true}export function installWebSocketPatch(n){const c=globalThis;const y=c.WebSocket;if(typeof y!=="function"||y[w])return false;const m=y.prototype;const h=m.send;const L=m.close;const I=m.addEventListener;const R=m.removeEventListener;class j extends y{static[w]=true;constructor(a,u,...E){super(a,u,...E);const i=this;const _={open:[],message:[],close:[],error:[]};let p=false;let S=false;let o=null;const O=Object.getOwnPropertyDescriptor(i,"readyState");let x=O&&"value"in O?O.value:void 0;const k=()=>O&&"value"in O?x:Reflect.get(m,"readyState",i);Object.defineProperty(i,"readyState",{configurable:true,enumerable:true,get:()=>p?z:S?V:k(),set:e=>{x=e}});const v=()=>{const e=p;p=false;try{L.call(i,G,"Closed by Buoy")}catch{}finally{p=e}};const C=(e,t)=>{const s=_[e];let r=false;const f=t;const b=f?.stopImmediatePropagation;if(f&&typeof b==="function"){try{f.stopImmediatePropagation=()=>{r=true;b.call(f)}}catch{}}for(const d of[...s]){if(r)break;const g=s.indexOf(d);if(g===-1)continue;if(d.once)s.splice(g,1);Y(i,d.listener,t)}};for(const e of A){Object.defineProperty(i,`on${e}`,{configurable:true,enumerable:true,get:()=>_[e].find(t=>t.attr)?.listener??null,set:t=>{const s=_[e];const r=s.find(f=>f.attr);if(typeof t==="function"){if(r)r.listener=t;else s.push({listener:t,once:false,capture:false,attr:true})}else if(r){s.splice(s.indexOf(r),1)}}})}const N=e=>typeof e==="boolean"?e:!!e?.capture;i.__buoyAdd=(e,t,s)=>{const r=_[e];if(!r)return false;const f=N(s);if(!t||r.some(g=>!g.attr&&g.listener===t&&g.capture===f))return true;const b=typeof s==="object"?s:void 0;if(b?.signal?.aborted)return true;const d={listener:t,once:!!b?.once,capture:f};r.push(d);b?.signal?.addEventListener?.("abort",()=>{const g=r.indexOf(d);if(g!==-1)r.splice(g,1)},{once:true});return true};i.__buoyRemove=(e,t,s)=>{const r=_[e];if(!r)return false;const f=N(s);const b=r.findIndex(d=>!d.attr&&d.listener===t&&d.capture===f);if(b!==-1)r.splice(b,1);return true};i.__buoySend=e=>{if(!o)return h.call(i,e);if(p){l(()=>n.message(o,"out",e,{sentWhileClosed:true,held:true}));return}if(S){l(()=>n.message(o,"out",e,{sentWhileClosed:true,held:true}));const t=globalThis.DOMException;throw typeof t==="function"?new t("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.","InvalidStateError"):new Error("INVALID_STATE_ERR")}if(k()!==P){l(()=>n.message(o,"out",e,{sentWhileClosed:true}));return h.call(i,e)}if(l(()=>n.cutOff()!==null||n.isFrozen(o))===true){l(()=>n.message(o,"out",e,{held:true}));return}l(()=>n.message(o,"out",e));return h.call(i,e)};const T={inject(e){if(!o)return void 0;const t=l(()=>n.message(o,"in",e,{fake:"inject"}));C("message",D("message",i,{data:e,origin:"",lastEventId:"",ports:[]}));return t},send(e){if(!o)return void 0;const t=p||k()!==P||l(()=>n.cutOff()!==null||n.isFrozen(o))===true;const s=l(()=>n.message(o,"out",e,t?{fake:"send",held:t}:{fake:"send"}));if(!t)h.call(i,e);return s},fakeClose(e,t){if(p)return;p=true;if(o&&e===1006)l(()=>n.error(o));if(o)l(()=>n.close(o,e,t,true));if(e===1006)C("error",D("error",i,{message:t}));C("close",D("close",i,{code:e,reason:t,wasClean:e!==1006}));v()},isOpen:()=>!p&&k()===P};const B=typeof a==="string"?a:String(a);const F=u==null?void 0:Array.isArray(u)?u:[u];o=l(()=>n.register(B,F,T))??null;for(const e of A){I.call(i,e,t=>{if(p||S){if(e==="open")v();return}if(o){const s=o;const r=e==="open"?l(()=>n.cutOff()):null;if(r)return T.fakeClose(1006,r);if(e==="open")l(()=>n.open(s));else if(e==="close")l(()=>n.close(s,t?.code,t?.reason,false));else if(e==="error")l(()=>n.error(s));else{const f=l(()=>n.cutOff()!==null||n.isFrozen(s))===true;l(()=>n.message(s,"in",t?.data,f?{held:f}:void 0));if(f)return}}C(e,t)})}const W=o?l(()=>n.cutOff()):null;if(W){S=true;v();setTimeout(()=>T.fakeClose(1006,W),0)}}addEventListener(a,u,E){if(this.__buoyAdd?.(a,u,E))return;return I.call(this,a,u,E)}removeEventListener(a,u,E){if(this.__buoyRemove?.(a,u,E))return;return R.call(this,a,u,E)}send(a){const u=this;return u.__buoySend?u.__buoySend(a):h.call(u,a)}}c.WebSocket=j;return true}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getNetworkCondition as E,setNetworkCondition as T,subscribeNetworkConditions as j,conditionsCanApply as m,networkConditionsRuntimeId as k}from"../conditions/store";import{networkEventStore as c}from"../utils/networkEventStore";import{flagsForEventId as O,networkSavedStore as a}from"../utils/networkSavedStore";import{overrideRulesStore as i}from"../overrides/overrideRulesStore";import{draftFromEvent as x}from"../overrides/presets";import{inspectEngine as B,overridesCanApply as C,OVERRIDES_INACTIVE_REASON as L}from"../overrides/engine";import{getNetworkListenerCount as R,isNetworkInterceptionLive as M,isNetworkListening as P}from"../utils/networkListener";import{MAX_RULES as w}from"../overrides/types";import{approxJsonSize as S,isOverWireBudget as _}from"@buoy-gg/shared-ui";import{expandKeyedArrays as $,patchFromPath as J,refusalText as W,shapeKind as I,suggestedPatch as U,typedEditViolations as K}from"@buoy-gg/shared-ui";export const SNAPSHOT_BODY_INLINE_LIMIT=16*1024;export const SNAPSHOT_EVENTS_BUDGET=1.25*1024*1024;function v(e,t){if(e===void 0)return false;if((t??0)>SNAPSHOT_BODY_INLINE_LIMIT)return true;return _(e,SNAPSHOT_BODY_INLINE_LIMIT)}const A=new WeakMap;const N=new WeakMap;function q(e){const t=A.get(e);if(t)return t;let n;try{n=F(e)}catch{n=z(e)}A.set(e,n);return n}function z(e){const t={...e,requestData:void 0,responseData:void 0,graphqlVariables:void 0,requestBodyOmitted:e.requestData!==void 0?true:void 0,responseBodyOmitted:e.responseData!==void 0?true:void 0};let n=1024;try{n=S(t,SNAPSHOT_EVENTS_BUDGET).bytes}catch{}return{event:t,bytes:n}}function F(e){const t=v(e.requestData,e.requestSize);const n=v(e.responseData,e.responseSize);const r=D(e.graphqlVariables);const o=H(e.requestHeaders);const s=H(e.responseHeaders);const d=t||n||r!==e.graphqlVariables||o!==e.requestHeaders||s!==e.responseHeaders;let u=e;if(d){u={...e};if(t){u.requestData=void 0;u.requestBodyOmitted=true}if(n){u.responseData=void 0;u.responseBodyOmitted=true}if(r!==e.graphqlVariables){u.graphqlVariables=r}if(o!==e.requestHeaders){u.requestHeaders=o;u.headersOmitted=true}if(s!==e.responseHeaders){u.responseHeaders=s;u.headersOmitted=true}}return{event:u,bytes:S(u,SNAPSHOT_EVENTS_BUDGET).bytes}}function G(e){const t=N.get(e);if(t)return t;const{event:n}=q(e);const r={...n};if(r.requestData!==void 0){r.requestData=void 0;r.requestBodyOmitted=true}if(r.responseData!==void 0){r.responseData=void 0;r.responseBodyOmitted=true}if(r.graphqlVariables!==void 0){r.graphqlVariables=D(r.graphqlVariables,true)}const o={event:r,bytes:S(r,SNAPSHOT_EVENTS_BUDGET).bytes};N.set(e,o);return o}function Y(e){const t=new Array(e.length);let n=0;for(let r=0;r<e.length;r++){const o=q(e[r]);if(n+o.bytes<=SNAPSHOT_EVENTS_BUDGET){t[r]=o.event;n+=o.bytes}else{const s=G(e[r]);t[r]=s.event;n+=s.bytes}}return t}function D(e,t=false){if(!e)return e;if(!t&&!v(e,void 0))return e;const n={};for(const[r,o]of Object.entries(e)){if(typeof o==="string"&&o.length<=64)n[r]=o;else if(typeof o==="number"||typeof o==="boolean"){n[r]=o}}return Object.keys(n).length>0?n:void 0}export const SNAPSHOT_HEADER_VALUE_LIMIT=64;function H(e){if(!e)return e;let t=false;const n={};for(const[r,o]of Object.entries(e)){if(typeof o!=="string")continue;if(o.length<=SNAPSHOT_HEADER_VALUE_LIMIT){n[r]=o}else{n[r]=`${o.slice(0,SNAPSHOT_HEADER_VALUE_LIMIT)}\u2026 [${o.length-SNAPSHOT_HEADER_VALUE_LIMIT} more]`;t=true}}return t?n:e}const X=e=>{let t=false;const n=e.rules.map(r=>{if(!r.body||r.body.length<=SNAPSHOT_BODY_INLINE_LIMIT){return r}t=true;return{...r,body:void 0,bodyOmitted:true}});return t?{...e,rules:n}:e};const p=e=>c.getEventById(e)??a.getEventById(e);const b=e=>e&&typeof e==="object"?e.id:void 0;const g=(e,t)=>!!(e&&typeof e==="object"&&e[t]);const h=()=>C()?{}:{active:false,inactiveReason:L};const Q=["respond","fail","delay"];function Z(e,t){if(!e||typeof e!=="object")return null;const n=e.rule??e;if(!n||typeof n!=="object")return null;const r=n;const o=typeof r.urlPattern==="string"&&r.urlPattern.trim()?r.urlPattern.trim():t?.urlPattern??"";if(!o)return null;const s=Q.includes(r.kind)?r.kind:t?.kind??"respond";return{id:typeof r.id==="string"?r.id:void 0,enabled:r.enabled!==false,name:typeof r.name==="string"?r.name:t?.name,urlPattern:o,methods:Array.isArray(r.methods)?r.methods.filter(d=>typeof d==="string").map(d=>d.toUpperCase()):t?.methods,requireHeader:typeof r.requireHeader==="string"&&r.requireHeader.trim()?r.requireHeader.trim():void 0,bodyIncludes:typeof r.bodyIncludes==="string"&&r.bodyIncludes?r.bodyIncludes.slice(0,4096):t?.bodyIncludes,kind:s,status:typeof r.status==="number"?r.status:t?.status,statusText:typeof r.statusText==="string"?r.statusText:t?.statusText,headers:r.headers&&typeof r.headers==="object"?r.headers:t?.headers,body:te(r,t),failKind:r.failKind==="timeout"?"timeout":void 0,delayMs:typeof r.delayMs==="number"?r.delayMs:void 0,times:typeof r.times==="number"?r.times:null,alternate:r.alternate===true}}const y=e=>!!e&&typeof e==="object"&&!Array.isArray(e);function V(e,t,n="",r={shrunk:[],breaks:[]}){if(Array.isArray(e)&&Array.isArray(t)){if(t.length>0&&t.length<e.length){r.shrunk.push({path:n||"(root)",have:e.length,sent:t.length})}return t}if(!y(e)||!y(t))return t;const o={...e};for(const[s,d]of Object.entries(t)){const u=n?`${n}.${s}`:s;if(s in e){const l=I(e[s]);const f=I(d);if((l==="array"||l==="object")&&l!==f){r.breaks.push({path:u,from:l,to:f})}o[s]=V(e[s],d,u,r)}else{o[s]=d}}return o}function ee(e,t){if(e.body!=null||!y(e.bodyPatch)||typeof t!=="string")return[];try{return K(JSON.parse(t),e.bodyPatch,{noun:"response body"})}catch{return[]}}function te(e,t){if(typeof e.body==="string")return e.body;if(e.body!=null)return JSON.stringify(e.body,null,2);const n=t?.body??(y(e.bodyPatch)&&typeof e.id==="string"?i.getState().rules.find(r=>r.id===e.id)?.body:void 0);if(y(e.bodyPatch)&&typeof n==="string"){try{return JSON.stringify(V(JSON.parse(n),e.bodyPatch),null,2)}catch{return n}}return n}function re(e){if(!e||typeof e!=="object")return null;const t=e.rule??e;if(!t||typeof t!=="object")return null;const n=t.id;if(typeof n!=="string")return null;const r=i.getState().rules.find(o=>o.id===n);return r?{...r}:null}function ne(e){if(!e||typeof e!=="object")return null;const t=e.rule??e;if(!t||typeof t!=="object")return null;const n=t;if(n.bodyOmitted!==true||typeof n.id!=="string")return null;const r=i.getState().rules.find(o=>o.id===n.id);return r?{body:r.body}:null}function oe(e){if(!e||typeof e!=="object")return null;const t=e.fromRequestId;if(typeof t!=="string"||!t)return null;const n=p(t);return n?x(n):null}export const networkSyncAdapter={dispose:()=>{i.setEnabled(false)},version:6,getSnapshot:()=>{c.ensureInterception();return{conditions:{version:1,runtimeId:k,profile:E(),available:m()},events:Y(c.getEvents()),overrides:X(i.getState()),saved:a.getRecords().map(e=>({...e,event:q(e.event).event}))}},subscribe:e=>{const t=c.subscribeToEvents(e);const n=j(e);const r=a.subscribe(e);const o=i.subscribe(e);return()=>{n();t();r();o()}},actions:{getNetworkConditions:()=>({runtimeId:k,profile:E(),available:m()}),setNetworkConditions:e=>{const t=e&&typeof e==="object"?e.profile:void 0;return{runtimeId:k,profile:T(t),available:m()}},clearEvents:()=>{c.clearEvents()},getEventBody:e=>{const t=b(e);if(!t)return null;const n=p(t);if(!n)return null;return{url:n.url??null,method:n.method??null,status:n.status??null,override:n.override??null,requestData:n.requestData??null,responseData:n.responseData??null,requestHeaders:n.requestHeaders??null,responseHeaders:n.responseHeaders??null}},setPinned:e=>{const t=b(e);if(!t)return null;const n=p(t);if(!n)return null;const r=g(e,"pinned");const o=O(a.getState(),t).pinned;if(o===r)return{ok:true};return a.togglePin(n)},setSaved:e=>{const t=b(e);if(!t)return null;const n=p(t);if(!n)return null;const r=g(e,"saved");const o=O(a.getState(),t).saved;if(o===r)return{ok:true};return a.toggleSave(n)},removeSavedRecord:e=>{const t=e&&typeof e==="object"?e.key:void 0;if(!t)return null;a.remove(t);return{ok:true}},clearSavedRequests:()=>{a.clearSaved();return{ok:true}},clearPinnedRequests:()=>{a.clearPinned();return{ok:true}},setOverridesEnabled:e=>{i.setEnabled(g(e,"enabled"));return{ok:true,enabled:i.getState().enabled,...h()}},upsertOverrideRule:e=>{const t=e?.rule??e;const n=!!t&&t.body==null&&(y(t.bodyPatch)||typeof t.bodyPath==="string");const r=oe(e)??ne(e)??(n?re(e):null);if(t&&typeof t.bodyPath==="string"&&t.body==null){const d=r?.body??(typeof t.id==="string"?i.getState().rules.find(f=>f.id===t.id)?.body:void 0);if(typeof d!=="string"){return{ok:false,error:"bodyPath needs something to patch: send fromRequestId (the captured request whose real response it addresses) or the id of an existing rule."}}if(t.bodyValue===void 0){return{ok:false,error:`Refused: sent \`bodyPath\` without \`bodyValue\`. Say what to set "${t.bodyPath}" to.`}}let u;try{u=JSON.parse(d)}catch{return{ok:false,error:"The captured response body is not JSON, so it cannot be addressed by path. Send a whole `body` instead."}}const l=J(u,t.bodyPath,t.bodyValue);if(!l.ok)return{ok:false,error:`Refused: ${l.error}`};t.bodyPatch=l.patch;delete t.bodyPath;delete t.bodyValue}if(t&&y(t.bodyPatch)&&t.body==null){const d=r?.body??(typeof t.id==="string"?i.getState().rules.find(u=>u.id===t.id)?.body:void 0);if(typeof d!=="string"){return{ok:false,error:"bodyPatch needs something to patch: send fromRequestId (the captured request whose real response the patch is merged into) or the id of an existing rule."}}if(t.force!==true){let u;try{const f=$(JSON.parse(d),t.bodyPatch);u=f.error;if(f.notes.length)t.bodyPatch=f.patch}catch{}if(u){return{ok:false,error:`Refused: ${u}`}}const l=ee(t,d);if(l.length>0){return{ok:false,error:W(l,"response body",U(t.bodyPatch,l)),violations:l}}}}const o=Z(e,r);if(!o){const d=e?.fromRequestId;return{ok:false,error:d?`No captured request \`${d}\` \u2014 it may have been cleared. Send a urlPattern instead.`:"A rule needs a non-empty urlPattern."}}const s=i.upsertRule(o);if(!s)return{ok:false,error:"Override rule limit reached."};if(s.enabled)i.setEnabled(true);return{ok:true,rule:{id:s.id,urlPattern:s.urlPattern,enabled:s.enabled,kind:s.kind,status:s.status,times:s.times,bodySize:s.body?s.body.length:0},...s.times===void 0||s.times===null?{lingers:`This rule has no \`times\` budget, so it overrides EVERY matching request until it is disabled or deleted (id \`${s.id}\`). If you meant only the next one, set times:1.`}:{},...h()}},setOverrideRuleEnabled:e=>{const t=b(e);if(!t)return{ok:false,error:"Missing rule id."};i.setRuleEnabled(t,g(e,"enabled"));return{ok:true,...h()}},deleteOverrideRule:e=>{const t=b(e);if(!t)return{ok:false,error:"Missing rule id."};i.removeRule(t);return{ok:true}},clearOverrideRules:()=>{i.clearRules();return{ok:true}},replaceOverrideRules:async e=>{const t=e??{};if(!Array.isArray(t.rules)){return{ok:false,error:"replaceOverrideRules needs `rules`: an array of rules, first match first."}}if(t.rules.length>w){return{ok:false,error:`Too many rules: ${t.rules.length}. The most is ${w}.`}}await i.ensureLoaded();const n=i.replaceAllRules(t.rules,t.enabled!==false);if(!n)return{ok:false,error:"This copy of the Network tool only mirrors a device, so it can't replace rules."};return{ok:true,count:n.length,enabled:i.getState().enabled,...h()}},listOverrideRules:async()=>{await i.ensureLoaded();return i.getState()},getOverrideRuleBody:e=>{const t=b(e);if(!t)return null;const n=i.getState().rules.find(r=>r.id===t);if(!n)return null;return{body:n.body??null}},getCaptureStatus:()=>{const e=c.getSubscriberCounts().total;let t=null;let n=null;try{t=P();n=R()}catch{}let r=null;try{r=M()}catch{}return{capturing:e>0,subscribers:e,interceptorInstalled:t,interceptorLive:r,listenerCount:n,eventCount:c.getEvents().length}},debugOverrides:e=>{const{url:t,method:n}=e&&typeof e==="object"?e:{};const r=typeof t==="string"?t:"https://example.com/";const o=typeof n==="string"&&n.trim()?n.trim().toUpperCase():"GET";return{tested:{url:r,method:o},interceptorInstalled:P(),listenerCount:R(),engine:B(r,o),store:{enabled:i.getState().enabled,autoPaused:i.getState().autoPaused,ruleCount:i.getState().rules.length,rulesVisibleToEngine:i.getRules().length}}}}};
|
|
1
|
+
"use strict";import{getNetworkConditions as v,setNetworkConditions as H,subscribeNetworkConditions as T}from"../conditions/store";import{networkEventStore as c}from"../utils/networkEventStore";import{flagsForEventId as O,networkSavedStore as a}from"../utils/networkSavedStore";import{overrideRulesStore as i}from"../overrides/overrideRulesStore";import{draftFromEvent as x}from"../overrides/presets";import{inspectEngine as B,overridesCanApply as j,OVERRIDES_INACTIVE_REASON as C}from"../overrides/engine";import{getNetworkListenerCount as E,isNetworkInterceptionLive as J,isNetworkListening as P}from"../utils/networkListener";import{MAX_RULES as R}from"../overrides/types";import{approxJsonSize as m,isOverWireBudget as L}from"@buoy-gg/shared-ui";import{expandKeyedArrays as M,patchFromPath as _,refusalText as $,shapeKind as w,suggestedPatch as W,typedEditViolations as U}from"@buoy-gg/shared-ui";export const SNAPSHOT_BODY_INLINE_LIMIT=16*1024;export const SNAPSHOT_EVENTS_BUDGET=1.25*1024*1024;function S(e,t){if(e===void 0)return false;if((t??0)>SNAPSHOT_BODY_INLINE_LIMIT)return true;return L(e,SNAPSHOT_BODY_INLINE_LIMIT)}const I=new WeakMap;const A=new WeakMap;function q(e){const t=I.get(e);if(t)return t;let n;try{n=z(e)}catch{n=K(e)}I.set(e,n);return n}function K(e){const t={...e,requestData:void 0,responseData:void 0,graphqlVariables:void 0,requestBodyOmitted:e.requestData!==void 0?true:void 0,responseBodyOmitted:e.responseData!==void 0?true:void 0};let n=1024;try{n=m(t,SNAPSHOT_EVENTS_BUDGET).bytes}catch{}return{event:t,bytes:n}}function z(e){const t=S(e.requestData,e.requestSize);const n=S(e.responseData,e.responseSize);const r=V(e.graphqlVariables);const o=N(e.requestHeaders);const s=N(e.responseHeaders);const u=t||n||r!==e.graphqlVariables||o!==e.requestHeaders||s!==e.responseHeaders;let d=e;if(u){d={...e};if(t){d.requestData=void 0;d.requestBodyOmitted=true}if(n){d.responseData=void 0;d.responseBodyOmitted=true}if(r!==e.graphqlVariables){d.graphqlVariables=r}if(o!==e.requestHeaders){d.requestHeaders=o;d.headersOmitted=true}if(s!==e.responseHeaders){d.responseHeaders=s;d.headersOmitted=true}}return{event:d,bytes:m(d,SNAPSHOT_EVENTS_BUDGET).bytes}}function F(e){const t=A.get(e);if(t)return t;const{event:n}=q(e);const r={...n};if(r.requestData!==void 0){r.requestData=void 0;r.requestBodyOmitted=true}if(r.responseData!==void 0){r.responseData=void 0;r.responseBodyOmitted=true}if(r.graphqlVariables!==void 0){r.graphqlVariables=V(r.graphqlVariables,true)}const o={event:r,bytes:m(r,SNAPSHOT_EVENTS_BUDGET).bytes};A.set(e,o);return o}function G(e){const t=new Array(e.length);let n=0;for(let r=0;r<e.length;r++){const o=q(e[r]);if(n+o.bytes<=SNAPSHOT_EVENTS_BUDGET){t[r]=o.event;n+=o.bytes}else{const s=F(e[r]);t[r]=s.event;n+=s.bytes}}return t}function V(e,t=false){if(!e)return e;if(!t&&!S(e,void 0))return e;const n={};for(const[r,o]of Object.entries(e)){if(typeof o==="string"&&o.length<=64)n[r]=o;else if(typeof o==="number"||typeof o==="boolean"){n[r]=o}}return Object.keys(n).length>0?n:void 0}export const SNAPSHOT_HEADER_VALUE_LIMIT=64;function N(e){if(!e)return e;let t=false;const n={};for(const[r,o]of Object.entries(e)){if(typeof o!=="string")continue;if(o.length<=SNAPSHOT_HEADER_VALUE_LIMIT){n[r]=o}else{n[r]=`${o.slice(0,SNAPSHOT_HEADER_VALUE_LIMIT)}\u2026 [${o.length-SNAPSHOT_HEADER_VALUE_LIMIT} more]`;t=true}}return t?n:e}const Y=e=>{let t=false;const n=e.rules.map(r=>{if(!r.body||r.body.length<=SNAPSHOT_BODY_INLINE_LIMIT){return r}t=true;return{...r,body:void 0,bodyOmitted:true}});return t?{...e,rules:n}:e};const b=e=>c.getEventById(e)??a.getEventById(e);const f=e=>e&&typeof e==="object"?e.id:void 0;const g=(e,t)=>!!(e&&typeof e==="object"&&e[t]);const h=()=>j()?{}:{active:false,inactiveReason:C};const X=["respond","fail","delay"];function Q(e,t){if(!e||typeof e!=="object")return null;const n=e.rule??e;if(!n||typeof n!=="object")return null;const r=n;const o=typeof r.urlPattern==="string"&&r.urlPattern.trim()?r.urlPattern.trim():t?.urlPattern??"";if(!o)return null;const s=X.includes(r.kind)?r.kind:t?.kind??"respond";return{id:typeof r.id==="string"?r.id:void 0,enabled:r.enabled!==false,name:typeof r.name==="string"?r.name:t?.name,urlPattern:o,methods:Array.isArray(r.methods)?r.methods.filter(u=>typeof u==="string").map(u=>u.toUpperCase()):t?.methods,requireHeader:typeof r.requireHeader==="string"&&r.requireHeader.trim()?r.requireHeader.trim():void 0,bodyIncludes:typeof r.bodyIncludes==="string"&&r.bodyIncludes?r.bodyIncludes.slice(0,4096):t?.bodyIncludes,graphqlOperation:typeof r.graphqlOperation==="string"&&r.graphqlOperation?r.graphqlOperation.slice(0,200):t?.graphqlOperation,graphqlVariables:typeof r.graphqlVariables==="string"?r.graphqlVariables.slice(0,4096):t?.graphqlVariables,bodyJson:typeof r.bodyJson==="string"&&r.bodyJson.length<=4096?r.bodyJson:t?.bodyJson,graphqlSingle:r.graphqlSingle===true?true:t?.graphqlSingle,sandbox:r.sandbox===true?true:void 0,kind:s,status:typeof r.status==="number"?r.status:t?.status,statusText:typeof r.statusText==="string"?r.statusText:t?.statusText,headers:r.headers&&typeof r.headers==="object"?r.headers:t?.headers,body:ee(r,t),failKind:r.failKind==="timeout"?"timeout":void 0,delayMs:typeof r.delayMs==="number"?r.delayMs:void 0,times:typeof r.times==="number"?r.times:null,alternate:r.alternate===true}}const k=e=>!!e&&typeof e==="object"&&!Array.isArray(e);const y=e=>k(e)||Array.isArray(e);function D(e,t,n="",r={shrunk:[],breaks:[]}){if(Array.isArray(e)&&Array.isArray(t)){if(t.length>0&&t.length<e.length){r.shrunk.push({path:n||"(root)",have:e.length,sent:t.length})}return t}if(!k(e)||!k(t))return t;const o={...e};for(const[s,u]of Object.entries(t)){const d=n?`${n}.${s}`:s;if(s in e){const l=w(e[s]);const p=w(u);if((l==="array"||l==="object")&&l!==p){r.breaks.push({path:d,from:l,to:p})}o[s]=D(e[s],u,d,r)}else{o[s]=u}}return o}function Z(e,t){if(e.body!=null||!y(e.bodyPatch)||typeof t!=="string")return[];try{return U(JSON.parse(t),e.bodyPatch,{noun:"response body"})}catch{return[]}}function ee(e,t){if(typeof e.body==="string")return e.body;if(e.body!=null)return JSON.stringify(e.body,null,2);const n=t?.body??(y(e.bodyPatch)&&typeof e.id==="string"?i.getState().rules.find(r=>r.id===e.id)?.body:void 0);if(y(e.bodyPatch)&&typeof n==="string"){try{return JSON.stringify(D(JSON.parse(n),e.bodyPatch),null,2)}catch{return n}}return n}function te(e){if(!e||typeof e!=="object")return null;const t=e.rule??e;if(!t||typeof t!=="object")return null;const n=t.id;if(typeof n!=="string")return null;const r=i.getState().rules.find(o=>o.id===n);return r?{...r}:null}function re(e){if(!e||typeof e!=="object")return null;const t=e.rule??e;if(!t||typeof t!=="object")return null;const n=t;if(n.bodyOmitted!==true||typeof n.id!=="string")return null;const r=i.getState().rules.find(o=>o.id===n.id);return r?{body:r.body}:null}function ne(e){if(!e||typeof e!=="object")return null;const t=e.fromRequestId;if(typeof t!=="string"||!t)return null;const n=b(t);return n?x(n):null}export const networkSyncAdapter={dispose:()=>{i.setEnabled(false)},version:6,getSnapshot:()=>{c.ensureInterception();return{conditions:v(),events:G(c.getEvents()),overrides:Y(i.getState()),saved:a.getRecords().map(e=>({...e,event:q(e.event).event}))}},subscribe:e=>{const t=c.subscribeToEvents(e);const n=T(e);const r=a.subscribe(e);const o=i.subscribe(e);return()=>{n();t();r();o()}},actions:{getNetworkConditions:v,setNetworkConditions:H,clearEvents:()=>{c.clearEvents()},getEventBody:e=>{const t=f(e);if(!t)return null;const n=b(t);if(!n)return null;return{url:n.url??null,method:n.method??null,status:n.status??null,override:n.override??null,condition:n.condition??null,requestData:n.requestData??null,responseData:n.responseData??null,requestHeaders:n.requestHeaders??null,responseHeaders:n.responseHeaders??null}},setPinned:e=>{const t=f(e);if(!t)return null;const n=b(t);if(!n)return null;const r=g(e,"pinned");const o=O(a.getState(),t).pinned;if(o===r)return{ok:true};return a.togglePin(n)},setSaved:e=>{const t=f(e);if(!t)return null;const n=b(t);if(!n)return null;const r=g(e,"saved");const o=O(a.getState(),t).saved;if(o===r)return{ok:true};return a.toggleSave(n)},removeSavedRecord:e=>{const t=e&&typeof e==="object"?e.key:void 0;if(!t)return null;a.remove(t);return{ok:true}},clearSavedRequests:()=>{a.clearSaved();return{ok:true}},clearPinnedRequests:()=>{a.clearPinned();return{ok:true}},setOverridesEnabled:e=>{i.setEnabled(g(e,"enabled"));return{ok:true,enabled:i.getState().enabled,...h()}},upsertOverrideRule:e=>{const t=e?.rule??e;const n=!!t&&t.body==null&&(y(t.bodyPatch)||typeof t.bodyPath==="string");const r=ne(e)??re(e)??(n?te(e):null);if(t&&typeof t.bodyPath==="string"&&t.body==null){const u=r?.body??(typeof t.id==="string"?i.getState().rules.find(p=>p.id===t.id)?.body:void 0);if(typeof u!=="string"){return{ok:false,error:"bodyPath needs something to patch: send fromRequestId (the captured request whose real response it addresses) or the id of an existing rule."}}if(t.bodyValue===void 0){return{ok:false,error:`Refused: sent \`bodyPath\` without \`bodyValue\`. Say what to set "${t.bodyPath}" to.`}}let d;try{d=JSON.parse(u)}catch{return{ok:false,error:"The captured response body is not JSON, so it cannot be addressed by path. Send a whole `body` instead."}}const l=_(d,t.bodyPath,t.bodyValue);if(!l.ok)return{ok:false,error:`Refused: ${l.error}`};t.bodyPatch=l.patch;delete t.bodyPath;delete t.bodyValue}if(t&&y(t.bodyPatch)&&t.body==null){const u=r?.body??(typeof t.id==="string"?i.getState().rules.find(l=>l.id===t.id)?.body:void 0);if(typeof u!=="string"){return{ok:false,error:"bodyPatch needs something to patch: send fromRequestId (the captured request whose real response the patch is merged into) or the id of an existing rule."}}let d;try{const l=M(JSON.parse(u),t.bodyPatch);d=l.error;if(l.notes.length)t.bodyPatch=l.patch}catch{}if(d){return{ok:false,error:`Refused: ${d}`}}if(t.force!==true){const l=Z(t,u);if(l.length>0){return{ok:false,error:$(l,"response body",W(t.bodyPatch,l)),violations:l}}}}const o=Q(e,r);if(!o){const u=e?.fromRequestId;return{ok:false,error:u?`No captured request \`${u}\` \u2014 it may have been cleared. Send a urlPattern instead.`:"A rule needs a non-empty urlPattern."}}const s=i.upsertRule(o);if(!s)return{ok:false,error:"Override rule limit reached."};if(s.enabled)i.setEnabled(true);return{ok:true,rule:{id:s.id,urlPattern:s.urlPattern,enabled:s.enabled,kind:s.kind,status:s.status,times:s.times,bodySize:s.body?s.body.length:0},...s.times===void 0||s.times===null?{lingers:`This rule has no \`times\` budget, so it overrides EVERY matching request until it is disabled or deleted (id \`${s.id}\`). If you meant only the next one, set times:1.`}:{},...h()}},setOverrideRuleEnabled:e=>{const t=f(e);if(!t)return{ok:false,error:"Missing rule id."};i.setRuleEnabled(t,g(e,"enabled"));return{ok:true,...h()}},deleteOverrideRule:e=>{const t=f(e);if(!t)return{ok:false,error:"Missing rule id."};i.removeRule(t);return{ok:true}},clearOverrideRules:()=>{i.clearRules();return{ok:true}},replaceOverrideRules:async e=>{const t=e??{};if(!Array.isArray(t.rules)){return{ok:false,error:"replaceOverrideRules needs `rules`: an array of rules, first match first."}}if(t.rules.length>R){return{ok:false,error:`Too many rules: ${t.rules.length}. The most is ${R}.`}}await i.ensureLoaded();const n=i.replaceAllRules(t.rules,t.enabled!==false);if(!n)return{ok:false,error:"This copy of the Network tool only mirrors a device, so it can't replace rules."};const r=await i.saveChecked();return{ok:true,count:n.length,enabled:i.getState().enabled,saved:r,...h()}},listOverrideRules:async()=>{await i.ensureLoaded();return i.getState()},getOverrideRuleBody:e=>{const t=f(e);if(!t)return null;const n=i.getState().rules.find(r=>r.id===t);if(!n)return null;return{body:n.body??null}},getCaptureStatus:()=>{const e=c.getSubscriberCounts().total;let t=null;let n=null;try{t=P();n=E()}catch{}let r=null;try{r=J()}catch{}return{capturing:e>0,subscribers:e,interceptorInstalled:t,interceptorLive:r,listenerCount:n,eventCount:c.getEvents().length}},debugOverrides:e=>{const{url:t,method:n}=e&&typeof e==="object"?e:{};const r=typeof t==="string"?t:"https://example.com/";const o=typeof n==="string"&&n.trim()?n.trim().toUpperCase():"GET";return{tested:{url:r,method:o},interceptorInstalled:P(),listenerCount:E(),engine:B(r,o),store:{enabled:i.getState().enabled,autoPaused:i.getState().autoPaused,ruleCount:i.getState().rules.length,rulesVisibleToEngine:i.getRules().length}}}}};
|
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
"use strict";function d(n){if(n===void 0||n===null)return"N/A";if(n===0)return"0 B";const
|
|
1
|
+
"use strict";function d(n){if(n===void 0||n===null)return"N/A";if(n===0)return"0 B";const e=1024;const u=["B","KB","MB","GB","TB"];const a=Math.floor(Math.log(n)/Math.log(e));return`${(n/Math.pow(e,a)).toFixed(1)} ${u[a]}`}function t(n,e){if(e===-1)return true;if(!n)return true;try{const u=JSON.stringify(n).length;return u<e*1024}catch{return false}}export function generateNetworkCopyText(n,e){let u=n;if(e.filterMode==="failed"){u=u.filter(s=>s.error||s.status&&s.status>=400)}else if(e.filterMode==="success"){u=u.filter(s=>s.status&&s.status>=200&&s.status<300)}if(u.length===0){return"No requests to copy"}if(e.format==="plaintext"){return u.map(s=>`${s.method} ${s.url}`).join("\n")}if(e.format==="json"){const s=u.map(i=>{const r={};if(e.includeMethod){r.method=i.method;r.url=i.url}if(e.includeStatus){r.status=i.status;r.statusText=i.statusText}if(e.includeDuration)r.duration=i.duration;if(i.condition)r.condition=i.condition;if(e.includeTimestamp)r.timestamp=i.timestamp;if(e.includeClient)r.requestClient=i.requestClient;if(e.includeSizes){r.requestSize=i.requestSize;r.responseSize=i.responseSize}if(e.includeErrors&&i.error)r.error=i.error;if(e.includeRequestHeaders){r.requestHeaders=i.requestHeaders}if(e.includeResponseHeaders){r.responseHeaders=i.responseHeaders}if(e.includeRequestBody&&t(i.requestData,e.bodySizeThreshold)){r.requestData=i.requestData}if(e.includeResponseBody&&t(i.responseData,e.bodySizeThreshold)){r.responseData=i.responseData}return r});return JSON.stringify(s,null,2)}const a=u.map((s,i)=>{let r=`# Request ${i+1}
|
|
2
2
|
|
|
3
|
-
`;if(
|
|
4
|
-
`;r+=`**URL:** ${
|
|
5
|
-
`}if(
|
|
6
|
-
`}if(
|
|
7
|
-
`}if(
|
|
8
|
-
`;if(s.
|
|
9
|
-
|
|
10
|
-
`}if(
|
|
3
|
+
`;if(e.includeMethod){r+=`**Method:** ${s.method}
|
|
4
|
+
`;r+=`**URL:** ${s.url}
|
|
5
|
+
`}if(e.includeStatus){const o=s.status||"Pending";r+=`**Status:** ${o}${s.statusText?` (${s.statusText})`:""}
|
|
6
|
+
`}if(e.includeClient&&s.requestClient){r+=`**Client:** ${s.requestClient}
|
|
7
|
+
`}if(s.condition)r+=`Conditions: ${s.condition.profile} (+${s.condition.delayMs} ms)
|
|
8
|
+
`;if(s.condition?.uploadCap?.note)r+=`${s.condition.uploadCap.note}
|
|
9
|
+
`;if(e.includeDuration&&s.duration){r+=`**Duration:** ${s.duration}ms
|
|
10
|
+
`}if(e.includeTimestamp){r+=`**Timestamp:** ${new Date(s.timestamp).toISOString()}
|
|
11
|
+
`}if(e.includeSizes){const o=s.requestSize?d(s.requestSize):"N/A";const f=s.responseSize?d(s.responseSize):"N/A";r+=`**Request Size:** ${o}
|
|
11
12
|
`;r+=`**Response Size:** ${f}
|
|
12
|
-
`}if(
|
|
13
|
-
`}if(
|
|
13
|
+
`}if(e.includeErrors&&s.error){r+=`**Error:** ${s.error}
|
|
14
|
+
`}if(e.includeRequestHeaders&&Object.keys(s.requestHeaders).length>0){r+=`
|
|
14
15
|
## Request Headers
|
|
15
16
|
\`\`\`json
|
|
16
|
-
${JSON.stringify(
|
|
17
|
+
${JSON.stringify(s.requestHeaders,null,2)}
|
|
17
18
|
\`\`\`
|
|
18
|
-
`}if(
|
|
19
|
+
`}if(e.includeRequestBody){r+=`
|
|
19
20
|
## Request Data
|
|
20
|
-
`;if(t(
|
|
21
|
-
${JSON.stringify(
|
|
21
|
+
`;if(t(s.requestData,e.bodySizeThreshold)){r+=`\`\`\`json
|
|
22
|
+
${JSON.stringify(s.requestData,null,2)}
|
|
22
23
|
\`\`\`
|
|
23
|
-
`}else{const o=
|
|
24
|
-
`}}if(
|
|
24
|
+
`}else{const o=s.requestSize?d(s.requestSize):"Unknown size";r+=`_Payload omitted (${o}). Exceeds ${e.bodySizeThreshold}KB threshold._
|
|
25
|
+
`}}if(e.includeResponseHeaders&&Object.keys(s.responseHeaders).length>0){r+=`
|
|
25
26
|
## Response Headers
|
|
26
27
|
\`\`\`json
|
|
27
|
-
${JSON.stringify(
|
|
28
|
+
${JSON.stringify(s.responseHeaders,null,2)}
|
|
28
29
|
\`\`\`
|
|
29
|
-
`}if(
|
|
30
|
+
`}if(e.includeResponseBody){r+=`
|
|
30
31
|
## Response Data
|
|
31
|
-
`;if(t(
|
|
32
|
-
${JSON.stringify(
|
|
32
|
+
`;if(t(s.responseData,e.bodySizeThreshold)){r+=`\`\`\`json
|
|
33
|
+
${JSON.stringify(s.responseData,null,2)}
|
|
33
34
|
\`\`\`
|
|
34
|
-
`}else{const o=
|
|
35
|
+
`}else{const o=s.responseSize?d(s.responseSize):"Unknown size";r+=`_Payload omitted (${o}). Exceeds ${e.bodySizeThreshold}KB threshold._
|
|
35
36
|
`}}r+=`
|
|
36
37
|
---
|
|
37
38
|
`;return r}).join("\n");const l=`# Network Requests (${u.length} total)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{isBuoyRequest as f,getAccountAccess as
|
|
1
|
+
"use strict";import{isBuoyRequest as f,getAccountAccess as h}from"@buoy-gg/shared-ui";import{BaseEventStore as v}from"@buoy-gg/shared-ui";import{extractOperationName as p}from"./extractOperationName";import{networkListener as d,addNetworkListener as l,getNetworkListenerCount as b,stopNetworkListener as g}from"./networkListener";import{networkSavedStore as m}from"./networkSavedStore";const y=200;class w extends v{replaceEvents(t){super.replaceEvents(t.filter(e=>!f(e.url)))}pendingRequests=new Map;rawListenerUnsubscribe=null;bootBuffer=[];bootBufferUnsubscribe=null;mirrorMode=false;constructor(){super({storeName:"network",maxEvents:500})}startBootCapture(){if(h().status==="locked")return;if(this.mirrorMode||this.bootBufferUnsubscribe||this.isCapturing()){return}const t=d();if(!t.isActive){t.startListening()}this.bootBufferUnsubscribe=l(e=>{this.bootBuffer.push(e);if(this.bootBuffer.length>y)this.bootBuffer.shift()})}takeBootBuffer(){if(this.bootBufferUnsubscribe){this.bootBufferUnsubscribe();this.bootBufferUnsubscribe=null}const t=this.bootBuffer;this.bootBuffer=[];return t}startCapturing(){const t=d();if(!t.isActive){t.startListening()}for(const e of this.takeBootBuffer()){this.processNetworkEvent(e)}if(!this.rawListenerUnsubscribe){this.rawListenerUnsubscribe=l(e=>{this.processNetworkEvent(e)})}t.adoptEarlyRequests()}stopCapturing(){this.takeBootBuffer();if(this.rawListenerUnsubscribe){this.rawListenerUnsubscribe();this.rawListenerUnsubscribe=null}if(b()===0){g()}}disableCapture(){this.mirrorMode=true;this.takeBootBuffer();if(b()===0){g()}super.disableCapture()}isCapturing(){return this.rawListenerUnsubscribe!==null}ensureInterception(){if(!this.isCapturing())return;d().startListening()}subscribeToEvents(t){const e=super.subscribeToEvents(t);this.ensureInterception();return e}processNetworkEvent(t){if(h().status==="locked")return;const{request:e}=t;if(f(e.url))return;if(t.type==="request"){if(this.events.some(u=>u.id===e.id))return;const r=e.params?`?${new URLSearchParams(e.params).toString()}`:"";const s=`${e.url}${r}`;let n;let o;if(e.client==="graphql"){const u=p(e.data);n=u||void 0;if(e.data&&typeof e.data==="object"&&"variables"in e.data&&e.data.variables&&typeof e.data.variables==="object"){o=e.data.variables}}const a={id:e.id,method:e.method,url:s,host:this.extractHost(e.url),path:this.extractPath(e.url),query:r,timestamp:t.timestamp.getTime(),requestHeaders:e.headers||{},requestData:e.data,requestSize:this.getDataSize(e.data),responseHeaders:{},requestClient:e.client,operationName:n,graphqlVariables:o,override:t.override,condition:t.condition};this.pendingRequests.set(e.id,a);this.events=[a,...this.events].slice(0,this.maxEvents);this.notify(a);this.notifyArrayListeners()}else if(t.type==="request-body"){const r=this.events.find(n=>n.id===e.id);if(!r)return;const s={...r,requestData:e.data,requestSize:this.getDataSize(e.data)};if(e.client==="graphql"){s.operationName=p(e.data)||void 0;const n=e.data?.variables;if(n&&typeof n==="object")s.graphqlVariables=n}this.events=this.events.map(n=>n.id===e.id?s:n);if(this.pendingRequests.has(e.id))this.pendingRequests.set(e.id,s);m.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}else if(t.type==="response"||t.type==="error"){const r=this.events.findIndex(s=>s.id===e.id);if(r!==-1){const s={...this.events[r],duration:t.duration,timings:t.timings};if(t.response){s.status=t.response.status;s.statusText=t.response.statusText;s.responseHeaders=t.response.headers||{};s.responseData=t.response.body;s.responseJson=typeof t.response.json==="boolean"?t.response.json:void 0;s.responseTruncated=t.response.truncated===true||void 0;s.responseUnread=t.response.unread===true||void 0;s.responseSize=t.response.size||0;s.responseType=t.response.headers?.["content-type"]}if(t.error){s.error=t.error.message;s.status=s.status||0}if(t.override)s.override=t.override;this.events=this.events.map((n,o)=>o===r?s:n);this.pendingRequests.delete(e.id);m.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}}}extractHost(t){try{const e=new URL(t);return e.hostname}catch{return""}}extractPath(t){try{const e=new URL(t);return e.pathname}catch{return t}}getDataSize(t){if(!t)return 0;if(typeof t==="string")return t.length;try{return JSON.stringify(t).length}catch{return 0}}getEventById(t){return this.events.find(e=>e.id===t)}clearEvents(){super.clearEvents();this.pendingRequests.clear()}onEvent(t,e=true){const r=this.subscribe(t);if(e&&this.events.length>0){const s=[...this.events].reverse();for(const n of s){try{t(n)}catch{}}}return r}getStats(){const t=this.events.length;const e=this.events.filter(i=>i.status&&i.status>=200&&i.status<300).length;const r=this.events.filter(i=>i.error||i.status&&i.status>=400).length;const s=this.events.filter(i=>!i.status&&!i.error).length;const n=this.events.filter(i=>i.duration).map(i=>i.duration);const o=n.length>0?n.reduce((i,c)=>i+c,0)/n.length:0;const a=this.events.reduce((i,c)=>i+(c.requestSize||0),0);const u=this.events.reduce((i,c)=>i+(c.responseSize||0),0);return{totalRequests:t,successfulRequests:e,failedRequests:r,pendingRequests:s,totalDataSent:a,totalDataReceived:u,averageDuration:Math.round(o)}}filterEvents(t){let e=[...this.events];if(t.method){e=e.filter(r=>r.method===t.method)}if(t.status){switch(t.status){case"success":e=e.filter(r=>r.status&&r.status>=200&&r.status<300);break;case"error":e=e.filter(r=>r.error||r.status&&r.status>=400);break;case"pending":e=e.filter(r=>!r.status&&!r.error);break}}if(t.searchText){const r=t.searchText.toLowerCase();e=e.filter(s=>s.url.toLowerCase().includes(r)||s.method.toLowerCase().includes(r)||s.error&&s.error.toLowerCase().includes(r))}if(t.host){e=e.filter(r=>r.host===t.host)}return e}}export const networkEventStore=new w;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";import{isBuoyRequest as
|
|
1
|
+
"use strict";import{paceByteCount as be,paceResponse as me,uploadBodySize as ge,uploadSize as Re,utf8Length as we}from"../conditions/pacer";import{isBuoyRequest as Le}from"@buoy-gg/shared-ui";import{resolveRequestUrl as K}from"./resolveRequestUrl";import{nextRequestId as V}from"./requestId";import{runConditionXhr as He}from"../conditions/xhr";import{snapshotNetworkCondition as ue}from"../conditions/store";import{throwIfAborted as ee,waitBeforeDispatch as qe}from"../conditions/wait";import{accountCheckFor as Se,overrideForRequest as le,overrideRulesLoaded as _e,overrideRulesNeedBody as Te,overrideRulesReady as pe}from"../overrides/engine";import{runOverride as Ee,hasPendingStandardRequest as ve}from"../overrides/applyToXhr";import{canSynthesizeResponse as te,synthesizeFetchError as Oe,synthesizeResponse as Xe}from"../overrides/applyToFetch";import{markForOutcome as he}from"../overrides/types";import{httpStatusText as ke,xhrCompletionKind as Ne}from"./httpCompletion";import{realNow as X}from"./realNow";let M;function fe(g){const e=globalThis.__buoyHeaderInjectors;if(!e||e.length===0)return void 0;let t;for(const s of e){try{const l=s(g);if(l)t={...t,...l}}catch{}}return t}function xe(){if(M!==void 0)return M;M=null;try{if(typeof __DEV__!=="undefined"&&!__DEV__)return M;const g=require("react-native");const e=g?.NativeModules?.SourceCode;const t=e?.getConstants?.().scriptURL??e?.scriptURL;if(typeof t==="string"&&/^https?:\/\//.test(t)){const s=new URL(t);M=`${s.protocol}//${s.host}`}}catch{M=null}return M}let j=false;const Ce=Symbol.for("buoy.earlyNetwork");function Be(g){const e={};if(!g)return e;if(typeof Headers!=="undefined"&&g instanceof Headers)g.forEach((t,s)=>{e[s]=t});else if(Array.isArray(g))for(const[t,s]of g)e[t]=s;else Object.assign(e,g);return e}export const BUOY_FETCH_INTERCEPTOR_FLAG="__buoyNetworkFetchIntercepted";export const BUOY_XHR_INTERCEPTOR_FLAG="__buoyNetworkXhrIntercepted";const Ie=["text/event-stream","application/x-ndjson","application/stream+json"];const se="[streaming\u2026]";let ne=false;function Ae(){if(ne)return true;const g=globalThis.document;ne=!!g?.querySelector?.("[ng-version]");return ne}function ye(g){if(!g)return false;const e=g.toLowerCase();return Ie.some(t=>e.includes(t))}const Me="__BUOY_INTERNAL_HOSTS__";function je(g){const e=globalThis[Me];if(!(e instanceof Set)||e.size===0)return false;let t;try{t=new URL(g).host.toLowerCase()}catch{return false}for(const s of e){if(typeof s==="string"&&s&&t===s.toLowerCase())return true}return false}class Ue{listeners=[];isListening=false;patchedFetch=null;patchedXHROpen=null;patchedXHRSend=null;patchedXHRSetRequestHeader=null;fetchGeneration=0;xhrGeneration=0;constructor(){this.originalFetch=globalThis.fetch;this.originalXHROpen=XMLHttpRequest.prototype.open;this.originalXHRSend=XMLHttpRequest.prototype.send;this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader}shouldIgnoreUrl(e){if(Le(e))return true;try{const t=new URL(e);if(t.hostname==="keygen.sh"||t.hostname.endsWith(".keygen.sh"))return true;if((t.hostname==="buoy.gg"||t.hostname==="www.buoy.gg")&&(t.pathname.startsWith("/api/license")||t.pathname.startsWith("/api/settings/")))return true;const s=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="10.0.2.2";if(s&&["8081","8802"].includes(t.port))return true;const l=xe();if(l&&`${t.protocol}//${t.host}`===l)return true}catch{return false}return je(e)}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(s){}})}parseUrl(e){let t=null;const s=e.indexOf("?");if(s>-1){t={};e.substring(s+1).split("&").forEach(l=>{const[u,o]=l.split("=");if(u&&o!==void 0){t[u]=decodeURIComponent(o.replace(/\+/g," "))}})}return{url:s>-1?e.substring(0,s):e,params:t}}async readStreamedBody(e,t=256*1024){const s=e.body;if(!s||typeof s.getReader!=="function"){const f=await e.text();return f.length>t?{body:`${f.slice(0,t)}
|
|
2
2
|
|
|
3
|
-
... [truncated]`,size:f.length}:{body:f,size:f.length}}const
|
|
3
|
+
... [truncated]`,size:f.length,truncated:true}:{body:f,size:f.length}}const l=s.getReader();const u=new TextDecoder;let o="";let h=0;let m=false;try{for(;;){const{done:f,value:i}=await l.read();if(f)break;h+=i?.byteLength??0;if(!m){o+=u.decode(i,{stream:true});if(h>=t){o=`${o.slice(0,t)}
|
|
4
4
|
|
|
5
|
-
... [truncated]`;
|
|
5
|
+
... [truncated]`;m=true;break}}}if(!m)o+=u.decode()}finally{try{void Promise.resolve(l.cancel()).catch(()=>{})}catch{}try{l.releaseLock()}catch{}}return{body:o,size:h,truncated:m||void 0}}async processResponseBody(e,t=1024*1024){try{const s=e.headers.get("content-length");if(s){const o=parseInt(s,10);if(!isNaN(o)&&o>t){return{body:`[Response too large: ${this.formatBytes(o)}]`,size:o,truncated:true,json:false}}}const l=await e.text();const u=l.length;if(u>t){const o=l.substring(0,t);const h=u-t;return{body:`${o}
|
|
6
6
|
|
|
7
|
-
... [truncated, ${this.formatBytes(h)} omitted]`,size:a,truncated:true}}try{return{body:JSON.parse(c),size:a,truncated:false}}catch{return{body:c,size:a,truncated:false}}}catch(n){return{body:"~~~ unable to read body ~~~",size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const n=["B","KB","MB","GB"];const c=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,c)*100)/100} ${n[c]}`}handleXHRResponse(e,t,n,c,a,r,h,R,f=false,i="xhr",d,H){const y=R?S()-R:0;const l=e._buoyTtfb;const _=l===void 0?void 0:{ttfb:l,download:Math.max(0,y-l)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:y,request:{id:t||"unknown",url:n,method:c,headers:a,data:r,params:h||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:d,condition:H});return}let s;let p=0;try{const o=e.response;if(e.responseType==="json"&&o){s=o;p=JSON.stringify(o).length}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{s=JSON.parse(e.responseText)}catch{s=e.responseText}}}else if(e.responseType==="arraybuffer"){if(o){try{const q=new TextDecoder("utf-8").decode(o);p=q.length;try{s=JSON.parse(q)}catch{s=q}}catch(q){s=`[arraybuffer response - ${o.byteLength||0} bytes]`;p=o.byteLength||0}}else{s=`[arraybuffer response - no data]`;p=0}}else if(e.responseType==="blob"){if(o instanceof Blob){s=`[blob response - ${o.size} bytes, type: ${o.type||"unknown"}]`;p=o.size}else if(o){try{s=typeof o==="string"?JSON.parse(o):o;p=JSON.stringify(s).length}catch{s=`[blob response - unable to parse]`;p=0}}else{s=`[blob response - no data]`;p=0}}else if(o){if(typeof o==="string"){s=o;p=o.length;try{s=JSON.parse(o)}catch{}}else if(typeof o==="object"){s=o;p=JSON.stringify(o).length}else{s=String(o);p=String(o).length}}}catch(o){s="~~~ unable to read body ~~~"}const b={};try{const o=e.getAllResponseHeaders();if(o){o.split("\r\n").forEach(q=>{if(q){const m=q.indexOf(": ");if(m>0){const T=q.substring(0,m).toLowerCase();const u=q.substring(m+2);b[T]=u}}})}}catch{}if(ae(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:y,timings:_,request:{id:t||"unknown",url:n,method:c,headers:a,data:r,params:h||void 0,client:i},response:{status:e.status,statusText:ie(e.status,e.statusText),headers:b,body:s,size:p},override:d,condition:H})}else{this.emit({type:"error",timestamp:new Date,duration:y,request:{id:t||"unknown",url:n,method:c,headers:a,data:r,params:h||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:b,body:s,size:p},error:{message:"Network Error"},override:d,condition:H})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const n=++this.fetchGeneration;const c=async(a,r)=>{const h=B(typeof a==="string"?a:a instanceof URL?a.href:a.url);if(n!==e.fetchGeneration){return t(a,r)}if(r?.__buoyInternal||e.shouldIgnoreUrl(h)){const u=x;x=true;try{return t(a,r)}finally{x=u}}const R=S();const f=D("fetch");const i=typeof a==="object"&&"method"in a?a:void 0;const d=r?.method??i?.method??"GET";const H=r?.signal!==void 0?r.signal:i?.signal;J(H);const y=j(h);const{url:l,params:_}=e.parseUrl(h);let s={};const p=r?.headers??i?.headers;if(p){if(p instanceof Headers){p.forEach((u,L)=>{s[L]=u})}else if(Array.isArray(p)){p.forEach(([u,L])=>{s[u]=L})}else{s={...p}}}Object.assign(s,W(h));let b;if(r?.body){if(typeof r.body==="string"){try{b=JSON.parse(r.body)}catch{b=r.body}}else{b=r.body}}const o=s["X-Request-Client"]||s["x-request-client"]||"fetch";const q=y?.profile!=="offline"&&P()?te(h,d,s,typeof r?.body==="string"?r.body:void 0):null;if(q)await q;const m=y?.profile!=="offline"&&P()?$(h,d,s,typeof r?.body==="string"?r.body:void 0):null;const T=m?Y(m):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,headers:s,data:b,params:_||void 0,client:o},override:T,condition:y});if(r?.body===void 0&&i?.body&&!i.bodyUsed){try{const u=i.clone();void e.readStreamedBody(u).then(({body:L})=>{try{b=JSON.parse(L)}catch{b=L}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,data:b,client:o}})}).catch(()=>{})}catch{}}try{if(y||m)await ee((y?.delayMs??0)+(m?.delayMs??0),H);J(H);if(y?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(m?.kind==="fail")throw re(m);let u;if(m?.kind==="respond"){u=oe(h,m)}else{const X=x;x=true;let w;try{w=t(a,r)}finally{x=X}u=await w}const L=S()-R;const E=typeof u.body?.getReader==="function"||V(u.headers?.get?.("content-type"));const I=u.clone();const{body:C,size:O}=E?{body:K,size:0}:await e.processResponseBody(I);const M=S()-R;const F=Math.max(0,M-L);const U=F>0?{ttfb:L,download:F}:void 0;const N={};u.headers.forEach((X,w)=>{N[w.toLowerCase()]=X});e.emit({type:"response",timestamp:new Date,duration:M,timings:U,request:{id:f||"unknown",url:l,method:d,headers:s,data:b,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:N,body:C,size:O},override:T,condition:y});if(E){const X=u.headers?.get?.("content-type");void e.readStreamedBody(I,V(X)?void 0:1024*1024).then(w=>{let G=w.body;if(X?.includes("json")){try{G=JSON.parse(w.body)}catch{}}e.emit({type:"response",timestamp:new Date,duration:S()-R,timings:U,request:{id:f||"unknown",url:l,method:d,headers:s,data:b,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:N,body:G,size:w.size},override:T,condition:y})}).catch(()=>{})}return u}catch(u){const L=S()-R;e.emit({type:"error",timestamp:new Date,duration:L,request:{id:f||"unknown",url:l,method:d,headers:s,data:b,params:_||void 0,client:o},error:{message:u instanceof Error?u.message:"Network error",stack:u instanceof Error?u.stack:void 0},override:T,condition:y});throw u}};c[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=c;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const n=XMLHttpRequest.prototype.send;const c=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=n;this.originalXHRSetRequestHeader=c;const a=++this.xhrGeneration;const r=new WeakMap;const h=function(i,d,H,y,l){const _=t.call(this,i,d,H??true,y,l);if(a===e.xhrGeneration){r.get(this)?.();const s=this;s._buoyRequestId=D("xhr");s._method=i;s._url=B(d);s._buoyStartTime=S();s._requestHeaders={}}return _};const R=function(i,d){const H=this;if(a===e.xhrGeneration&&H._requestHeaders){H._requestHeaders[i]=d}return c.call(this,i,d)};const f=function(i){if(a!==e.xhrGeneration||x){return n.call(this,i)}if(ne(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return n.call(this,i)}const d=this;const H=d._buoyRequestId;const y=d._method||"GET";const l=d._url||"";const _=S();d._buoyStartTime=_;d._buoyTtfb=void 0;const s=d._requestHeaders||{};Object.assign(s,W(l));if(e.shouldIgnoreUrl(l)){return n.call(this,i)}const{url:p,params:b}=e.parseUrl(l);let o;if(i){if(typeof i==="string"){try{o=JSON.parse(i)}catch{o=i}}else{o=i}}const q=s["X-Request-Client"]||s["x-request-client"];const m=s["Accept"]||s["accept"]||"";const T=m.includes("application/json")&&m.includes("text/plain")&&m.includes("*/*")&&!he();const u=q||(T?"axios":"xhr");const L=j(l);const E=L?.profile==="offline"?null:$(l,y,s,typeof i==="string"?i:void 0);const I=E?Y(E):void 0;e.emit({type:"request",timestamp:new Date,request:{id:H||"unknown",url:p,method:y,headers:s,data:o,params:b||void 0,client:u},override:I,condition:L});let C=false;const O=(w=false)=>{if(C)return;C=true;e.handleXHRResponse(this,H||"unknown",p,y,s,o,b,_||0,w,u,I,L);M()};const M=()=>{r.delete(this);this.removeEventListener("load",F);this.removeEventListener("error",U);this.removeEventListener("abort",N);this.removeEventListener("readystatechange",X)};r.set(this,M);const F=()=>{O(false)};const U=()=>{O(true)};const N=()=>{O(true)};const X=()=>{if(this.readyState===2){const w=this;if(w._buoyTtfb===void 0&&w._buoyStartTime){w._buoyTtfb=S()-w._buoyStartTime}}if(this.readyState===4&&!C){O(false)}};this.addEventListener("load",F);this.addEventListener("error",U);this.addEventListener("abort",N);this.addEventListener("readystatechange",X);if(L){Z(this,l,L,E,()=>n.call(this,i));return}if(E){const w=se(this,l,E,()=>n.call(this,i));if(w)return}return n.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=h;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=R;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis.__BUOY_EARLY_NETWORK__;if(e?.version!==1)return;for(const t of e.adopt()){try{if(t.kind==="fetch")this.adoptEarlyFetch(t);else this.adoptEarlyXhr(t)}catch{}}}adoptEarlyFetch(e){const{input:t,init:n}=e;const c=typeof t==="object"&&"method"in t?t:void 0;const a=B(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(a))return;const r=D("fetch");const h=n?.method??c?.method??"GET";const{url:R,params:f}=this.parseUrl(a);const i=de(n?.headers??c?.headers);let d=n?.body;if(typeof d==="string"){try{d=JSON.parse(d)}catch{}}const H=i["X-Request-Client"]||i["x-request-client"]||"fetch";const y=()=>({id:r,url:R,method:h,headers:i,data:d,params:f||void 0,client:H});this.emit({type:"request",timestamp:new Date(e.start),request:y()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:l})=>{try{d=JSON.parse(l)}catch{d=l}this.emit({type:"request-body",timestamp:new Date,request:{id:r,url:R,method:h,data:d,client:H}})}).catch(()=>{})}void e.settled.then(async({response:l,clone:_,error:s,headersAt:p})=>{if(!l){this.emit({type:"error",timestamp:new Date,duration:p-e.start,request:y(),error:{message:s instanceof Error?s.message:"Network error",stack:s instanceof Error?s.stack:void 0}});return}const{body:b,size:o}=_?await this.processResponseBody(_):{body:K,size:0};const q=Math.max(0,S()-e.start);const m=p-e.start;const T={};l.headers.forEach((u,L)=>{T[L.toLowerCase()]=u});this.emit({type:"response",timestamp:new Date,duration:q,timings:q>m?{ttfb:m,download:q-m}:void 0,request:y(),response:{status:l.status,statusText:l.statusText,headers:T,body:b,size:o}})})}adoptEarlyXhr(e){const t=B(e.url);if(this.shouldIgnoreUrl(t))return;const n=D("xhr");const c=e.method.toUpperCase();const{url:a,params:r}=this.parseUrl(t);let h=e.body;if(typeof h==="string"){try{h=JSON.parse(h)}catch{}}const R=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:n,url:a,method:c,headers:e.headers,data:h,params:r||void 0,client:R}});const f=e.xhr;const i=()=>{const d=(f._buoyEarlyEnd??S())-e.start;this.handleXHRResponse(f,n,a,c,e.headers,h,r,S()-d,false,R)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let v=null;const z=()=>{if(!v){v=new fe}return v};export const networkListener=z;export const startNetworkListener=()=>z().startListening();export const stopNetworkListener=()=>v?.stopListening();export const addNetworkListener=g=>z().addListener(g);export const removeAllNetworkListeners=()=>v?.removeAllListeners();export const isNetworkListening=()=>v?.isActive??false;export const getNetworkListenerCount=()=>v?.listenerCount??0;export const isNetworkInterceptionLive=()=>v?.isInterceptionLive()??false;
|
|
7
|
+
... [truncated, ${this.formatBytes(h)} omitted]`,size:u,truncated:true,json:false}}try{return{body:JSON.parse(l),size:u,truncated:false,json:true}}catch{return{body:l,size:u,truncated:false,json:false}}}catch(s){return{body:"~~~ unable to read body ~~~",json:false,unread:true,size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const s=["B","KB","MB","GB"];const l=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,l)*100)/100} ${s[l]}`}handleXHRResponse(e,t,s,l,u,o,h,m,f=false,i="xhr",n,b){const L=m?X()-m:0;const c=e._buoyTtfb;const q=c===void 0?void 0:{ttfb:c,download:Math.max(0,L-c)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:L,request:{id:t||"unknown",url:s,method:l,headers:u,data:o,params:h||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:n,condition:b});return}let r;let y=false;let R=false;let p=0;try{const a=e.response;if(e.responseType==="json"){const H=e.status===204||e.status===205||e.status===304||l.toUpperCase()==="HEAD"||e.getResponseHeader?.("content-length")==="0";if(a===null){r=void 0;R=!H;p=0}else{r=a;y=true;p=JSON.stringify(a).length}}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{r=JSON.parse(e.responseText);y=true}catch{r=e.responseText}}}else if(e.responseType==="arraybuffer"){if(a){try{const H=new TextDecoder("utf-8").decode(a);p=H.length;try{r=JSON.parse(H);y=true}catch{r=H}}catch(H){r=`[arraybuffer response - ${a.byteLength||0} bytes]`;R=true;p=a.byteLength||0}}else{r=`[arraybuffer response - no data]`;R=true;p=0}}else if(e.responseType==="blob"){if(a instanceof Blob){r=`[blob response - ${a.size} bytes, type: ${a.type||"unknown"}]`;R=true;p=a.size}else if(a){try{r=typeof a==="string"?JSON.parse(a):a;p=JSON.stringify(r).length}catch{r=`[blob response - unable to parse]`;R=true;p=0}}else{r=`[blob response - no data]`;R=true;p=0}}else if(a){if(typeof a==="string"){r=a;p=a.length;try{r=JSON.parse(a);y=true}catch{}}else if(typeof a==="object"){r=a;p=JSON.stringify(a).length}else{r=String(a);p=String(a).length}}}catch(a){r="~~~ unable to read body ~~~";R=true}if(b?.downloadBytesPerSecond&&(!e.responseType||e.responseType==="text"||e.responseType==="json")){const a=e._response;if(typeof a==="string")p=we(a)}const E={};try{const a=e.getAllResponseHeaders();if(a){a.split("\r\n").forEach(H=>{if(H){const w=H.indexOf(": ");if(w>0){const T=H.substring(0,w).toLowerCase();const v=H.substring(w+2);E[T]=v}}})}}catch{}if(Ne(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:L,timings:q,request:{id:t||"unknown",url:s,method:l,headers:u,data:o,params:h||void 0,client:i},response:{status:e.status,statusText:ke(e.status,e.statusText),headers:E,body:r,size:p,json:y,unread:R||void 0},override:n,condition:b})}else{this.emit({type:"error",timestamp:new Date,duration:L,request:{id:t||"unknown",url:s,method:l,headers:u,data:o,params:h||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:E,body:r,size:p},error:{message:"Network Error"},override:n,condition:b})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const s=++this.fetchGeneration;const l=async(u,o)=>{const h=K(typeof u==="string"?u:u instanceof URL?u.href:u.url);if(s!==e.fetchGeneration){return t(u,o)}if(o?.__buoyInternal||e.shouldIgnoreUrl(h)){const d=j;j=true;try{return t(u,o)}finally{j=d}}const m=X();const f=V("fetch");const i=typeof u==="object"&&"method"in u?u:void 0;const n=o?.method??i?.method??"GET";const b=o?.signal!==void 0?o.signal:i?.signal;ee(b);const L=ue(h);const c=L?.uploadBytesPerSecond?{...L,uploadCap:ge(u,o)}:L;const{url:q,params:r}=e.parseUrl(h);let y={};const R=o?.headers??i?.headers;if(R){if(R instanceof Headers){R.forEach((d,S)=>{y[S]=d})}else if(Array.isArray(R)){R.forEach(([d,S])=>{y[d]=S})}else{y={...R}}}Object.assign(y,fe(h));let p;if(o?.body){if(typeof o.body==="string"){try{p=JSON.parse(o.body)}catch{p=o.body}}else{p=o.body}}const E=y["X-Request-Client"]||y["x-request-client"]||"fetch";if(c?.profile!=="offline"&&te())await pe();let a=typeof o?.body==="string"?o.body:void 0;if(a===void 0&&o?.body===void 0&&i&&!i.bodyUsed&&n!=="GET"&&n!=="HEAD"&&Te()){try{a=(await e.readStreamedBody(i.clone())).body}catch{}}const H=c?.profile!=="offline"&&te()?Se(h,n,y,a):null;if(H)await H;const w=c?.profile!=="offline"&&te()?le(h,n,y,a):null;const T=w?he(w):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:q,method:n,headers:y,data:p,params:r||void 0,client:E},override:T,condition:c});const v=d=>{try{p=JSON.parse(d)}catch{p=d}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:q,method:n,data:p,client:E}})};if(o?.body===void 0&&i&&typeof a==="string"){v(a)}else if(!c?.uploadBytesPerSecond&&o?.body===void 0&&i&&!i.bodyUsed&&n!=="GET"&&n!=="HEAD"){try{const d=i.clone();void e.readStreamedBody(d).then(({body:S})=>{if(S)v(S)}).catch(()=>{})}catch{}}try{if(c||w)await qe((c?.delayMs??0)+(w?.delayMs??0),b);ee(b);if(c?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(w?.kind==="fail")throw Oe(w);if(c?.uploadBytesPerSecond){await be(c.uploadCap?.knownBytes??0,c.uploadBytesPerSecond,b);ee(b)}let d;if(w?.kind==="respond"){d=Xe(h,w)}else{const k=j;j=true;let _;try{_=t(u,o)}finally{j=k}d=await _}if(c?.downloadBytesPerSecond){const k={};d.headers.forEach((N,x)=>{k[x.toLowerCase()]=N});let _=0;let A=0;const G=[];const oe=(N,x)=>{const F=new Uint8Array(A);let ie=0;for(const ce of G){F.set(ce,ie);ie+=ce.byteLength}let Q=N?new TextDecoder().decode(F):se;let ae=false;if(N&&k["content-type"]?.includes("json")){try{Q=JSON.parse(Q);ae=true}catch{}}const de=_>A;const Z=!N||x!==void 0;e.emit({type:x!==void 0?"error":"response",timestamp:new Date,duration:X()-m,request:{id:f,url:q,method:n,headers:y,data:p,params:r||void 0,client:E},response:{status:d.status,statusText:d.statusText,headers:k,body:Q,size:_,json:ae&&!de&&!Z,truncated:de&&!Z,...Z?{unread:true}:{}},...x!==void 0?{error:{message:x instanceof Error?x.message:String(x)}}:{},override:T,condition:c})};oe(false);return me(d,c.downloadBytesPerSecond,b,(N,x)=>{if(N){_+=N.byteLength;const F=Math.min(N.byteLength,65536-A);if(F>0){G.push(N.slice(0,F));A+=F}}else oe(true,x)},n.toUpperCase()==="HEAD")}const S=X()-m;const U=typeof d.body?.getReader==="function"||ye(d.headers?.get?.("content-type"));const I=d.clone();const{body:J,size:P,json:$,truncated:W,unread:Y}=U?{body:se,size:0,json:false,truncated:false,unread:true}:await e.processResponseBody(I);const O=X()-m;const z=Math.max(0,O-S);const D=z>0?{ttfb:S,download:z}:void 0;const C={};d.headers.forEach((k,_)=>{C[_.toLowerCase()]=k});e.emit({type:"response",timestamp:new Date,duration:O,timings:D,request:{id:f||"unknown",url:q,method:n,headers:y,data:p,params:r||void 0,client:E},response:{status:d.status,statusText:d.statusText,headers:C,body:J,size:P,json:$,truncated:W||void 0,unread:Y||void 0},override:T,condition:c});if(U){const k=d.headers?.get?.("content-type");void e.readStreamedBody(I,ye(k)?void 0:1024*1024).then(_=>{let A=_.body;let G=false;if(k?.toLowerCase().includes("json")){try{A=JSON.parse(_.body);G=true}catch{}}e.emit({type:"response",timestamp:new Date,duration:X()-m,timings:D,request:{id:f||"unknown",url:q,method:n,headers:y,data:p,params:r||void 0,client:E},response:{status:d.status,statusText:d.statusText,headers:C,body:A,size:_.size,json:G,truncated:_.truncated},override:T,condition:c})}).catch(()=>{})}return d}catch(d){const S=X()-m;e.emit({type:"error",timestamp:new Date,duration:S,request:{id:f||"unknown",url:q,method:n,headers:y,data:p,params:r||void 0,client:E},error:{message:d instanceof Error?d.message:"Network error",stack:d instanceof Error?d.stack:void 0},override:T,condition:c});throw d}};l[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=l;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const s=XMLHttpRequest.prototype.send;const l=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=s;this.originalXHRSetRequestHeader=l;const u=++this.xhrGeneration;const o=new WeakMap;const h=function(i,n,b,L,c){const q=t.call(this,i,n,b??true,L,c);if(u===e.xhrGeneration){o.get(this)?.();const r=this;r._buoyRequestId=V("xhr");r._method=i;r._url=K(n);r._buoyStartTime=X();r._requestHeaders={};r._buoyAsync=b!==false;r._buoyRestoreAbort?.();r._buoyWaitedForRules=false;r._buoyHeldSend=false;r._buoyOpenSeq=(r._buoyOpenSeq??0)+1}return q};const m=function(i,n){const b=this;if(u===e.xhrGeneration&&b._requestHeaders){b._requestHeaders[i]=n}return l.call(this,i,n)};const f=function(i){if(u!==e.xhrGeneration||j){return s.call(this,i)}if(ve(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return s.call(this,i)}const n=this;if(n._buoyHeldSend)throw new DOMException("The request has already been sent.","InvalidStateError");if(!_e()&&n._buoyAsync!==false&&!n._buoyWaitedForRules){n._buoyWaitedForRules=true;n._buoyHeldSend=true;const O=n._buoyOpenSeq;let z=false;const D=Object.prototype.hasOwnProperty.call(this,"abort")?this.abort:void 0;const C=()=>{if(n._buoyRestoreAbort!==C)return;n._buoyRestoreAbort=void 0;if(D)this.abort=D;else delete this.abort};n._buoyRestoreAbort=C;const k=D??Object.getPrototypeOf(this).abort;this.abort=function(){z=true;n._buoyHeldSend=false;C();return k.call(this)};const _=()=>{C();if(z||n._buoyOpenSeq!==O)return;n._buoyHeldSend=false;if(this.readyState===1&&!this._sent)f.call(this,i)};void pe().then(_,_);return}const b=n._buoyRequestId;const L=n._method||"GET";const c=n._url||"";const q=X();n._buoyStartTime=q;n._buoyTtfb=void 0;const r=n._requestHeaders||{};Object.assign(r,fe(c));if(e.shouldIgnoreUrl(c)){return s.call(this,i)}const{url:y,params:R}=e.parseUrl(c);let p;if(i){if(typeof i==="string"){try{p=JSON.parse(i)}catch{p=i}}else{p=i}}const E=r["X-Request-Client"]||r["x-request-client"];const a=r["Accept"]||r["accept"]||"";const H=a.includes("application/json")&&a.includes("text/plain")&&a.includes("*/*")&&!Ae();const w=E||(H?"axios":"xhr");const T=ue(c);const v=T?.uploadBytesPerSecond?{...T,uploadCap:Re(i)}:T;const d=v?.profile==="offline"?null:le(c,L,r,typeof i==="string"?i:void 0);const S=d?he(d):void 0;e.emit({type:"request",timestamp:new Date,request:{id:b||"unknown",url:y,method:L,headers:r,data:p,params:R||void 0,client:w},override:S,condition:v});let U=false;const I=(O=false)=>{if(U)return;U=true;e.handleXHRResponse(this,b||"unknown",y,L,r,p,R,q||0,O,w,S,v);J()};const J=()=>{o.delete(this);this.removeEventListener("load",P);this.removeEventListener("error",$);this.removeEventListener("abort",W);this.removeEventListener("readystatechange",Y)};o.set(this,J);const P=()=>{I(false)};const $=()=>{I(true)};const W=()=>{I(true)};const Y=()=>{if(this.readyState===2){const O=this;if(O._buoyTtfb===void 0&&O._buoyStartTime){O._buoyTtfb=X()-O._buoyStartTime}}if(this.readyState===4&&!U){I(false)}};this.addEventListener("load",P);this.addEventListener("error",$);this.addEventListener("abort",W);this.addEventListener("readystatechange",Y);if(v){He(this,c,v,d,()=>s.call(this,i),i);return}if(d){const O=Ee(this,c,d,()=>s.call(this,i));if(O)return}return s.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=h;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=m;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis;const t=e[Ce]??e.__BUOY_EARLY_NETWORK__;if(t?.version!==1)return;for(const s of t.adopt()){try{if(s.kind==="fetch")this.adoptEarlyFetch(s);else this.adoptEarlyXhr(s)}catch{}}}adoptEarlyFetch(e){const{input:t,init:s}=e;const l=typeof t==="object"&&"method"in t?t:void 0;const u=K(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(u))return;const o=V("fetch");const h=s?.method??l?.method??"GET";const{url:m,params:f}=this.parseUrl(u);const i=Be(s?.headers??l?.headers);let n=s?.body;if(typeof n==="string"){try{n=JSON.parse(n)}catch{}}const b=i["X-Request-Client"]||i["x-request-client"]||"fetch";const L=()=>({id:o,url:m,method:h,headers:i,data:n,params:f||void 0,client:b});this.emit({type:"request",timestamp:new Date(e.start),request:L()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:c})=>{try{n=JSON.parse(c)}catch{n=c}this.emit({type:"request-body",timestamp:new Date,request:{id:o,url:m,method:h,data:n,client:b}})}).catch(()=>{})}void e.settled.then(async({response:c,clone:q,error:r,headersAt:y})=>{if(!c){this.emit({type:"error",timestamp:new Date,duration:y-e.start,request:L(),error:{message:r instanceof Error?r.message:"Network error",stack:r instanceof Error?r.stack:void 0}});return}const{body:R,size:p,json:E,truncated:a,unread:H}=q?await this.processResponseBody(q):{body:se,size:0,json:false,truncated:false,unread:true};const w=Math.max(0,X()-e.start);const T=y-e.start;const v={};c.headers.forEach((d,S)=>{v[S.toLowerCase()]=d});this.emit({type:"response",timestamp:new Date,duration:w,timings:w>T?{ttfb:T,download:w-T}:void 0,request:L(),response:{status:c.status,statusText:c.statusText,headers:v,body:R,size:p,json:E,truncated:a||void 0,unread:H||void 0}})})}adoptEarlyXhr(e){const t=K(e.url);if(this.shouldIgnoreUrl(t))return;const s=V("xhr");const l=e.method.toUpperCase();const{url:u,params:o}=this.parseUrl(t);let h=e.body;if(typeof h==="string"){try{h=JSON.parse(h)}catch{}}const m=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:s,url:u,method:l,headers:e.headers,data:h,params:o||void 0,client:m}});const f=e.xhr;const i=()=>{const n=(f._buoyEarlyEnd??X())-e.start;this.handleXHRResponse(f,s,u,l,e.headers,h,o,X()-n,false,m)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let B=null;const re=()=>{if(!B){B=new Ue}return B};export const networkListener=re;export const startNetworkListener=()=>re().startListening();export const stopNetworkListener=()=>B?.stopListening();export const addNetworkListener=g=>re().addListener(g);export const removeAllNetworkListeners=()=>B?.removeAllListeners();export const isNetworkListening=()=>B?.isActive??false;export const getNetworkListenerCount=()=>B?.listenerCount??0;export const isNetworkInterceptionLive=()=>B?.isInterceptionLive()??false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{networkEventStore as n}from"./networkEventStore";import{
|
|
1
|
+
"use strict";import{networkEventStore as n}from"./networkEventStore";import{socketStore as i}from"../sockets/socketStore";import{overrideRulesStore as s}from"../overrides/overrideRulesStore";import{registerLocalNetworkFloatingTool as u}from"../conditions/NetworkFloatingTool";export function startNetworkCapture(){const t=typeof navigator!=="undefined"&&navigator.product==="ReactNative";if(!t&&(typeof window==="undefined"||typeof document==="undefined"))return()=>{};void s.ensureLoaded();i.install();const o=t?()=>{}:u();const r=n.subscribeToEvents(()=>{});let e=false;return()=>{if(e)return;e=true;o();r()}}
|
package/lib/module/preset.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{NetworkConditionsIcon as t}from"./network/conditions/NetworkConditionsIcon";import{createToolFactory as r,defineToolPreset as i}from"@buoy-gg/shared-ui";import{NetworkModal as n}from"./network/components/NetworkModal";import{overrideRulesStore as
|
|
1
|
+
"use strict";import{NetworkConditionsIcon as t}from"./network/conditions/NetworkConditionsIcon";import{createToolFactory as r,defineToolPreset as i}from"@buoy-gg/shared-ui";import{NetworkModal as n}from"./network/components/NetworkModal";import{overrideRulesStore as s}from"./network/overrides/overrideRulesStore";import{networkEventStore as a}from"./network/utils/networkEventStore";import{socketStore as d}from"./network/sockets/socketStore";import{jsx as m}from"react/jsx-runtime";const e=typeof navigator!=="undefined"&&navigator.product==="ReactNative";if(e)void s.ensureLoaded();if(e&&typeof __DEV__!=="undefined"&&__DEV__){a.startBootCapture();d.install()}export const networkToolPreset=i({id:"network",name:"NET",description:"Network request logger",slot:"both",icon:({size:o})=>m(t,{size:o}),component:n,props:{enableSharedModalDimensions:false}});export const createNetworkTool=r(networkToolPreset,o=>({enableSharedModalDimensions:o.enableSharedModalDimensions??false}));
|
|
@@ -34,6 +34,17 @@ type OverrideRulesRemote, } from "./network/overrides/overrideRulesStore";
|
|
|
34
34
|
export { draftFromEvent } from "./network/overrides/presets";
|
|
35
35
|
export { MAX_RULES as MAX_OVERRIDE_RULES, FREE_TIER_RULE_LIMIT as FREE_TIER_OVERRIDE_LIMIT, STATUS_MIN as OVERRIDE_STATUS_MIN, STATUS_MAX as OVERRIDE_STATUS_MAX, type OverrideRule, type OverrideRuleKind, type OverrideFailKind, type NetworkOverrideMark, } from "./network/overrides/types";
|
|
36
36
|
export { useIgnoredPatterns, ignoredPatternsStore, urlMatchesIgnoredPattern, isUrlIgnored, } from "@buoy-gg/shared-ui";
|
|
37
|
+
export { NetworkSocketsScreen } from "./network/components/sockets/NetworkSocketsScreen";
|
|
38
|
+
export { useSocketsState } from "./network/hooks/useSocketsState";
|
|
39
|
+
export { socketsSyncAdapter, querySockets, type SocketQuery } from "./network/sockets/socketsSyncAdapter";
|
|
40
|
+
export type { SocketAction, SocketActionResult, SocketConnection, SocketFrame, SocketProblem, SocketProblemKind, SocketsState, SocketState, } from "./network/sockets/types";
|
|
41
|
+
/**
|
|
42
|
+
* @internal — the desktop dashboard mirrors this (`applySnapshot`) and sends
|
|
43
|
+
* Tricks to the device through `setRemote`.
|
|
44
|
+
*/
|
|
45
|
+
export { socketStore, type SocketsRemote } from "./network/sockets/socketStore";
|
|
46
|
+
/** @internal — the Events tool's socket source (opened, closed, faked). */
|
|
47
|
+
export { onSocketMoment, type SocketMoment } from "./network/sockets/socketMoments";
|
|
37
48
|
export { networkSyncAdapter } from "./network/sync/networkSyncAdapter";
|
|
38
49
|
export { NetworkBodyResolverProvider, type NetworkBodyResolver, type ResolvedNetworkBody, } from "./network/sync/networkBodyResolver";
|
|
39
50
|
/** @internal */
|
|
@@ -46,6 +57,7 @@ export { networkSavedStore, flagsForEventId, FREE_TIER_SAVED_LIMIT, MAX_PINNED,
|
|
|
46
57
|
export { generateCurl } from "./network/utils/generateCurl";
|
|
47
58
|
/** @internal */
|
|
48
59
|
export { networkListener, addNetworkListener, removeAllNetworkListeners, } from "./network/utils/networkListener";
|
|
49
|
-
export { NETWORK_CONDITIONS, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions } from "./network/conditions/store";
|
|
50
|
-
export type { NetworkConditionProfile, NetworkConditionStamp } from "./network/conditions/store";
|
|
60
|
+
export { NETWORK_CONDITIONS, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions, getNetworkConditions, setNetworkConditions, getNetworkConnection, getConditionsRevision, networkConditionsActive } from "./network/conditions/store";
|
|
61
|
+
export type { NetworkConditionProfile, NetworkConditionStamp, NetworkConditionsState, NetworkConditionsChange, NetworkConnection } from "./network/conditions/store";
|
|
62
|
+
export { chooseConditionsSnapshot } from "./network/conditions/remoteState";
|
|
51
63
|
//# sourceMappingURL=index.d.ts.map
|