@buoy-gg/network 7.0.77 → 7.0.79
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 +68 -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/NetworkCopySettingsView.js +1 -1
- package/lib/commonjs/network/components/NetworkEventDetailView.js +2 -2
- package/lib/commonjs/network/components/NetworkEventDetailView.web.js +1 -1
- package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -2
- package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +1 -1
- package/lib/commonjs/network/components/NetworkListScreen.js +1 -1
- package/lib/commonjs/network/components/NetworkModal.js +1 -1
- package/lib/commonjs/network/components/NetworkSavedScreen.js +1 -1
- 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/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/sync/networkSyncAdapter.js +1 -1
- package/lib/commonjs/network/utils/generateNetworkCopyText.js +1 -0
- package/lib/commonjs/network/utils/networkListener.js +4 -4
- 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/NetworkCopySettingsView.js +3 -3
- 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/NetworkListScreen.js +1 -1
- package/lib/module/network/components/NetworkModal.js +1 -1
- package/lib/module/network/components/NetworkSavedScreen.js +1 -1
- 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/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/sync/networkSyncAdapter.js +1 -1
- package/lib/module/network/utils/generateNetworkCopyText.js +23 -22
- package/lib/module/network/utils/networkListener.js +4 -4
- package/lib/typescript/expo-network.d.ts +2 -0
- package/lib/typescript/index.d.ts +3 -2
- package/lib/typescript/index.web.d.ts +3 -2
- package/lib/typescript/netinfo.d.ts +3 -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/overrides/engine.d.ts +14 -0
- package/lib/typescript/network/overrides/matchRule.d.ts +3 -0
- package/lib/typescript/network/overrides/overrideRulesStore.d.ts +3 -0
- package/lib/typescript/network/overrides/types.d.ts +19 -0
- package/lib/typescript/network/sync/networkSyncAdapter.d.ts +27 -12
- package/lib/typescript/network/utils/networkListener.d.ts +4 -0
- package/lib/web/index.mjs +58 -57
- package/package.json +26 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useCallback as $}from"react";import{FlatList as _,StyleSheet as A,Text as m,TouchableOpacity as I,View as c}from"react-native";import{FlaskConical as G,Pin as J,Power as K,macOSColors as e,ToolEmptyState as Q,resolveListEmptyState as X,EVENT_LIST_PRESET as Y,monoFont as Z}from"@buoy-gg/shared-ui";import{NetworkEventItemCompact as w}from"./NetworkEventItemCompact";import{NetworkUpgradeBanner as ee}from"./NetworkUpgradeBanner";import{useNetworkEventList as ne}from"../hooks/useNetworkEventList";import{useNetworkSaved as te}from"../hooks/useNetworkSaved";import{useOverrideRules as re}from"../hooks/useOverrideRules";import{overriddenEvents as oe}from"../overrides/overriddenRows";import{splitPinned as ie}from"../utils/withPinnedFirst";import{jsx as n,jsxs as l}from"react/jsx-runtime";const de=o=>o.id;function se({events:o,onEventPress:a,onLongPress:g,savedLiveIds:p,onClearPinned:i}){if(o.length===0)return null;return l(c,{style:t.pinnedSection,children:[l(c,{style:t.pinnedHeader,children:[n(J,{size:11,active:true,color:e.semantic.info}),l(m,{style:t.pinnedTitle,children:["PINNED \xB7 ",o.length]}),n(I,{onPress:i,"sentry-label":"ignore unpin all",style:t.pinnedClear,children:n(m,{style:t.pinnedClearText,children:"Unpin all"})})]}),o.map(d=>n(w,{event:d,onPress:a,onLongPress:g,pinned:true,saved:p.has(d.id)},d.id))]})}function le({events:o,onEventPress:a,onLongPress:g,savedLiveIds:p,paused:i,onTogglePaused:d}){if(o.length===0)return null;return l(c,{style:[t.overriddenSection,i&&t.overriddenSectionOff],children:[l(c,{style:t.overriddenHeader,children:[n(G,{size:11,color:i?e.text.muted:e.semantic.warning}),n(m,{testID:"buoy-network-overridden-strip",style:[t.overriddenTitle,i&&t.overriddenTitleOff],children:i?`PAUSED \xB7 ${o.length}`:`OVERRIDDEN \xB7 ${o.length}`}),n(I,{onPress:d,"sentry-label":"ignore pause overrides",style:t.overriddenManage,children:n(m,{style:[t.overriddenManageText,i&&t.overriddenTitleOff],children:i?"Resume":"Pause"})})]}),o.map(s=>n(w,{event:s,onPress:a,onLongPress:g,overridden:true,saved:p.has(s.id)},s.id))]})}export function NetworkListScreen({visible:o,paused:a,filter:g,ignoredPatterns:p,isPro:i,searchText:d,onEventPress:s,onUpgradePress:L}){const{visibleEvents:z,hasLockedEvents:S,lockedEventCount:f,totalEvents:B}=ne({filter:g,ignoredPatterns:p,paused:a,visible:o,isPro:i});const{pinnedEvents:N,pinnedLiveIds:D,savedLiveIds:u,togglePin:k,clearPinned:R}=te();const{rules:H,enabled:x,setEnabled:O,isRuleSpent:q}=re();const h=$(r=>{k(r)},[k]);if(!o)return null;const{pinned:E,rest:v}=ie(z,N,D);const F=H.filter(r=>r.enabled&&!q(r));const b=oe([...E,...v],F);const y=new Set(b.map(r=>r.id));const P=E.filter(r=>!y.has(r.id));const T=y.size?v.filter(r=>!y.has(r.id)):v;const C=!a;const V=({item:r})=>n(w,{event:r,onPress:s,onLongPress:h,saved:u.has(r.id)});const W=()=>{if(P.length>0||b.length>0)return null;return n(Q,{testID:"buoy-network-empty",...X({subject:"requests",search:d,total:B,capturing:C,waiting:{otto:"fishing",title:"No network events",message:"Network requests will appear here"},paused:{title:"No network events",message:"Enable interception to start capturing"}})})};const j=()=>{if(!S)return null;const r=d.length>0;const M=r?`${f} matching ${f===1?"request":"requests"} in locked history`:`${f} requests locked`;const U=r?"Upgrade to Pro to search your full request history":"Upgrade to Pro to unlock full request history";return n(ee,{title:M,subtitle:U,onPress:L})};return l(c,{style:t.root,children:[!C?l(c,{style:t.disabledBanner,children:[n(K,{size:14,color:e.semantic.warning}),n(m,{style:t.disabledText,children:"Network interception is disabled"})]}):null,n(le,{events:b,onEventPress:s,onLongPress:h,savedLiveIds:u,paused:!x,onTogglePaused:()=>O(!x)}),n(se,{events:P,onEventPress:s,onLongPress:h,savedLiveIds:u,onClearPinned:R}),T.length>0||S?n(_,{testID:"buoy-network-list",data:T,renderItem:V,keyExtractor:de,contentContainerStyle:t.listContent,showsVerticalScrollIndicator:true,onEndReachedThreshold:.8,scrollEnabled:true,...Y,extraData:u,"sentry-label":"ignore network events list",ListFooterComponent:j}):W()]})}const t=A.create({root:{flex:1,minHeight:0},overriddenSection:{borderBottomWidth:1,borderBottomColor:e.semantic.warning+"44",backgroundColor:e.semantic.warningBackground},overriddenSectionOff:{borderBottomColor:e.border.default,backgroundColor:e.background.card},overriddenTitleOff:{color:e.text.muted},overriddenHeader:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingTop:8,paddingBottom:4},overriddenTitle:{flex:1,fontSize:10,fontWeight:"700",letterSpacing:.8,color:e.semantic.warning},overriddenManage:{paddingHorizontal:6,paddingVertical:2},overriddenManageText:{fontSize:10,fontWeight:"600",color:e.semantic.warning},pinnedSection:{borderBottomWidth:1,borderBottomColor:e.border.default,paddingBottom:4},pinnedHeader:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:20,paddingTop:10,paddingBottom:6},pinnedTitle:{flex:1,color:e.semantic.info,fontSize:10,fontWeight:"700",letterSpacing:.6,fontFamily:Z},pinnedClear:{paddingHorizontal:6,paddingVertical:2},pinnedClearText:{color:e.text.muted,fontSize:10},disabledBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:e.semantic.warningBackground,borderRadius:8,borderWidth:1,borderColor:e.semantic.warning+"20"},disabledText:{color:e.semantic.warning,fontSize:11,flex:1},listContent:{paddingTop:8}});
|
|
1
|
+
"use strict";import{useCallback as $}from"react";import{FlatList as _,StyleSheet as A,Text as m,TouchableOpacity as I,View as c}from"react-native";import{FlaskConical as G,Pin as J,Power as K,macOSColors as e,ToolEmptyState as Q,resolveListEmptyState as X,EVENT_LIST_PRESET as Y,monoFont as Z}from"@buoy-gg/shared-ui";import{NetworkEventItemCompact as w}from"./NetworkEventItemCompact";import{NetworkUpgradeBanner as ee}from"./NetworkUpgradeBanner";import{useNetworkEventList as ne}from"../hooks/useNetworkEventList";import{useNetworkSaved as te}from"../hooks/useNetworkSaved";import{useOverrideRules as re}from"../hooks/useOverrideRules";import{overriddenEvents as oe}from"../overrides/overriddenRows";import{splitPinned as ie}from"../utils/withPinnedFirst";import{jsx as n,jsxs as l}from"react/jsx-runtime";const de=o=>o.id;function se({events:o,onEventPress:a,onLongPress:g,savedLiveIds:p,onClearPinned:i}){if(o.length===0)return null;return l(c,{style:t.pinnedSection,children:[l(c,{style:t.pinnedHeader,children:[n(J,{size:11,active:true,color:e.semantic.info}),l(m,{style:t.pinnedTitle,children:["PINNED \xB7 ",o.length]}),n(I,{onPress:i,"sentry-label":"ignore unpin all",style:t.pinnedClear,children:n(m,{style:t.pinnedClearText,children:"Unpin all"})})]}),o.map(d=>n(w,{event:d,onPress:a,onLongPress:g,pinned:true,saved:p.has(d.id)},d.id))]})}function le({events:o,onEventPress:a,onLongPress:g,savedLiveIds:p,paused:i,onTogglePaused:d}){if(o.length===0)return null;return l(c,{style:[t.overriddenSection,i&&t.overriddenSectionOff],children:[l(c,{style:t.overriddenHeader,children:[n(G,{size:11,color:i?e.text.muted:e.semantic.warning}),n(m,{testID:"buoy-network-overridden-strip",style:[t.overriddenTitle,i&&t.overriddenTitleOff],children:i?`PAUSED \xB7 ${o.length}`:`OVERRIDDEN \xB7 ${o.length}`}),n(I,{onPress:d,"sentry-label":"ignore pause overrides",style:t.overriddenManage,children:n(m,{style:[t.overriddenManageText,i&&t.overriddenTitleOff],children:i?"Resume":"Pause"})})]}),o.map(s=>n(w,{event:s,onPress:a,onLongPress:g,overridden:true,saved:p.has(s.id)},s.id))]})}export function NetworkListScreen({visible:o,paused:a,filter:g,ignoredPatterns:p,isPro:i,searchText:d,onEventPress:s,onUpgradePress:L}){const{visibleEvents:z,hasLockedEvents:S,lockedEventCount:f,totalEvents:B}=ne({filter:g,ignoredPatterns:p,paused:a,visible:o,isPro:i});const{pinnedEvents:N,pinnedLiveIds:D,savedLiveIds:u,togglePin:k,clearPinned:R}=te();const{rules:H,enabled:x,setEnabled:O,isRuleSpent:q}=re();const h=$(r=>{k(r)},[k]);if(!o)return null;const{pinned:E,rest:v}=ie(z,N,D);const F=H.filter(r=>r.enabled&&!q(r));const b=oe([...E,...v],F);const y=new Set(b.map(r=>r.id));const P=E.filter(r=>!y.has(r.id));const T=y.size?v.filter(r=>!y.has(r.id)):v;const C=!a;const V=({item:r})=>n(w,{event:r,onPress:s,onLongPress:h,saved:u.has(r.id)});const W=()=>{if(P.length>0||b.length>0)return null;return n(Q,{testID:"buoy-network-empty",...X({subject:"requests",search:d,total:B,capturing:C,waiting:{otto:"fishing",title:"No network events",message:"Network requests will appear here"},paused:{title:"No network events",message:"Enable interception to start capturing"}})})};const j=()=>{if(!S)return null;const r=d.length>0;const M=r?`${f} matching ${f===1?"request":"requests"} in locked history`:`${f} requests locked`;const U=r?"Upgrade to Pro to search your full request history":"Upgrade to Pro to unlock full request history";return n(ee,{title:M,subtitle:U,onPress:L})};return l(c,{style:t.root,children:[!C?l(c,{style:t.disabledBanner,children:[n(K,{size:14,color:e.semantic.warning}),n(m,{style:t.disabledText,children:"Network interception is disabled"})]}):null,n(le,{events:b,onEventPress:s,onLongPress:h,savedLiveIds:u,paused:!x,onTogglePaused:()=>O(!x)}),n(se,{events:P,onEventPress:s,onLongPress:h,savedLiveIds:u,onClearPinned:R}),T.length>0||S?n(_,{keyboardShouldPersistTaps:"handled",testID:"buoy-network-list",data:T,renderItem:V,keyExtractor:de,contentContainerStyle:t.listContent,showsVerticalScrollIndicator:true,onEndReachedThreshold:.8,scrollEnabled:true,...Y,extraData:u,"sentry-label":"ignore network events list",ListFooterComponent:j}):W()]})}const t=A.create({root:{flex:1,minHeight:0},overriddenSection:{borderBottomWidth:1,borderBottomColor:e.semantic.warning+"44",backgroundColor:e.semantic.warningBackground},overriddenSectionOff:{borderBottomColor:e.border.default,backgroundColor:e.background.card},overriddenTitleOff:{color:e.text.muted},overriddenHeader:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingTop:8,paddingBottom:4},overriddenTitle:{flex:1,fontSize:10,fontWeight:"700",letterSpacing:.8,color:e.semantic.warning},overriddenManage:{paddingHorizontal:6,paddingVertical:2},overriddenManageText:{fontSize:10,fontWeight:"600",color:e.semantic.warning},pinnedSection:{borderBottomWidth:1,borderBottomColor:e.border.default,paddingBottom:4},pinnedHeader:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:20,paddingTop:10,paddingBottom:6},pinnedTitle:{flex:1,color:e.semantic.info,fontSize:10,fontWeight:"700",letterSpacing:.6,fontFamily:Z},pinnedClear:{paddingHorizontal:6,paddingVertical:2},pinnedClearText:{color:e.text.muted,fontSize:10},disabledBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:e.semantic.warningBackground,borderRadius:8,borderWidth:1,borderColor:e.semantic.warning+"20"},disabledText:{color:e.semantic.warning,fontSize:11,flex:1},listContent:{paddingTop:8}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{createRemoteConditionsSource as _e,openNetworkFloatingTool as Ve}from"../conditions/NetworkFloatingTool";import{useState as n,useRef as x,useEffect as P,useCallback as G}from"react";import{View as E,StyleSheet as qe,TouchableOpacity as He}from"react-native";import{Search as Le,Wifi as Ue,Filter as ze,Bookmark as je,JsModal as Ke,ModalHeader as o,devToolsStorageKeys as D,macOSColors as We,night as u,persistentStorage as de,NightSegmented as Je,useFeatureGate as $e,UpgradeModal as Ge,PowerToggleButton as Xe,useIgnoredPatterns as Ye,windowDragProps as Qe}from"@buoy-gg/shared-ui";import{NetworkFilterViewV3 as Ze}from"./NetworkFilterViewV3";import{TickProvider as ue}from"../hooks/useTickEveryMinute";import{NetworkEventDetailView as et}from"./NetworkEventDetailView";import{NetworkCopySettingsView as tt,DEFAULT_COPY_SETTINGS as rt}from"./NetworkCopySettingsView";import{NetworkHeaderBadges as ot,NetworkClearButton as nt,NetworkDetailPinActions as st,NetworkHeaderCopyButton as at}from"./NetworkHeaderLive";import{NetworkListScreen as it}from"./NetworkListScreen";import{NetworkSavedScreen as lt}from"./NetworkSavedScreen";import{NetworkOverridesScreen as ct}from"./NetworkOverridesScreen";import{NetworkOverridesButton as dt}from"./NetworkOverridesButton";import{NetworkOverrideHeaderButton as ut}from"./NetworkOverrideHeaderButton";import{NetworkHeaderMenu as pt,NetworkHeaderMenuButton as ft,NetworkHeaderMenuItem as X}from"./NetworkHeaderMenu";import{NetworkDetailStepper as gt}from"./NetworkDetailStepper";import{useNetworkEventList as pe}from"../hooks/useNetworkEventList";import{useLiveNetworkEvent as ht}from"../hooks/useLiveNetworkEvent";import{useHasNetworkSelection as mt,useNetworkBodyEventId as St,useSelectedNetworkEventId as vt}from"../hooks/useNetworkSelection";import{networkSelectionStore as _}from"../utils/networkSelectionStore";import{FREE_TIER_SAVED_LIMIT as wt,MAX_SAVED as yt}from"../utils/networkSavedStore";import{FREE_TIER_RULE_LIMIT as kt,MAX_RULES as Pt}from"../overrides/types";import{jsx as e,jsxs as l,Fragment as bt}from"react/jsx-runtime";function Ct({visible:r,paused:p,ignoredPatternValues:f,onTogglePattern:g,isPro:v,filter:c,ignoredPatterns:h,fromSaved:m,savedSearch:w,applySafeAreaInset:i}){const y=vt();const V=St();const C=y!=null&&y===V;const s=ht(y,{paused:p||!r});P(()=>{if(r&&s&&C){_.reportRendered(s.id)}},[r,s,C]);if(!r)return null;return l(E,{style:b.detailRoot,children:[s?e(et,{event:s,ignoredPatterns:f,onTogglePattern:g,showBodies:C}):e(E,{style:b.detailBodyFallback}),e(gt,{paused:p,filter:c,ignoredPatterns:h,isPro:v,fromSaved:m,savedSearch:w,applySafeAreaInset:i})]})}function Rt({visible:r,paused:p,isPro:f,filter:g,onFilterChange:v,ignoredPatterns:c,onRemovePattern:h,onAddPattern:m,onTogglePatternMode:w,isTeamPattern:i}){const{events:y}=pe({filter:g,ignoredPatterns:c,paused:p,visible:r,isPro:f});if(!r)return null;return e(Ze,{events:y,filter:g,onFilterChange:v,ignoredPatterns:c,onRemovePattern:h,onAddPattern:m,onTogglePatternMode:w,isTeamPattern:i})}function It({visible:r,paused:p,isPro:f,filter:g,ignoredPatterns:v,settings:c,onSettingsChange:h}){const{events:m}=pe({filter:g,ignoredPatterns:v,paused:p,visible:r,isPro:f});if(!r)return null;return e(tt,{settings:c,onSettingsChange:h,events:m})}function fe({visible:r,onClose:p,onBack:f,onMinimize:g,enableSharedModalDimensions:v=false,inline:c=false,paused:h,onPausedChange:m,remoteConditions:w}){const{isPro:i}=$e();const[y,V]=n(false);const C=h!=null&&m!=null;const s=C?h:y;const ge=t=>{const a=typeof t==="function"?t(s):t;if(C)m(a);else V(a)};const[d,q]=n({});const S=mt();const[k,Y]=n(false);const[A,Q]=n(false);const[B,H]=n(false);const[Z,R]=n(false);const[he,me]=n(0);const[M]=n(_e);P(()=>{M.update(w)},[M,w]);P(()=>()=>M.update(void 0),[M]);const I=true;const[Se,L]=n(null);const[U,ee]=n("filters");const[te,ve]=n("");const[z,j]=n(false);const Tt=x(false);const[re,we]=n("");const ye=x(null);const{patterns:N,values:ke,add:Pe,remove:be,toggle:Ce,toggleMode:Re,isTeamOnly:Ie}=Ye();const[F,oe]=n(rt);const K=x(false);const[W,J]=n(false);const[T,Ne]=n("export");const O=t=>{Ne(t);J(true)};P(()=>{if(W&&i){J(false)}},[W,i]);P(()=>{if(!r||K.current)return;const t=async()=>{try{const a=await de.getItem(D.network.copyOptions());if(a){const De=JSON.parse(a);oe(De)}}catch(a){}finally{K.current=true}};t()},[r]);P(()=>{if(!K.current)return;const t=async()=>{try{await de.setItem(D.network.copyOptions(),JSON.stringify(F))}catch(a){}};t()},[F]);const Te=()=>{_.clear()};const ne=G(t=>{_.select(t.id)},[]);const Ee=G((t,a)=>{L(a?{...t,id:a}:t);H(true);_.clear()},[]);const Me=G(()=>L(null),[]);const se=x(null);const ae=t=>{ve(t);q(a=>({...a,searchText:t}))};const Fe=t=>{q(a=>({...a,status:a.status===t?void 0:t}))};const[ie,Oe]=n("bottomSheet");const Ae=t=>{Oe(t)};P(()=>{if(z){requestAnimationFrame(()=>{ye.current?.focus()})}},[z]);const le=()=>{if(k){return l(o,{children:[e(o.Navigation,{onBack:()=>Y(false)}),e(o.Content,{title:"",noMargin:true,children:e(Je,{size:"sm",tabs:[{key:"filters",label:"Filters"},{key:"copy",label:"Copy"}],activeKey:U,onChange:t=>ee(t)})})]})}if(S){return l(o,{children:[e(o.Navigation,{onBack:Te}),e(o.Content,{title:"Request Details",centered:true}),l(o.Actions,{children:[I?e(ut,{onOpen:Ee}):null,e(st,{isPro:i,onUpgradePress:()=>O("saved")})]})]})}if(B&&I){return l(o,{children:[e(o.Navigation,{onBack:()=>{if(se.current?.())return;H(false);L(null)}}),e(o.Content,{title:"Response Overrides",centered:true})]})}if(A){return l(o,{children:[e(o.Navigation,{onBack:()=>Q(false)}),e(o.Content,{title:"Saved Requests",centered:true})]})}return l(o,{children:[f&&e(o.Navigation,{onBack:f}),e(o.Content,{title:"",children:z?e(o.Search,{value:te,onChangeText:ae,onCancel:()=>{ae("");j(false)},onDismiss:()=>j(false),dismissOnBlur:true,clearOnlyWhenText:true,placeholder:"Search URL, method, operation, error...",accessibilityLabel:"Search network requests",iconSize:14,testID:"buoy-network-search-input",clearTestID:"buoy-network-search-clear",inputProps:{"sentry-label":"ignore network search header"}}):e(ot,{activeStatus:d.status,onToggleStatus:Fe,ignoredPatterns:N,paused:s})}),l(o.Actions,{children:[e(He,{"sentry-label":"ignore open search",testID:"buoy-network-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",onPress:()=>j(true),style:b.headerActionButton,children:e(Le,{size:14,color:u.color.textSecondary})}),I?e(dt,{onPress:()=>H(true)}):null,e(Xe,{isEnabled:!s,onToggle:()=>ge(t=>!t),accessibilityLabel:s?"Resume network capture":"Pause network capture",testID:"buoy-network-power"}),e(nt,{paused:s}),e(ft,{onPress:()=>R(t=>!t),isOpen:Z,hasIndicator:$})]})]})};const $=!!(d.status||d.method||d.contentType);const Be=v?D.modal.root():D.network.modal();if(!r)return null;const xe=S||!k;const ce=l(bt,{children:[l(E,{style:b.container,children:[e(Ct,{visible:S,paused:s,ignoredPatternValues:ke,onTogglePattern:Ce,isPro:i,filter:d,ignoredPatterns:N,fromSaved:A,savedSearch:re,applySafeAreaInset:!c&&ie==="bottomSheet"}),e(Rt,{visible:k&&U==="filters"&&!S,paused:s,isPro:i,filter:d,onFilterChange:q,ignoredPatterns:N,onRemovePattern:be,onAddPattern:Pe,onTogglePatternMode:Re,isTeamPattern:Ie}),e(It,{visible:k&&U==="copy"&&!S,paused:s,isPro:i,filter:d,ignoredPatterns:N,settings:F,onSettingsChange:oe}),e(ct,{visible:I&&B&&!S&&!k,isPro:i,onUpgradePress:()=>O("overrides"),pendingDraft:Se,onPendingConsumed:Me,backHandlerRef:se,applySafeAreaInset:!c&&ie==="bottomSheet"}),e(lt,{visible:A&&!S&&!k&&!(B&&I),isPro:i,copySettings:F,search:re,onSearchChange:we,onEventPress:ne,onUpgradePress:()=>O("saved")}),e(it,{visible:!S&&!k&&!A&&!(B&&I),paused:s,filter:d,ignoredPatterns:N,isPro:i,searchText:te,onEventPress:ne,onUpgradePress:()=>O("export")})]}),Z?l(pt,{onClose:()=>R(false),children:[e(X,{icon:e(Ue,{size:14,color:u.color.textSecondary}),label:"Network throttling",testID:"buoy-network-menu-throttling",onPress:()=>{R(false);Ve(w?M:void 0);if(!c)me(t=>t+1)}}),e(X,{icon:e(ze,{size:14,color:$?u.color.accent:u.color.textSecondary}),label:"Filters",detail:$?"Active":void 0,onPress:()=>{R(false);ee("filters");Y(true)}}),e(X,{icon:e(je,{size:14,color:u.color.textSecondary}),label:"Saved requests",onPress:()=>{R(false);Q(true)}}),e(E,{style:b.menuCopyRow,children:e(at,{isPro:i,filter:d,ignoredPatterns:N,copySettings:F,paused:s,onUpgradePress:()=>{R(false);O("export")},label:"Copy requests"})})]}):null,e(Ge,{visible:W,onClose:()=>J(false),featureName:T==="saved"?"Saved Requests":T==="overrides"?"Response Overrides":"Network Export",description:T==="saved"?"Keep the requests that matter. Saved requests survive Clear, app restarts, and the 500-request history cap.":T==="overrides"?"Force any endpoint to fail, stall or return something else \u2014 no backend changes, no code changes. Free keeps one active rule.":"Export network requests to share with your team, debug APIs, or feed into AI tools.",benefits:T==="overrides"?[`Run ${Pt} rules at once (free keeps ${kt})`,"Force a 500, a 401 or an empty list in one tap","Simulate offline, timeouts and slow connections","Rules survive an app reload, so you can test the boot path"]:T==="saved"?[`Save up to ${yt} requests (free keeps ${wt})`,"Failed requests stay put through a Clear","Snapshots survive an app restart","Export saved requests to teammates or AI assistants"]:["Export to JSON, Markdown, or plain text","Customizable copy presets (URLs only, LLM-ready, full data)","Share request details with teammates","Feed network data directly to AI assistants"]})]});if(c){return l(E,{style:b.inlineRoot,children:[e(E,{style:b.inlineHeader,...Qe,children:le()}),ce]})}return e(Ke,{visible:r,onClose:p,onMinimize:g,minimizeRequest:he,persistenceKey:Be,variant:"night",header:{showToggleButton:true,customContent:le()},onModeChange:Ae,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:xe,styles:{},children:ce})}const b=qe.create({container:{flex:1,backgroundColor:"transparent"},detailRoot:{flex:1,minHeight:0},detailBodyFallback:{flex:1},inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:We.border.default,backgroundColor:"transparent"},menuCopyRow:{paddingHorizontal:6},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:u.color.buttonSurface,borderWidth:1,borderColor:u.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:u.color.accentSoft,borderColor:u.color.accentBorderStrong}});export function NetworkModal(r){return e(ue,{children:e(fe,{...r})})}export function NetworkToolView(r={}){return e(ue,{children:e(fe,{...r,inline:true,visible:true,onClose:Nt})})}const Nt=()=>{};
|
|
1
|
+
"use strict";import{createRemoteConditionsSource as qe,openNetworkFloatingTool as ue}from"../conditions/NetworkFloatingTool";import{useState as n,useRef as B,useEffect as b,useCallback as X}from"react";import{View as M,StyleSheet as He,TouchableOpacity as Le}from"react-native";import{Search as Ue,Wifi as pe,Filter as ze,Bookmark as je,JsModal as Ke,ModalHeader as o,devToolsStorageKeys as D,macOSColors as We,night as d,persistentStorage as fe,NightSegmented as Je,useFeatureGate as $e,UpgradeModal as Ge,PowerToggleButton as Xe,useIgnoredPatterns as Ye,windowDragProps as Qe}from"@buoy-gg/shared-ui";import{NetworkFilterViewV3 as Ze}from"./NetworkFilterViewV3";import{TickProvider as ge}from"../hooks/useTickEveryMinute";import{NetworkEventDetailView as et}from"./NetworkEventDetailView";import{NetworkCopySettingsView as tt,DEFAULT_COPY_SETTINGS as rt}from"./NetworkCopySettingsView";import{NetworkHeaderBadges as ot,NetworkClearButton as nt,NetworkDetailPinActions as st,NetworkHeaderCopyButton as at}from"./NetworkHeaderLive";import{NetworkListScreen as it}from"./NetworkListScreen";import{NetworkSavedScreen as lt}from"./NetworkSavedScreen";import{NetworkOverridesScreen as ct}from"./NetworkOverridesScreen";import{NetworkOverridesButton as dt}from"./NetworkOverridesButton";import{NetworkOverrideHeaderButton as ut}from"./NetworkOverrideHeaderButton";import{NetworkHeaderMenu as pt,NetworkHeaderMenuButton as ft,NetworkHeaderMenuItem as _}from"./NetworkHeaderMenu";import{NetworkDetailStepper as gt}from"./NetworkDetailStepper";import{useNetworkEventList as he}from"../hooks/useNetworkEventList";import{useLiveNetworkEvent as ht}from"../hooks/useLiveNetworkEvent";import{useHasNetworkSelection as mt,useNetworkBodyEventId as St,useSelectedNetworkEventId as vt}from"../hooks/useNetworkSelection";import{networkSelectionStore as V}from"../utils/networkSelectionStore";import{FREE_TIER_SAVED_LIMIT as wt,MAX_SAVED as yt}from"../utils/networkSavedStore";import{FREE_TIER_RULE_LIMIT as kt,MAX_RULES as Pt}from"../overrides/types";import{jsx as e,jsxs as c,Fragment as bt}from"react/jsx-runtime";function Ct({visible:r,paused:p,ignoredPatternValues:f,onTogglePattern:g,isPro:w,filter:l,ignoredPatterns:h,fromSaved:m,savedSearch:S,applySafeAreaInset:i}){const y=vt();const q=St();const R=y!=null&&y===q;const s=ht(y,{paused:p||!r});b(()=>{if(r&&s&&R){V.reportRendered(s.id)}},[r,s,R]);if(!r)return null;return c(M,{style:C.detailRoot,children:[s?e(et,{event:s,ignoredPatterns:f,onTogglePattern:g,showBodies:R}):e(M,{style:C.detailBodyFallback}),e(gt,{paused:p,filter:l,ignoredPatterns:h,isPro:w,fromSaved:m,savedSearch:S,applySafeAreaInset:i})]})}function Rt({visible:r,paused:p,isPro:f,filter:g,onFilterChange:w,ignoredPatterns:l,onRemovePattern:h,onAddPattern:m,onTogglePatternMode:S,isTeamPattern:i}){const{events:y}=he({filter:g,ignoredPatterns:l,paused:p,visible:r,isPro:f});if(!r)return null;return e(Ze,{events:y,filter:g,onFilterChange:w,ignoredPatterns:l,onRemovePattern:h,onAddPattern:m,onTogglePatternMode:S,isTeamPattern:i})}function It({visible:r,paused:p,isPro:f,filter:g,ignoredPatterns:w,settings:l,onSettingsChange:h}){const{events:m}=he({filter:g,ignoredPatterns:w,paused:p,visible:r,isPro:f});if(!r)return null;return e(tt,{settings:l,onSettingsChange:h,events:m})}function me({visible:r,onClose:p,onBack:f,onMinimize:g,enableSharedModalDimensions:w=false,inline:l=false,paused:h,onPausedChange:m,remoteConditions:S}){const{isPro:i}=$e();const[y,q]=n(false);const R=h!=null&&m!=null;const s=R?h:y;const Se=t=>{const a=typeof t==="function"?t(s):t;if(R)m(a);else q(a)};const[u,H]=n({});const v=mt();const[k,Y]=n(false);const[A,Q]=n(false);const[x,L]=n(false);const[Z,P]=n(false);const[ve,ee]=n(0);const[I]=n(qe);b(()=>{I.update(S)},[I,S]);b(()=>()=>I.update(void 0),[I]);const N=true;const[we,U]=n(null);const[z,te]=n("filters");const[re,ye]=n("");const[j,K]=n(false);const Tt=B(false);const[oe,ke]=n("");const Pe=B(null);const{patterns:T,values:be,add:Ce,remove:Re,toggle:Ie,toggleMode:Ne,isTeamOnly:Te}=Ye();const[F,ne]=n(rt);const W=B(false);const[J,$]=n(false);const[E,Ee]=n("export");const O=t=>{Ee(t);$(true)};b(()=>{if(J&&i){$(false)}},[J,i]);b(()=>{if(!r||W.current)return;const t=async()=>{try{const a=await fe.getItem(D.network.copyOptions());if(a){const Ve=JSON.parse(a);ne(Ve)}}catch(a){}finally{W.current=true}};t()},[r]);b(()=>{if(!W.current)return;const t=async()=>{try{await fe.setItem(D.network.copyOptions(),JSON.stringify(F))}catch(a){}};t()},[F]);const Me=()=>{V.clear()};const se=X(t=>{V.select(t.id)},[]);const Fe=X((t,a)=>{U(a?{...t,id:a}:t);L(true);V.clear()},[]);const Oe=X(()=>U(null),[]);const ae=B(null);const ie=t=>{ye(t);H(a=>({...a,searchText:t}))};const Ae=t=>{H(a=>({...a,status:a.status===t?void 0:t}))};const[le,xe]=n("bottomSheet");const Be=t=>{xe(t)};b(()=>{if(j){requestAnimationFrame(()=>{Pe.current?.focus()})}},[j]);const ce=()=>{if(k){return c(o,{children:[e(o.Navigation,{onBack:()=>Y(false)}),e(o.Content,{title:"",noMargin:true,children:e(Je,{size:"sm",tabs:[{key:"filters",label:"Filters"},{key:"copy",label:"Copy"}],activeKey:z,onChange:t=>te(t)})})]})}if(v){return c(o,{children:[e(o.Navigation,{onBack:Me}),e(o.Content,{title:"Request Details",centered:true}),c(o.Actions,{children:[N?e(ut,{onOpen:Fe}):null,e(st,{isPro:i,onUpgradePress:()=>O("saved")})]})]})}if(x&&N){return c(o,{children:[e(o.Navigation,{onBack:()=>{if(ae.current?.())return;L(false);U(null)}}),e(o.Content,{title:"Response Overrides",centered:true})]})}if(A){return c(o,{children:[e(o.Navigation,{onBack:()=>Q(false)}),e(o.Content,{title:"Saved Requests",centered:true})]})}return c(o,{children:[f&&e(o.Navigation,{onBack:f}),e(o.Content,{title:"",children:j?e(o.Search,{value:re,onChangeText:ie,onCancel:()=>{ie("");K(false)},onDismiss:()=>K(false),dismissOnBlur:true,clearOnlyWhenText:true,placeholder:"Search URL, method, operation, error...",accessibilityLabel:"Search network requests",iconSize:14,testID:"buoy-network-search-input",clearTestID:"buoy-network-search-clear",inputProps:{"sentry-label":"ignore network search header"}}):e(ot,{activeStatus:u.status,onToggleStatus:Ae,ignoredPatterns:T,paused:s})}),c(o.Actions,{children:[e(Le,{"sentry-label":"ignore open search",testID:"buoy-network-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",onPress:()=>K(true),style:C.headerActionButton,children:e(Ue,{size:14,color:d.color.textSecondary})}),N?e(dt,{onPress:()=>L(true)}):null,e(Xe,{isEnabled:!s,onToggle:()=>Se(t=>!t),accessibilityLabel:s?"Resume network capture":"Pause network capture",testID:"buoy-network-power"}),e(nt,{paused:s}),e(ft,{onPress:()=>P(t=>!t),isOpen:Z,hasIndicator:G})]})]})};const G=!!(u.status||u.method||u.contentType);const De=w?D.modal.root():D.network.modal();if(!r)return null;const _e=v||!k;const de=c(bt,{children:[c(M,{style:C.container,children:[e(Ct,{visible:v,paused:s,ignoredPatternValues:be,onTogglePattern:Ie,isPro:i,filter:u,ignoredPatterns:T,fromSaved:A,savedSearch:oe,applySafeAreaInset:!l&&le==="bottomSheet"}),e(Rt,{visible:k&&z==="filters"&&!v,paused:s,isPro:i,filter:u,onFilterChange:H,ignoredPatterns:T,onRemovePattern:Re,onAddPattern:Ce,onTogglePatternMode:Ne,isTeamPattern:Te}),e(It,{visible:k&&z==="copy"&&!v,paused:s,isPro:i,filter:u,ignoredPatterns:T,settings:F,onSettingsChange:ne}),e(ct,{visible:N&&x&&!v&&!k,isPro:i,onUpgradePress:()=>O("overrides"),pendingDraft:we,onPendingConsumed:Oe,backHandlerRef:ae,applySafeAreaInset:!l&&le==="bottomSheet"}),e(lt,{visible:A&&!v&&!k&&!(x&&N),isPro:i,copySettings:F,search:oe,onSearchChange:ke,onEventPress:se,onUpgradePress:()=>O("saved")}),e(it,{visible:!v&&!k&&!A&&!(x&&N),paused:s,filter:u,ignoredPatterns:T,isPro:i,searchText:re,onEventPress:se,onUpgradePress:()=>O("export")})]}),Z?c(pt,{onClose:()=>P(false),children:[e(_,{icon:e(pe,{size:14,color:d.color.textSecondary}),label:"Network throttling",testID:"buoy-network-menu-throttling",onPress:()=>{P(false);ue(S?I:void 0);if(!l)ee(t=>t+1)}}),e(_,{icon:e(pe,{size:14,color:d.color.textSecondary}),label:"Speed and link state",testID:"buoy-network-menu-conditions",onPress:()=>{P(false);ue(S?I:void 0,true);if(!l)ee(t=>t+1)}}),e(_,{icon:e(ze,{size:14,color:G?d.color.accent:d.color.textSecondary}),label:"Filters",detail:G?"Active":void 0,onPress:()=>{P(false);te("filters");Y(true)}}),e(_,{icon:e(je,{size:14,color:d.color.textSecondary}),label:"Saved requests",onPress:()=>{P(false);Q(true)}}),e(M,{style:C.menuCopyRow,children:e(at,{isPro:i,filter:u,ignoredPatterns:T,copySettings:F,paused:s,onUpgradePress:()=>{P(false);O("export")},label:"Copy requests"})})]}):null,e(Ge,{visible:J,onClose:()=>$(false),featureName:E==="saved"?"Saved Requests":E==="overrides"?"Response Overrides":"Network Export",description:E==="saved"?"Keep the requests that matter. Saved requests survive Clear, app restarts, and the 500-request history cap.":E==="overrides"?"Force any endpoint to fail, stall or return something else \u2014 no backend changes, no code changes. Free keeps one active rule.":"Export network requests to share with your team, debug APIs, or feed into AI tools.",benefits:E==="overrides"?[`Run ${Pt} rules at once (free keeps ${kt})`,"Force a 500, a 401 or an empty list in one tap","Simulate offline, timeouts and slow connections","Rules survive an app reload, so you can test the boot path"]:E==="saved"?[`Save up to ${yt} requests (free keeps ${wt})`,"Failed requests stay put through a Clear","Snapshots survive an app restart","Export saved requests to teammates or AI assistants"]:["Export to JSON, Markdown, or plain text","Customizable copy presets (URLs only, LLM-ready, full data)","Share request details with teammates","Feed network data directly to AI assistants"]})]});if(l){return c(M,{style:C.inlineRoot,children:[e(M,{style:C.inlineHeader,...Qe,children:ce()}),de]})}return e(Ke,{visible:r,onClose:p,onMinimize:g,minimizeRequest:ve,persistenceKey:De,variant:"night",header:{showToggleButton:true,customContent:ce()},onModeChange:Be,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:_e,styles:{},children:de})}const C=He.create({container:{flex:1,backgroundColor:"transparent"},detailRoot:{flex:1,minHeight:0},detailBodyFallback:{flex:1},inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:We.border.default,backgroundColor:"transparent"},menuCopyRow:{paddingHorizontal:6},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:d.color.buttonSurface,borderWidth:1,borderColor:d.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:d.color.accentSoft,borderColor:d.color.accentBorderStrong}});export function NetworkModal(r){return e(ge,{children:e(me,{...r})})}export function NetworkToolView(r={}){return e(ge,{children:e(me,{...r,inline:true,visible:true,onClose:Nt})})}const Nt=()=>{};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useState as L}from"react";import{FlatList as q,StyleSheet as B,Text as b,TextInput as D,View as u,TouchableOpacity as V}from"react-native";import{Bookmark as N,CopyButton as
|
|
1
|
+
"use strict";import{useState as L}from"react";import{FlatList as q,StyleSheet as B,Text as b,TextInput as D,View as u,TouchableOpacity as V}from"react-native";import{Bookmark as N,CopyButton as P,Search as j,macOSColors as e,useLimit as R,ToolEmptyState as F,resolveListEmptyState as H,EVENT_LIST_PRESET as _,monoFont as $}from"@buoy-gg/shared-ui";import{NetworkEventItemCompact as A}from"./NetworkEventItemCompact";import{NetworkUpgradeBanner as O}from"./NetworkUpgradeBanner";import{generateNetworkCopyText as U}from"../utils/generateNetworkCopyText";import{selectSavedEvents as W}from"../utils/selectSavedEvents";import{useNetworkSaved as K}from"../hooks/useNetworkSaved";import{MAX_SAVED as M}from"../utils/networkSavedStore";import{jsx as t,jsxs as d}from"react/jsx-runtime";const X=c=>c.id;export function NetworkSavedScreen({visible:c,isPro:y,copySettings:v,search:p,onSearchChange:m,onEventPress:S,onUpgradePress:x}){const{savedRecords:o,pinnedLiveIds:h,toggleSave:f,clearSaved:C}=K();const a=R("network.saved");const[k,T]=L("");const g=p!=null&&m!=null;const s=g?p:k;const w=g?m:T;if(!c)return null;const{events:l,lockedCount:n}=W(o,a,s);const E=i=>{f(i)};const I=({item:i})=>t(A,{event:i,onPress:S,onLongPress:E,saved:true,pinned:h.has(i.id)});const z=()=>{if(n===0)return null;return t(O,{title:`${n} saved ${n===1?"request":"requests"} locked`,subtitle:`Your plan keeps ${a}. Upgrade to Pro to unlock the rest.`,onPress:x})};return d(u,{style:r.root,children:[d(u,{style:r.toolbar,children:[t(N,{size:11,color:e.semantic.debug}),d(b,{style:r.toolbarTitle,children:["SAVED \xB7 ",o.length,a>=M?"":`/${a}`]}),y?t(P,{value:()=>U(l,v),size:13,buttonStyle:r.toolbarButton,colors:{idle:e.text.secondary,success:e.semantic.success,error:e.semantic.error},disabled:l.length===0}):null,t(V,{onPress:C,"sentry-label":"ignore clear saved",style:r.toolbarClear,disabled:o.length===0,children:t(b,{style:[r.toolbarClearText,o.length===0&&r.toolbarClearTextDisabled],children:"Clear all"})})]}),o.length>0?d(u,{style:r.searchRow,children:[t(j,{size:13,color:e.text.secondary}),t(D,{style:r.searchInput,placeholder:"Search saved requests\u2026",placeholderTextColor:e.text.muted,value:s,onChangeText:w,"sentry-label":"ignore saved search",accessibilityLabel:"Search saved requests",autoCapitalize:"none",autoCorrect:false,returnKeyType:"search"})]}):null,o.length===0||s.trim().length>0&&l.length===0&&n===0?t(F,{testID:"buoy-network-saved-empty",...H({subject:"saved requests",verb:"kept",search:o.length===0?"":s,total:o.length,waiting:{otto:"empty",title:"No saved requests",message:"Open a request and tap the bookmark to keep it here \u2014 saved requests survive Clear and app restarts."}})}):t(q,{keyboardShouldPersistTaps:"handled",data:l,renderItem:I,keyExtractor:X,contentContainerStyle:r.listContent,showsVerticalScrollIndicator:true,scrollEnabled:true,..._,extraData:h,"sentry-label":"ignore saved requests list",ListFooterComponent:z})]})}const r=B.create({root:{flex:1,minHeight:0},toolbar:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:20,paddingTop:10,paddingBottom:6},toolbarTitle:{flex:1,color:e.semantic.debug,fontSize:10,fontWeight:"700",letterSpacing:.6,fontFamily:$},toolbarButton:{width:26,height:26,borderRadius:6,alignItems:"center",justifyContent:"center"},toolbarClear:{paddingHorizontal:6,paddingVertical:2},toolbarClearText:{color:e.text.muted,fontSize:10},toolbarClearTextDisabled:{color:e.text.disabled},searchRow:{flexDirection:"row",alignItems:"center",gap:6,marginHorizontal:12,marginBottom:8,paddingHorizontal:10,paddingVertical:5,backgroundColor:e.background.input,borderRadius:10,borderWidth:1,borderColor:e.border.default},searchInput:{flex:1,color:e.text.primary,fontSize:13,paddingVertical:2},listContent:{paddingTop:4}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useEffect as
|
|
1
|
+
"use strict";import{useEffect as O,useRef as N,useState as w,useSyncExternalStore as I}from"react";import{ActivityIndicator as V,StyleSheet as $,Text as i,TouchableOpacity as k,View as S}from"react-native";import{ChevronDown as _,Check as J,night as t}from"@buoy-gg/shared-ui";import{conditionsCanApply as W,getNetworkCondition as A,setNetworkCondition as X,subscribeNetworkConditions as R,getNetworkConditions as M,getConditionsRevision as K,setNetworkConditions as Q}from"./store";import{jsx as n,jsxs as h}from"react/jsx-runtime";const L=[{profile:"normal",label:"No throttling"},{profile:"slow",label:"Slow"},{profile:"verySlow",label:"Very slow"},{profile:"offline",label:"Offline"},{profile:"slow3g",label:"Slow 3G"},{profile:"slow4g",label:"Slow 4G"},{profile:"fast4g",label:"Fast 4G"}];const j={normal:"No added delay",slow:"+500 ms before each new request",verySlow:"+2 seconds before each new request",offline:"New requests fail before sending",slow3g:"50 KB/s down, 50 KB/s up; +2000 ms",slow4g:"180 KB/s down, 84.375 KB/s up; +562.5 ms",fast4g:"1012.5 KB/s down, 168.75 KB/s up; +165 ms"};export function NetworkConditionsControl({remote:r,compact:P=false}){I(R,K,K);const l=r?r.state:M();const[U,T]=w(false);const q=I(R,A,A);const F=I(R,W,W);const[C,m]=w(false);const[E,y]=w();const[c,g]=w(false);const u=N(false);const p=N(true);const d=N(0);O(()=>{d.current++;u.current=false;g(false);y(void 0)},[r?.targetId]);O(()=>{p.current=true;return()=>{p.current=false}},[]);const f=r?r.profile:q;const s=r?r.available:F;const z=l?.active??(f!==null&&f!=="normal");const v=f==="offline"?t.color.danger:z?t.color.warning:t.color.accent;async function G(o){if(!s||u.current)return;if(o===f&&(o!=="normal"||!l?.active)){m(false);return}const a=++d.current;u.current=true;g(true);y(void 0);try{if(r)await r.onChange(o);else X(o);if(p.current&&d.current===a)m(false)}catch(b){if(p.current&&d.current===a)y(b instanceof Error?b.message:String(b))}finally{if(d.current===a){u.current=false;if(p.current)g(false)}}}const D=[["auto","Follow speed"],["real","Real link"],["offline","Offline"],["wifi","Wi-Fi"],["cellular","Cellular"],["noInternet","No internet"]];const B=(!r||!!r.onConnectionChange)&&(l?.capabilities.netInfo.supported||l?.capabilities.expoNetwork.supported);const H=L.find(o=>o.profile===f)?.label??"Unavailable";return h(S,{style:e.container,testID:"buoy-network-throttling-screen",children:[n(i,{style:e.heading,children:"Connection profile"}),h(k,{testID:"buoy-network-conditions",accessibilityRole:"button",accessibilityLabel:`Network throttling: ${H}`,accessibilityState:{expanded:C,disabled:!s||c},disabled:!s||c,onPress:()=>m(o=>!o),style:[e.dropdown,C&&e.dropdownOpen,!s&&e.disabled],children:[n(i,{style:[e.value,z&&{color:v}],children:H}),c?n(V,{size:"small",color:t.color.textSecondary}):n(_,{size:16,color:t.color.textSecondary})]}),C&&n(S,{accessibilityRole:"radiogroup",accessibilityLabel:"Connection profile",style:e.options,children:L.map(o=>{const a=f===o.profile;return h(k,{testID:`buoy-network-condition-${o.profile}`,accessibilityRole:"radio",accessibilityLabel:o.label,accessibilityState:{checked:a,disabled:!s||c},disabled:!s||c,onPress:()=>void G(o.profile),style:[e.option,a&&e.selected],children:[h(S,{style:e.optionBody,children:[n(i,{style:[e.optionTitle,a&&{color:v}],children:o.label}),n(i,{style:e.caption,children:j[o.profile]})]}),a&&n(J,{size:16,color:v})]},o.profile)})}),n(i,{style:e.caption,accessibilityLiveRegion:"polite",children:c?"Applying to device\u2026":!s?r?"Conditions unavailable on this device":"Requires a signed-in account and a development build":f?j[f]:"Waiting for device status"}),!!E&&n(i,{accessibilityRole:"alert",style:e.error,children:E}),n(k,{testID:"buoy-network-link-state",accessibilityRole:"button",accessibilityLabel:"App link state",disabled:!s||c||!B,onPress:()=>T(o=>!o),style:e.dropdown,children:h(i,{style:e.value,children:["App link: ",D.find(([o])=>o===l?.connection)?.[1]??"Unavailable"]})}),U&&D.map(([o,a])=>n(k,{testID:`buoy-network-link-${o}`,accessibilityRole:"radio",accessibilityState:{checked:l?.connection===o,disabled:c||!s},disabled:c||!s,style:e.option,onPress:async()=>{if(u.current)return;const b=++d.current;u.current=true;g(true);y(void 0);try{if(r)await r.onConnectionChange?.(o);else Q({connection:o});if(p.current&&d.current===b)T(false)}catch(x){if(p.current&&d.current===b)y(x instanceof Error?x.message:String(x))}finally{if(d.current===b){u.current=false;if(p.current)g(false)}}},children:n(i,{style:e.optionTitle,children:a})},o)),!B&&n(i,{style:e.caption,children:l?.capabilities.netInfo.reason??"This device has no link hook."}),!P&&h(S,{style:e.help,children:[n(i,{style:e.heading,children:"How it works"}),l&&h(i,{style:e.caption,children:["NetInfo: ",l.capabilities.netInfo.supported?"Hook on":l.capabilities.netInfo.reason??"No hook",". Expo Network: ",l.capabilities.expoNetwork.supported?"Hook on":l.capabilities.expoNetwork.reason??"No hook","."]}),n(i,{style:e.caption,children:"Down caps pace bytes to the app in JS. The socket stays at its real speed."}),n(i,{style:e.caption,children:"Up caps wait before send for known bytes. Upload time is simulated. The socket is not paced. Unknown sizes pass through with latency only. Each call shows any cap gap."}),n(i,{style:e.caption,children:"Caps apply per call through global fetch and RN XHR. WebSocket, native images, native SDKs and file transfers are not affected."}),n(i,{style:e.caption,children:"Link state changes what NetInfo and Expo Network report. It does not change the radio or web calls."}),n(i,{style:e.caption,children:"Stays on when this tool closes or capture pauses. No throttling clears both controls. App reload clears them too."})]})]})}const e=$.create({container:{padding:t.gutter,gap:10},heading:{fontSize:t.font.caption,fontWeight:"600",color:t.color.textSecondary},dropdown:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:44,paddingHorizontal:12,paddingVertical:10,borderRadius:t.radius.segment,borderWidth:1,borderColor:t.color.separator,backgroundColor:t.color.surfaceElevated},dropdownOpen:{borderColor:t.color.accentBorderStrong},value:{flex:1,fontSize:t.font.body,color:t.color.text},options:{padding:4,borderRadius:t.radius.row,borderWidth:1,borderColor:t.color.border,backgroundColor:t.color.surface},option:{flexDirection:"row",alignItems:"center",gap:12,minHeight:54,padding:10,borderRadius:t.radius.segment},optionBody:{flex:1,gap:4},optionTitle:{fontSize:t.font.caption,fontWeight:"600",color:t.color.text},selected:{backgroundColor:t.color.surfaceElevated},disabled:{opacity:.45},caption:{fontSize:t.font.caption,lineHeight:19,color:t.color.textSecondary},help:{marginTop:14,paddingTop:16,gap:10,borderTopWidth:1,borderTopColor:t.color.separator},error:{fontSize:t.font.caption,lineHeight:18,color:t.color.danger}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{act as
|
|
1
|
+
"use strict";import{act as a,createElement as f}from"react";import{createRoot as C}from"react-dom/client";import{afterEach as m,beforeEach as b,expect as t,it as c,vi as n}from"vitest";import{NetworkConditionsControl as v}from"./NetworkConditionsControl";n.mock("@buoy-gg/shared-ui",async()=>({ChevronDown:()=>null,Check:()=>null,night:(await n.importActual("../../../../shared/src/ui/night/nightTheme")).night}));n.mock("react-native",()=>({StyleSheet:{create:e=>e},View:({children:e})=>f("div",null,e),Text:({children:e})=>f("span",null,e),ActivityIndicator:()=>f("span",null,"pending"),TouchableOpacity:({children:e,onPress:i,disabled:d,accessibilityLabel:w,accessibilityState:h,testID:k})=>f("button",{onClick:i,disabled:d,"aria-label":w,"aria-checked":h?.checked,"data-testid":k},e)}));n.mock("./store",()=>({NETWORK_CONDITIONS:{normal:{label:"Normal"},slow:{label:"Slow"},verySlow:{label:"Very slow"},offline:{label:"Offline"}},getConditionsRevision:()=>0,getNetworkConditions:()=>({capabilities:{netInfo:{supported:false},expoNetwork:{supported:false}}}),setNetworkConditions:n.fn(),getNetworkCondition:()=>"normal",conditionsCanApply:()=>true,subscribeNetworkConditions:()=>()=>{},setNetworkCondition:n.fn()}));let p;let l;b(()=>{globalThis.IS_REACT_ACT_ENVIRONMENT=true;l=document.createElement("div");p=C(l)});m(()=>a(()=>p.unmount()));const o=e=>l.querySelector(`[data-testid="buoy-network-condition-${e}"]`);function r(e){a(()=>p.render(f(v,{remote:e})))}const u=()=>l.querySelector('[data-testid="buoy-network-conditions"]');const s=()=>a(()=>u().click());c("defaults to a closed No throttling dropdown and closes when the current option is chosen",()=>{const e=n.fn();r({profile:"normal",available:true,onChange:e});t(u().textContent).toBe("No throttling");t(o("normal")).toBeNull();s();t(["normal","slow","verySlow","offline"].every(i=>!!o(i))).toBe(true);a(()=>o("normal").click());t(o("normal")).toBeNull();t(e).not.toHaveBeenCalled()});c("blocks duplicate remote changes and waits for the device profile before selecting it",async()=>{let e;const i=n.fn(()=>new Promise(d=>{e=d}));r({profile:"normal",available:true,onChange:i});s();a(()=>o("slow").click());t(o("offline").disabled).toBe(true);t(o("normal").getAttribute("aria-checked")).toBe("true");a(()=>o("offline").click());t(i).toHaveBeenCalledExactlyOnceWith("slow");await a(async()=>e());r({profile:"slow",available:true,onChange:i});t(u().textContent).toBe("Slow");t(o("slow")).toBeNull();s();t(o("slow").getAttribute("aria-checked")).toBe("true")});c("reports a remote error, permits retry, and disables unavailable devices",async()=>{const e=n.fn().mockRejectedValue(new Error("Device disconnected"));r({profile:"normal",available:true,onChange:e});s();await a(async()=>o("offline").click());t(l.textContent).toContain("Device disconnected");t(o("offline").disabled).toBe(false);r({profile:null,available:false,onChange:e});t(o("normal").disabled).toBe(true);t(l.textContent).toContain("Conditions unavailable on this device")});c("offers all v2 speed profiles on the remote control",async()=>{const e=n.fn().mockResolvedValue(void 0);r({profile:"normal",available:true,onChange:e});s();for(const i of["slow3g","slow4g","fast4g"])t(o(i)).not.toBeNull();await a(async()=>o("slow4g").click());t(e).toHaveBeenCalledExactlyOnceWith("slow4g");t(l.textContent).toContain("socket is not paced")});c("forwards a link change and keeps device readback as the selected state",async()=>{const e=n.fn().mockResolvedValue(void 0);const i={version:2,connection:"real",capabilities:{netInfo:{supported:true},expoNetwork:{supported:false}}};r({profile:"normal",available:true,onChange:n.fn(),state:i,onConnectionChange:e});a(()=>l.querySelector('[data-testid="buoy-network-link-state"]').click());await a(async()=>l.querySelector('[data-testid="buoy-network-link-cellular"]').click());t(e).toHaveBeenCalledExactlyOnceWith("cellular");t(l.textContent).toContain("App link: Real link")});c("shows a late peer gap even when the other hook works",()=>{const e={version:2,connection:"real",capabilities:{netInfo:{supported:false,reason:"Link hook loaded too late."},expoNetwork:{supported:true}}};r({profile:"normal",available:true,onChange:n.fn(),state:e,onConnectionChange:n.fn()});t(l.textContent).toContain("NetInfo: Link hook loaded too late.");t(l.textContent).toContain("Expo Network: Hook on")});c("ignores an old device action result after switching devices",async()=>{let e;r({targetId:"first",profile:"normal",available:true,onChange:()=>new Promise((i,d)=>{e=d})});s();a(()=>o("slow3g").click());r({targetId:"second",profile:"fast4g",available:true,onChange:n.fn()});await a(async()=>e(new Error("Old device failed")));t(l.textContent).not.toContain("Old device failed");t(u().textContent).toBe("Fast 4G");t(u().disabled).toBe(false)});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useSyncExternalStore as
|
|
1
|
+
"use strict";import{useSyncExternalStore as e}from"react";import{Text as a,View as i}from"react-native";import{NetworkIcon as d}from"@buoy-gg/shared-ui";import{getNetworkCondition as n,subscribeNetworkConditions as r,NETWORK_CONDITIONS as s,getConditionsRevision as l,networkConditionsActive as f}from"./store";import{jsx as t,jsxs as p}from"react/jsx-runtime";export function NetworkConditionsIcon({size:c}){e(r,l,l);const m=f();const o=e(r,n,n);return p(i,{accessibilityLabel:o==="normal"?"Network":`Network: ${s[o].label}`,children:[t(d,{size:c}),m&&t(i,{pointerEvents:"none",style:{position:"absolute",top:-6,right:-8,width:48,alignItems:"flex-end"},children:t(a,{testID:"buoy-network-condition-indicator",numberOfLines:1,style:{color:"#FFCC66",fontSize:10,fontWeight:"700"},children:o==="normal"?"LINK":o==="offline"?"OFF":`+${s[o].delayMs}`})})]})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useEffect as
|
|
1
|
+
"use strict";import{useEffect as O,useRef as T,useState as L,useSyncExternalStore as m}from"react";import{ActivityIndicator as ee,StyleSheet as te,Text as b,TouchableOpacity as H,View as c,ScrollView as oe,useWindowDimensions as ie,Platform as V}from"react-native";import{FloatingTool as ne,night as t,openFloatingTool as re,persistentStorage as le,registerPersistentFloatingTool as ae}from"@buoy-gg/shared-ui";import{conditionsCanApply as $,getNetworkCondition as A,setNetworkCondition as se,subscribeNetworkConditions as z,getConditionsRevision as q,getNetworkConditions as ce,NETWORK_CONDITIONS as K}from"./store";import{NetworkConditionsControl as de}from"./NetworkConditionsControl";import{jsx as e,jsxs as w}from"react/jsx-runtime";export function createRemoteConditionsSource(){let a;const s=new Set;return{getSnapshot:()=>a,subscribe:l=>{s.add(l);return()=>{s.delete(l)}},update(l){a=l;s.forEach(n=>n())}}}const fe=()=>()=>{};const U=()=>void 0;const S=[{id:"normal",label:"No throttling",detail:"No added delay"},{id:"slow",label:"Slow",detail:"+500 ms before sending"},{id:"verySlow",label:"Very slow",detail:"+2 seconds before sending"},{id:"offline",label:"Offline",detail:"New requests fail"}];const ge={id:"network-throttling",render:a=>e(NetworkFloatingTool,{...a})};export function registerLocalNetworkFloatingTool(){if(typeof __DEV__==="undefined"||!__DEV__)return()=>{};return ae(ge,le)}if(typeof __DEV__!=="undefined"&&__DEV__&&typeof navigator!=="undefined"&&navigator.product==="ReactNative"){registerLocalNetworkFloatingTool()}export function openNetworkFloatingTool(a,s=false){re({id:"network-throttling",render:l=>e(NetworkFloatingTool,{...l,source:a,showControls:s})})}export function NetworkFloatingTool({id:a,revealToken:s,dismiss:l,source:n,showControls:v=false}){m(z,q,q);const G=ce();const J=m(z,A,A);const Q=m(z,$,$);const f=m(n?.subscribe??fe,n?.getSnapshot??U,U);const x=n?f?.profile??null:J;const p=n?f?.available===true:Q;const[g,F]=L(v);O(()=>{F(v)},[v,s]);const[d,k]=L(false);const[C,D]=L();const y=T(false);const u=T(0);const h=T(true);const{width:M,height:X}=ie();O(()=>{h.current=true;return()=>{h.current=false}},[]);O(()=>{u.current+=1;y.current=false;k(false);D(void 0)},[n,f?.targetId]);const _=n?f?.state?.active??(x!==null&&x!=="normal"):G.active;const i=x??"normal";const R=S.find(r=>r.id===i)??{label:K[i].label};const P=S[(S.findIndex(r=>r.id===i)+1)%S.length];const Y=!p||i==="offline"?0:i==="verySlow"?1:i==="slow"?2:4;const Z=d?"Applying\u2026":!p?"Unavailable":i==="normal"?_?"Link set":"0 ms":i==="slow"?"+500 ms":i==="verySlow"?"+2000 ms":i==="offline"?"Blocked":`${Math.round((K[i].downloadBytesPerSecond??0)/1e3)} kB/s`;async function W(r,I=false){if(y.current)return;const N=++u.current;y.current=true;k(true);D(void 0);const B=n?.getSnapshot();try{if(n){if(!B?.available)throw new Error("Device unavailable. Open Network again to reconnect these controls.");await B.onChange(r)}else se(r);if(h.current&&u.current===N){if(I)l()}}catch(E){if(h.current&&u.current===N)D(E instanceof Error?E.message:String(E))}finally{if(u.current===N){y.current=false;if(h.current)k(false)}}}const j=C||g?w(c,{style:o.menu,children:[!!C&&e(b,{accessibilityRole:"alert",style:o.error,children:C}),g&&e(oe,{testID:"throttling-controls-scroll",style:{maxHeight:Math.min(420,X-180)},children:e(de,{remote:n?f??{profile:null,available:false,onChange:async()=>{throw new Error("Device unavailable.")}}:void 0})})]}):void 0;return e(ne,{id:a,revealToken:s,variant:"strip",dragFromSurface:V.OS!=="android"||!g,accessibilityLabel:`Move or hide network throttling. ${_?"Active":"Off"}`,accessory:V.OS==="android"?void 0:j,children:w(c,{style:{width:Math.max(220,Math.min(336,M-64))},children:[w(c,{style:[o.row,{width:Math.max(220,Math.min(336,M-64))}],children:[e(H,{testID:"throttling-cycle",accessibilityRole:"button",accessibilityLabel:`Network: ${R.label}. Switch to ${P.label}`,accessibilityState:{disabled:d||!p},disabled:d||!p,onPress:()=>void W(P.id),style:o.signalButton,children:d?e(ee,{size:"small",color:t.color.accent}):w(c,{testID:`throttling-signal-${i}`,style:o.signal,children:[[7,12,18,24].map((r,I)=>e(c,{style:{width:4,height:r,borderRadius:2,backgroundColor:I<Y?i==="offline"?t.color.danger:t.color.accent:t.color.fillTertiary}},r)),i==="offline"&&e(c,{style:o.slash})]})}),e(c,{style:o.profile,children:e(b,{testID:"throttling-profile",accessibilityLabel:`Connection profile: ${R.label}`,accessibilityLiveRegion:"polite",numberOfLines:1,style:o.profileLabel,children:R.label})}),e(b,{testID:"throttling-status",numberOfLines:1,accessibilityLiveRegion:"polite",style:o.status,children:Z}),e(H,{testID:"throttling-edit",accessibilityRole:"button",accessibilityLabel:g?"Hide speed and link controls":"Edit speed and link state",onPress:()=>F(r=>!r),style:o.action,children:e(b,{style:o.actionText,children:g?"Done":"Edit"})}),e(c,{style:o.separator}),e(H,{testID:"throttling-close",accessibilityRole:"button",accessibilityLabel:"Close and turn off throttling",disabled:d,accessibilityState:{disabled:d},onPress:()=>{if(!_)l();else void W("normal",true)},style:[o.action,d&&o.disabled],children:e(b,{style:o.actionText,children:"Close"})})]}),V.OS==="android"&&j]})})}const o=te.create({row:{flexDirection:"row",alignItems:"center",gap:6,paddingVertical:4,minHeight:48},signalButton:{width:36,minHeight:44,alignItems:"center",justifyContent:"center"},signal:{flexDirection:"row",alignItems:"flex-end",gap:3,height:24},slash:{position:"absolute",width:30,height:2,backgroundColor:t.color.danger,top:11,left:-2,transform:[{rotate:"-45deg"}]},separator:{height:20,width:1,backgroundColor:t.color.separator,marginHorizontal:2},status:{color:t.color.textSecondary,fontSize:10,lineHeight:15,flexShrink:1},profile:{flex:1,flexDirection:"row",alignItems:"center",gap:6,minHeight:44},profileLabel:{color:t.color.text,fontSize:13,fontWeight:"500",flexShrink:1},action:{minHeight:36,minWidth:52,borderRadius:t.radius.input,borderWidth:1,borderColor:t.color.accentBorderStrong,alignItems:"center",justifyContent:"center",paddingHorizontal:10},actionText:{color:t.color.accent,fontSize:12,fontWeight:"600"},disabled:{opacity:.4},menu:{marginVertical:8,padding:6,borderRadius:t.radius.card,borderWidth:1,borderColor:t.color.separator,backgroundColor:t.color.surface,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.25,shadowRadius:16,elevation:8},error:{color:t.color.danger,fontSize:12,lineHeight:18,padding:10}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{act as
|
|
1
|
+
"use strict";import{act as c,createElement as u}from"react";import{createRoot as y}from"react-dom/client";import{afterEach as b,beforeEach as k,expect as t,it as d,vi as a}from"vitest";import{NetworkFloatingTool as B,createRemoteConditionsSource as m}from"./NetworkFloatingTool";const n=a.hoisted(()=>({platform:"web",profile:"normal",available:true,listeners:new Set,set:a.fn()}));a.mock("./store",()=>({getConditionsRevision:()=>0,getNetworkConditions:()=>({active:n.profile!=="normal",capabilities:{netInfo:{supported:false},expoNetwork:{supported:false}}}),NETWORK_CONDITIONS:{fast4g:{label:"Fast 4G",downloadBytesPerSecond:1012500}},getNetworkCondition:()=>n.profile,conditionsCanApply:()=>n.available,subscribeNetworkConditions:e=>{n.listeners.add(e);return()=>n.listeners.delete(e)},setNetworkCondition:e=>{n.set(e);n.profile=e;n.listeners.forEach(o=>o())}}));a.mock("@buoy-gg/shared-ui",async()=>({night:(await a.importActual("../../../../shared/src/ui/night/nightTheme")).night,ChevronDown:()=>null,Check:()=>null,openFloatingTool:a.fn(),FloatingTool:({children:e,accessory:o})=>u("div",null,e,o)}));a.mock("react-native",()=>({Platform:{get OS(){return n.platform}},StyleSheet:{create:e=>e},useWindowDimensions:()=>({width:390,height:844}),View:({children:e,testID:o})=>u("div",{"data-testid":o},e),Text:({children:e,testID:o})=>u("span",{"data-testid":o},e),ScrollView:({children:e})=>u("div",null,e),ActivityIndicator:()=>null,TouchableOpacity:({children:e,onPress:o,disabled:r,testID:s,accessibilityLabel:h})=>u("button",{onClick:o,disabled:r,"data-testid":s,"aria-label":h},e)}));let v;let p;const g=a.fn();k(()=>{globalThis.IS_REACT_ACT_ENVIRONMENT=true;n.platform="web";n.profile="normal";n.available=true;n.set.mockClear();g.mockClear();p=document.createElement("div");v=y(p)});b(()=>c(()=>v.unmount()));const w=e=>p.querySelector(`[data-testid="${e}"]`);const l=async e=>c(async()=>w(e).click());const i=()=>p.querySelector('[data-testid="throttling-status"]')?.textContent;function f(e){c(()=>v.render(u(B,{id:"network-throttling",revealToken:1,dismiss:g,source:e})))}async function C(e){const o=["normal","slow","verySlow","offline"];const r=(o.indexOf(e)-o.indexOf(n.profile)+o.length)%o.length;for(let s=0;s<r;s++)await l("throttling-cycle")}d("cycles and applies every profile immediately, including wrapping to normal",async()=>{f();for(const[e,o]of[["slow","+500 ms"],["verySlow","+2000 ms"],["offline","Blocked"],["normal","0 ms"]]){await l("throttling-cycle");t(n.profile).toBe(e);t(p.querySelector(`[data-testid="throttling-signal-${e}"]`)).not.toBeNull();t(i()).toBe(o)}t(n.set).toHaveBeenCalledTimes(4)});d("keeps the profile label informational when tapped",async()=>{f();await l("throttling-profile");t(n.set).not.toHaveBeenCalled();t(n.profile).toBe("normal");t(w("throttling-profile").closest("button")).toBeNull()});d("changes active profiles and stops before dismissal",async()=>{n.profile="slow";f();await C("offline");t(n.profile).toBe("offline");await l("throttling-close");t(n.profile).toBe("normal");t(g).toHaveBeenCalledOnce()});d("reflects external changes and disables cycling when account admission is revoked",()=>{f();c(()=>{n.profile="offline";n.listeners.forEach(e=>e())});t(i()).toBe("Blocked");c(()=>{n.profile="normal";n.available=false;n.listeners.forEach(e=>e())});t(i()).toBe("Unavailable");t(w("throttling-cycle").disabled).toBe(true)});d("keeps remote failures visible and does not claim a profile was applied",async()=>{const e=m();const o=a.fn().mockRejectedValue(new Error("Connection lost"));e.update({profile:"normal",available:true,onChange:o});f(e);await C("slow");t(p.textContent).toContain("Connection lost");t(i()).toBe("0 ms");t(n.set).not.toHaveBeenCalled()});d("prevents duplicate remote operations and follows confirmed snapshots",async()=>{const e=m();let o;const r=a.fn(()=>new Promise(s=>{o=s}));e.update({profile:"normal",available:true,onChange:r});f(e);await l("throttling-cycle");await l("throttling-cycle");t(r).toHaveBeenCalledOnce();t(i()).toBe("Applying\u2026");await c(async()=>o());t(i()).toBe("0 ms");c(()=>e.update({profile:"slow",available:true,onChange:r}));t(i()).toBe("+500 ms");c(()=>e.update(void 0));t(i()).toBe("Unavailable")});d("ignores a previous device's completion after switching devices",async()=>{const e=m();let o;e.update({targetId:"first",profile:"normal",available:true,onChange:()=>new Promise((r,s)=>{o=s})});f(e);await C("slow");c(()=>e.update({targetId:"second",profile:"normal",available:true,onChange:a.fn()}));await c(async()=>o(new Error("Old device failed")));t(p.textContent).not.toContain("Old device failed");t(i()).toBe("0 ms");t(w("throttling-profile").textContent).toBe("No throttling")});d("keeps the strip open when stopping a remote device fails",async()=>{const e=m();e.update({profile:"offline",available:true,onChange:a.fn().mockRejectedValue(new Error("Could not stop"))});f(e);await l("throttling-close");t(g).not.toHaveBeenCalled();t(i()).toBe("Blocked");t(p.textContent).toContain("Could not stop")});d.each(["web","android"])("opens the full remote control on %s and forwards v2 changes",async e=>{n.platform=e;const o=m();const r=a.fn().mockResolvedValue(void 0);const s=a.fn().mockResolvedValue(void 0);const h={version:2,active:false,connection:"real",capabilities:{netInfo:{supported:true},expoNetwork:{supported:false}}};o.update({profile:"normal",available:true,onChange:r,onConnectionChange:s,state:h});f(o);await l("throttling-edit");await l("buoy-network-conditions");await l("buoy-network-condition-fast4g");t(r).toHaveBeenCalledExactlyOnceWith("fast4g");t(i()).toBe("0 ms");c(()=>o.update({profile:"fast4g",available:true,onChange:r,onConnectionChange:s,state:{...h,active:true}}));t(i()).toBe("1013 kB/s");await l("buoy-network-link-state");await l("buoy-network-link-cellular");t(s).toHaveBeenCalledExactlyOnceWith("cellular");await l("throttling-edit");t(w("buoy-network-conditions")).toBeNull();t(i()).toBe("1013 kB/s")});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{useSyncExternalStore as l}from"react";import{getEffectiveNetworkConnection as d,getConditionsRevision as i,subscribeNetworkConditions as m}from"../store";import{maskConnection as b}from"./patchNetwork";export function wrapNetInfoApi(o){const s=e=>b(e,d());const n={};for(const e of["fetch","refresh"]){const t=o[e];n[e]=(...r)=>Promise.resolve(t(...r)).then(s)}const u=o.addEventListener;n.addEventListener=e=>u(t=>e(s(t)));const a=o.useNetInfo;n.useNetInfo=(...e)=>{const t=a(...e);l(m,i,i);return s(t)};const c=[];try{for(const[e,t]of Object.entries(n)){for(const r of new Set([o,o.default].filter(Boolean))){const f=Object.getOwnPropertyDescriptor(r,e);Object.defineProperty(r,e,{configurable:true,writable:true,enumerable:true,value:t});c.push(()=>{if(f)Object.defineProperty(r,e,f);else delete r[e]})}}}catch(e){c.reverse().forEach(t=>t());throw e}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function maskConnection(t,n,i=false){if(n==="auto"||n==="real")return{...t};const r=n==="offline"?"none":n==="cellular"?"cellular":"wifi";return{type:i?r.toUpperCase():r,...!i?{details:n==="offline"?null:{isConnectionExpensive:n==="cellular",...n==="cellular"?{cellularGeneration:null,carrier:null}:{}}}:{},isConnected:n!=="offline",isInternetReachable:n!=="offline"&&n!=="noInternet"}}export function patchConnectionState(t,n,i,r={}){const o=r.eventName??"netInfo.networkStatusDidChange";if((t.eventEmitter.listenerCount?.(o)??0)>0)throw new Error("Link hook loaded too late. Load it before app code, then reload.");const y=t.getCurrentState;const s=t.eventEmitter.addListener;const l=new Set;let a={type:r.expo?"UNKNOWN":"unknown",isConnected:null,isInternetReachable:null};let u=0;let f=false;let C=n();const d=e=>maskConnection(e,n(),r.expo);const p=()=>{if(!f)l.forEach(e=>e(d(a)))};const x=s.call(t.eventEmitter,o,e=>{u++;a=e;p()});const h=async(...e)=>{const c=u;const b=await y.apply(r.receiver??t,e);if(e[0])return d(b);if(c===u)a=b;return d(a)};const E=(e,c)=>{if(e!==o)return s.call(t.eventEmitter,e,c);l.add(c);return{remove:()=>{l.delete(c)}}};let w;const S=()=>{f=true;try{w?.()}finally{try{x.remove()}finally{l.clear();if(t.getCurrentState===h)t.getCurrentState=y;if(t.eventEmitter.addListener===E)t.eventEmitter.addListener=s}}};try{t.getCurrentState=h;t.eventEmitter.addListener=E;w=i(()=>{const e=n();if(e!==C){C=e;p()}})}catch(e){S();throw e}void h(...r.expo?[]:[void 0]).then(p).catch(()=>{});return()=>{if(f)return;try{l.forEach(e=>e({...a}))}finally{S()}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{realNow as w}from"../utils/realNow";import{waitBeforeDispatch as B,throwIfAborted as m}from"./wait";export const chunkSize=e=>Math.max(1,Math.min(16384,Math.floor(e*.02)));export const utf8Length=e=>new TextEncoder().encode(e).byteLength;export function bodyByteLength(e){if(e==null)return 0;if(typeof e==="string")return utf8Length(e);if(e instanceof ArrayBuffer)return e.byteLength;if(ArrayBuffer.isView(e))return e.byteLength;if(typeof Blob!=="undefined"&&e instanceof Blob)return e.size;if(typeof URLSearchParams!=="undefined"&&e instanceof URLSearchParams)return utf8Length(e.toString());return null}export async function paceByteCount(e,f,o,d){const y=chunkSize(f);const a=w();for(let i=0;i<e;){const b=Math.min(y,e-i);await B(Math.max(0,a+(i+b)/f*1e3-w()),o);m(o);i+=b;d?.(i,e)}}export function uploadBodySize(e,f){try{const o=typeof e==="object"&&"method"in e?e:void 0;const d=f?.body!==void 0?f.body:o&&"_bodyInit"in o?o._bodyInit:o?.body;return uploadSize(d)}catch{return L(0)}}function L(e){return{knownBytes:e,status:e>0?"partial":"not-applied",note:e>0?"upload cap partial: size unknown":"upload cap not applied: size unknown"}}export function uploadSize(e){let f=0;try{const o=bodyByteLength(e);if(o!==null)return{knownBytes:o,status:"applied"};if(e&&typeof e==="object"){const d=e;const y=Array.isArray(d._parts)?d._parts:typeof FormData!=="undefined"&&e instanceof FormData&&d.entries?d.entries():void 0;if(y){for(const[,a]of y){try{const i=bodyByteLength(a);if(i!==null)f+=i;else if(a&&typeof a==="object"&&"uri"in a&&"size"in a&&typeof a.size==="number"&&Number.isSafeInteger(a.size)&&a.size>=0)f+=a.size}catch{}}}}}catch{}return L(f)}export function createBytePacer(e){let f=0;return async(o,d)=>{const y=o/e*1e3;const a=w();const i=Math.max(0,y-f);if(i>0)await B(i,d);m(d);f=Math.min(chunkSize(e)/e*1e3,Math.max(0,f+w()-a-y))}}export function pacedStream(e,f,o,d){const y=createBytePacer(f);let a;const i=()=>{a?.releaseLock();a=void 0};const b=t=>{void(a?a.cancel(t):e.cancel(t)).catch(()=>{});i()};const l=new AbortController;let r;let n=0;let s=false;let u;const c=(t,p=false)=>{if(s)return;s=true;o?.removeEventListener("abort",h);l.abort();r=void 0;if(p)u.error(t);else{i();u.close()}d?.(null,t)};const h=()=>{const t=o?.reason!==void 0?o.reason:Object.assign(new Error("The request was aborted."),{name:"AbortError"});c(t,true);b(t)};return new ReadableStream({start(t){u=t;o?.addEventListener("abort",h,{once:true});if(o?.aborted)h()},async pull(){try{if(!r||n===r.byteLength){const x=await(a??=e.getReader()).read();if(s)return;if(x.done){c();return}r=x.value;n=0}const t=Math.min(chunkSize(f),r.byteLength-n);const p=r.subarray(n,n+t);await y(t,l.signal);if(s)return;n+=t;d?.(p);u.enqueue(p)}catch(t){if(!s){c(t,true);b(t)}}},cancel(t){if(!s){s=true;o?.removeEventListener("abort",h);l.abort();r=void 0;d?.(null,t??new Error("Body read stopped."))}b(t)}},{highWaterMark:0})}export function paceResponse(e,f,o,d,y=false){if(y||[204,205,304].includes(e.status)||e.body===null){d?.(null);return e}let a;let i=false;const b=()=>{if(!a){let r;let n=false;const s=new ReadableStream({async pull(u){i=true;try{if(e.body?.getReader){r??=e.body.getReader();const c=await r.read();if(n)return;if(c.done){n=true;r.releaseLock();r=void 0;u.close()}else u.enqueue(c.value)}else{const c=new Uint8Array(await e.arrayBuffer());if(n)return;u.enqueue(c);n=true;u.close()}}catch(c){if(!n){n=true;r?.releaseLock();r=void 0;u.error(c)}}},cancel(u){i=true;n=true;const c=r?r.cancel(u):e.body?.cancel?.(u);r?.releaseLock();r=void 0;return c}},{highWaterMark:0});a=pacedStream(s,f,o,d)}return a};const l=async(r=true)=>{if(i||a?.locked||e.bodyUsed)throw new TypeError("Body has already been read.");i=true;const n=b().getReader();const s=[];let u=0;try{for(;;){const t=await n.read();if(t.done)break;if(r){s.push(t.value);u+=t.value.byteLength}}}finally{n.releaseLock()}const c=new Uint8Array(u);let h=0;for(const t of s){c.set(t,h);h+=t.byteLength}return c};return new Proxy(e,{get(r,n){if(n==="body")return b();if(n==="bodyUsed")return i||e.bodyUsed;if(n==="arrayBuffer")return async()=>(await l()).buffer;if(n==="bytes")return l;if(n==="text")return async()=>new TextDecoder().decode(await l());if(n==="json")return async()=>JSON.parse(new TextDecoder().decode(await l()));if(n==="blob")return async()=>{if(i||a?.locked||e.bodyUsed)throw new TypeError("Body has already been read.");m(o);let u=false;try{new Blob([new Uint8Array(0)]);u=true}catch{}if(u)return new Blob([await l()],{type:r.headers.get("content-type")??""});const c=r.clone();let h;Object.defineProperty(c,"arrayBuffer",{configurable:true,value:async()=>{if(c.body&&!c.body.locked)void c.body.cancel().catch(()=>{});h??=l();return(await h).buffer}});try{const t=c.blob();void t.catch(()=>{});await(h??l(false));m(o);return await t}finally{if(c.body&&!c.body.locked)void c.body.cancel().catch(()=>{})}};if(n==="formData")return async()=>{const u=await l();return new Response(u,{headers:r.headers}).formData()};if(n==="clone")return()=>{if(i||a?.locked||e.bodyUsed)throw new TypeError("Body has already been read.");return paceResponse(r.clone(),f,o)};const s=Reflect.get(r,n,r);return typeof s==="function"?s.bind(r):s}})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export const NETWORK_CONDITIONS={normal:{label:"Normal",delayMs:0},offline:{label:"Offline (requests)",delayMs:0},slow:{label:"Slow (+500 ms)",delayMs:500},verySlow:{label:"Very slow (+2000 ms)",delayMs:2e3},slow3g:{label:"Slow 3G",delayMs:2e3,downloadBytesPerSecond:5e4,uploadBytesPerSecond:5e4},slow4g:{label:"Slow 4G",delayMs:562.5,downloadBytesPerSecond:18e4,uploadBytesPerSecond:84375},fast4g:{label:"Fast 4G",delayMs:165,downloadBytesPerSecond:1012500,uploadBytesPerSecond:168750}};export const CONNECTIONS=["auto","real","offline","wifi","cellular","noInternet"];export const CONDITIONS_SCOPE={download:"Paces bytes to the app in JS. The socket stays at its real speed.",upload:"Waits before send for known body bytes. Unknown sizes pass through with latency only. Multipart overhead is not counted. Each call marks a partial or skipped cap. Upload time is simulated; the socket is not paced.",transports:"Affects global fetch and RN XHR. WebSocket, native images, native SDKs and file transfers are not affected."};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function chooseConditionsSnapshot(i,r){if(!i)return null;if(!r||r.runtimeId!==i.runtimeId||r.revision<i.revision)return i;return r}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{hasAccountAccess as
|
|
1
|
+
"use strict";import{hasAccountAccess as u,subscribeAccountAccess as w}from"@buoy-gg/shared-ui";import{addNetworkListener as N,startNetworkListener as C,getNetworkListenerCount as k,stopNetworkListener as h}from"../utils/networkListener";import{NETWORK_CONDITIONS as d,CONNECTIONS as m,CONDITIONS_SCOPE as x}from"./profiles";export{NETWORK_CONDITIONS,CONDITIONS_SCOPE}from"./profiles";const c={netInfo:{supported:false,reason:"Load the NetInfo hook before app code."},expoNetwork:{supported:false,reason:"Load the Expo Network hook before app code."}};let r="auto";let p=0;export const getNetworkConnection=()=>r;export const getConditionsRevision=()=>p;export const getEffectiveNetworkConnection=()=>!conditionsCanApply()?"real":r==="auto"?n==="offline"?"offline":"real":r;export const networkConditionsActive=()=>n!=="normal"||!["auto","real"].includes(r);export function setConnectionSupport(o,e){c[o]=e;p++;s.forEach(t=>t())}export function getNetworkConditions(){const o=d[n];return{version:2,runtimeId:networkConditionsRuntimeId,revision:p,profile:n,connection:r,available:conditionsCanApply(),active:networkConditionsActive(),delayMs:o.delayMs,downloadBytesPerSecond:o.downloadBytesPerSecond??null,uploadBytesPerSecond:o.uploadBytesPerSecond??null,capabilities:{...c,fetch:"JS body delivery",xhr:"RN progress and body delivery",upload:"time-simulated",webSocket:false,nativeImages:false,nativeModules:false},scope:x}}export function setNetworkConditions(o){if(!o||typeof o!=="object"||Array.isArray(o))throw new Error("Choose a speed or link state.");const e=o;if(Object.keys(e).some(a=>a!=="profile"&&a!=="connection")||!("profile"in e)&&!("connection"in e))throw new Error("Choose a speed or link state.");const t="profile"in e?e.profile:n;const i="connection"in e?e.connection:t==="normal"&&"profile"in e?"auto":r;if(typeof t!=="string"||!Object.prototype.hasOwnProperty.call(d,t))throw new Error("Choose a valid speed profile.");if(!m.includes(i))throw new Error("Choose a valid link state.");if((t!=="normal"||!["auto","real"].includes(i))&&!conditionsCanApply())throw new Error("Use a signed-in account and a dev build.");if(!["auto","real"].includes(i)&&!c.netInfo.supported&&!c.expoNetwork.supported)throw new Error("Load a link hook before app code.");if(t===n&&i===r)return getNetworkConditions();const f=t!=="normal";if(f&&!l){C();l=N(()=>{})}if(!f){l?.();l=void 0;if(k()===0)h()}n=t;r=i;p++;s.forEach(a=>a());return getNetworkConditions()}export const networkConditionsRuntimeId=`${Date.now()}-${Math.random().toString(36).slice(2)}`;let n="normal";let l;const s=new Set;export const conditionsCanApply=()=>typeof __DEV__!=="undefined"&&__DEV__&&u();export const getNetworkCondition=()=>n;export const subscribeNetworkConditions=o=>{s.add(o);return()=>{s.delete(o)}};export function setNetworkCondition(o){return setNetworkConditions({profile:o}).profile}export function snapshotNetworkCondition(o){if(n==="normal"||!conditionsCanApply()||!/^https?:\/\//i.test(o))return;const{label:e,...t}=d[n];return Object.freeze({profile:n,...t})}w(()=>{if(!u())setNetworkCondition("normal");s.forEach(o=>o())});
|
|
@@ -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))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getAccountAccess as
|
|
1
|
+
"use strict";import{getAccountAccess as f,hasAccountAccess as c,subscribeAccountAccess as _}from"@buoy-gg/shared-ui";import{findMatchingRule as d,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))}export function overridesCanApply(){return c()&&!(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,u){return{hooksInstalled:e!==null,devFlag:typeof __DEV__==="undefined"?"undefined":__DEV__,ruleCount:e?e.getRules().length:0,matches:e?d(t,u,e.getRules())!==null:false}}const m=3e3;export function accountCheckFor(t,u,i,l){if(!e||c())return null;if(typeof __DEV__!=="undefined"&&!__DEV__)return null;if(f().status!=="initializing")return null;if(!d(t,u,e.getRules(),i,l))return null;return new Promise(r=>{let n=()=>{};const o=()=>{R(s);n();r()};const s=g(o,m);n=_(()=>{if(f().status!=="initializing")o()})})}export function overrideForRequest(t,u,i,l){if(!e)return null;if(typeof __DEV__!=="undefined"&&!__DEV__)return null;let r=e.getRules();if(r.length===0)return null;if(!c()){r=r.filter(s=>s.sandbox===true);if(r.length===0)return null}const n=d(t,u,r,i,l);if(!n)return null;const o=a(n);e.recordMatch(n.id);if(!o)return null;e.recordHit(n.id);return p(n)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const a="[]{}()\\.^$+|-,?";export function escapeRegex(e){let n="";for(let t=0;t<e.length;t++){const r=e.charAt(t);if(a.indexOf(r)!==-1){n+="\\"}n+=r}return n.split("*").join(".*")}const i=new Map;export function compilePattern(e){const n=i.get(e);if(n)return n;const t=e.startsWith("/")?`[a-zA-Z][a-zA-Z0-9+.-]*://[^/]*${escapeRegex(e)}`:escapeRegex(e);const r=new RegExp(`^${t}$`);if(i.size>200)i.clear();i.set(e,r);return r}function c(e,n){if(!e)return false;const t=n.toLowerCase();for(const r of Object.keys(e)){if(r.toLowerCase()===t&&e[r]!==void 0&&e[r]!=="")return true}return false}export function canonicalJson(e){const n=t=>Array.isArray(t)?t.map(n):t&&typeof t==="object"?Object.fromEntries(Object.keys(t).sort().map(r=>[r,n(t[r])])):t;return JSON.stringify(n(e))??"null"}function f(e,n,t){if(typeof e!=="string"||!e.includes(n))return false;try{const r=JSON.parse(e);const s=Array.isArray(r)?r:[r];return s.some(o=>{if(!o||typeof o!=="object"||o.operationName!==n)return false;return t===void 0||canonicalJson(o.variables??{})===t})}catch{return false}}export function ruleMatches(e,n,t,r,s){if(e.methods&&e.methods.length>0){if(!e.methods.includes(t.toUpperCase()))return false}if(e.requireHeader&&!c(r,e.requireHeader))return false;if(e.bodyIncludes&&(typeof s!=="string"||!s.includes(e.bodyIncludes)))return false;if(e.graphqlOperation&&!f(s,e.graphqlOperation,e.graphqlVariables))return false;try{return compilePattern(e.urlPattern).test(n)}catch{return false}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{devToolsStorageKeys as
|
|
1
|
+
"use strict";import{devToolsStorageKeys as l,persistentStorage as o}from"@buoy-gg/shared-ui";import{addNetworkListener as b,getNetworkListenerCount as d,startNetworkListener as y,stopNetworkListener as h}from"../utils/networkListener";import{setOverrideHooks as g}from"./engine";import{isSpent as k}from"./resolveOverride";import{MAX_RULES as u,STATUS_MAX as S,STATUS_MIN as E}from"./types";import{realNow as c}from"../utils/realNow";const v=800;const A=3;function R(){const r=`${l.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 T=250;const x=["respond","fail","delay"];function f(r){if(!Array.isArray(r))return[];const t=[];for(const i of r){if(!i||typeof i!=="object")continue;const e=i;if(typeof e.id!=="string"||typeof e.urlPattern!=="string"){continue}if(!e.urlPattern)continue;const s=x.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,sandbox:e.sandbox===true?true:void 0,kind:s,status:typeof e.status==="number"?Math.min(S,Math.max(E,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 P{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,i=false){if(!this.remote)return;if(!i&&c()<this.remoteEchoUntil)return;this.enabled=t.enabled;this.rules=t.rules;this.rebuild();this.emit()}markLocalEdit(){if(this.remote)this.remoteEchoUntil=c()+v}disableEngine(){this.engineDisabled=true;if(this.keepAlive){this.keepAlive();this.keepAlive=null;if(d()===0)h()}}getState(){return this.state}getRules(){if(this.engineDisabled)return m;if(!this.enabled)return this.sandboxOnly();return this.rules}sandboxCache=null;sandboxOnly(){if(this.sandboxCache?.from!==this.rules){const t=this.rules.filter(i=>i.sandbox===true);this.sandboxCache={from:this.rules,rules:t.length?t:m}}return this.sandboxCache.rules}async fetchRuleBody(t){const i=this.rules.find(e=>e.id===t);if(!i)return null;if(!i.bodyOmitted)return i.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&&!k(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 i={...t,id:`ovr_${Date.now().toString(36)}_${++this.idCounter}`,hits:0,seen:0,createdAt:Date.now()};this.commit([i,...this.rules]);return i}upsertRule(t){this.remote?.upsertRule(t);this.markLocalEdit();this.markTouched();const{id:i,...e}=t;if(i&&this.rules.some(s=>s.id===i)){this.updateRule(i,e);return this.rules.find(s=>s.id===i)??null}return this.addRule(e)}replaceAllRules(t,i){if(this.remote)return null;this.markTouched();const e=t.map(s=>s&&typeof s==="object"&&typeof s.id==="string"?s:{...s,id:`ovr_${Date.now().toString(36)}_${++this.idCounter}`,createdAt:Date.now()});this.enabled=i;this.commit(f(e));return this.rules.slice()}updateRule(t,i){const e=this.rules.findIndex(n=>n.id===t);if(e===-1)return;const s=[...this.rules];s[e]={...s[e],...i,hits:0,seen:0};this.commit(s)}setRuleEnabled(t,i){const e=this.rules.findIndex(n=>n.id===t);if(e===-1||this.rules[e].enabled===i)return;this.remote?.setRuleEnabled(t,i);this.markLocalEdit();this.markTouched();const s=[...this.rules];s[e]={...s[e],enabled:i,hits:i?0:s[e].hits,seen:i?0:s[e].seen};this.commit(s)}removeRule(t){const i=this.rules.filter(e=>e.id!==t);if(i.length===this.rules.length)return;this.remote?.removeRule(t);this.markLocalEdit();this.markTouched();this.commit(i)}clearRules(){if(this.rules.length===0)return;this.remote?.clearRules();this.markLocalEdit();this.markTouched();this.commit([])}recordMatch(t){const i=this.rules.findIndex(s=>s.id===t);if(i===-1)return;const e=[...this.rules];e[i]={...e[i],seen:e[i].seen+1};this.rules=e;this.rebuild()}recordHit(t){const i=this.rules.findIndex(p=>p.id===t);if(i===-1)return;const e=this.rules[i];const s=e.hits+1;const n=typeof e.times==="number"&&s>=e.times;const a=[...this.rules];a[i]={...e,hits:s,enabled:n?false:e.enabled};if(n){this.commit(a);return}this.rules=a;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 o.getItem(l.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(l.network.overrides())??null}catch{return}if(t===null)return;this.hydrate(t)}hydrate(t){try{if(t&&!this.dirty){const i=JSON.parse(t);this.enabled=i?.enabled!==false;this.rules=f(i?.rules);this.launchStreak=typeof i?.launchStreak==="number"?i.launchStreak:0;this.autoPaused=i?.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(R())return;this.launchStreak+=1;if(this.launchStreak>=A){this.enabled=false;this.autoPaused=true;this.launchStreak=0}this.persist()}syncKeepAlive(){const t=!this.engineDisabled&&this.activeCount()>0;if(t&&!this.keepAlive){y();this.keepAlive=b(()=>{});return}if(!t&&this.keepAlive){this.keepAlive();this.keepAlive=null;if(d()===0)h()}}scheduleHitEmit(){if(this.hitEmitTimer!==null)return;this.hitEmitTimer=setTimeout(()=>{this.hitEmitTimer=null;this.emit()},T)}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()}persist(){if(this.remote)return;o.setItem(l.network.overrides(),JSON.stringify({enabled:this.enabled,rules:this.rules,launchStreak:this.launchStreak,autoPaused:this.autoPaused})).catch(()=>{})}emit(){this.listeners.forEach(t=>t())}}export const overrideRulesStore=new P;g({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()}
|
|
@@ -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 f}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 L,isNetworkListening as P}from"../utils/networkListener";import{MAX_RULES as R}from"../overrides/types";import{approxJsonSize as m,isOverWireBudget as M}from"@buoy-gg/shared-ui";import{expandKeyedArrays as _,patchFromPath as $,refusalText as J,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 M(e,SNAPSHOT_BODY_INLINE_LIMIT)}const I=new WeakMap;const A=new WeakMap;function k(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 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:m(u,SNAPSHOT_EVENTS_BUDGET).bytes}}function F(e){const t=A.get(e);if(t)return t;const{event:n}=k(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=k(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=>f.getEventById(e)??a.getEventById(e);const c=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(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,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,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 q=e=>!!e&&typeof e==="object"&&!Array.isArray(e);const y=e=>q(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(!q(e)||!q(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=w(e[s]);const p=w(d);if((l==="array"||l==="object")&&l!==p){r.breaks.push({path:u,from:l,to:p})}o[s]=D(e[s],d,u,r)}else{o[s]=d}}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:()=>{f.ensureInterception();return{conditions:v(),events:G(f.getEvents()),overrides:Y(i.getState()),saved:a.getRecords().map(e=>({...e,event:k(e.event).event}))}},subscribe:e=>{const t=f.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:()=>{f.clearEvents()},getEventBody:e=>{const t=c(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=c(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=c(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 d=r?.body??(typeof t.id==="string"?i.getState().rules.find(p=>p.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=$(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(l=>l.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."}}let u;try{const l=_(JSON.parse(d),t.bodyPatch);u=l.error;if(l.notes.length)t.bodyPatch=l.patch}catch{}if(u){return{ok:false,error:`Refused: ${u}`}}if(t.force!==true){const l=Z(t,d);if(l.length>0){return{ok:false,error:J(l,"response body",W(t.bodyPatch,l)),violations:l}}}}const o=Q(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=c(e);if(!t)return{ok:false,error:"Missing rule id."};i.setRuleEnabled(t,g(e,"enabled"));return{ok:true,...h()}},deleteOverrideRule:e=>{const t=c(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."};return{ok:true,count:n.length,enabled:i.getState().enabled,...h()}},listOverrideRules:async()=>{await i.ensureLoaded();return i.getState()},getOverrideRuleBody:e=>{const t=c(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=f.getSubscriberCounts().total;let t=null;let n=null;try{t=P();n=E()}catch{}let r=null;try{r=L()}catch{}return{capturing:e>0,subscribers:e,interceptorInstalled:t,interceptorLive:r,listenerCount:n,eventCount:f.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)
|