@buoy-gg/impersonate 7.0.63 → 7.0.64
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/lib/commonjs/impersonate/components/ImpersonateBanner.js +1 -1
- package/lib/commonjs/impersonate/utils/impersonateStore.js +1 -1
- package/lib/commonjs/preset.js +1 -1
- package/lib/module/impersonate/components/ImpersonateBanner.js +1 -1
- package/lib/module/impersonate/utils/impersonateStore.js +1 -1
- package/lib/module/preset.js +1 -1
- package/lib/web/index.mjs +8 -8
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImpersonateBanner=ImpersonateBanner;exports.ImpersonateBannerMinimal=ImpersonateBannerMinimal;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _impersonateStore=require("../utils/impersonateStore");var _UserAvatar=require("./UserAvatar");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,a){if("function"==typeof WeakMap)var l=new WeakMap,i=new WeakMap;return(_interopRequireWildcard=function(e,c){if(!c&&e&&e.__esModule)return e;var t,o,r={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return r;if(t=c?i:l){if(t.has(e))return t.get(e);t.set(e,r)}for(const s in e)"default"!==s&&{}.hasOwnProperty.call(e,s)&&((o=(t=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,s))&&(o.get||o.set)?t(r,s,o):r[s]=e[s]);return r})(n,a)}function ImpersonateBanner({onPress:n,onStopPress:a,position:l="top",offset:i=50}){const e=(0,_react.useSyncExternalStore)(_impersonateStore.impersonateStore.subscribe,_impersonateStore.impersonateStore.getSnapshot,_impersonateStore.impersonateStore.getSnapshot);if(!e.isActive||!e.currentUser||!e.showBanner){return null}const c=async()=>{console.log("[impersonate] banner pause/resume pressed");if(e.isPaused){await _impersonateStore.impersonateStore.resumeImpersonation()}else{await _impersonateStore.impersonateStore.pauseImpersonation()}};const t=e.currentUser.displayName||e.currentUser.email||e.currentUser.id;const o=l==="top"?{top:i}:{bottom:i};const r=async()=>{console.log("[impersonate] banner STOP pressed");await _impersonateStore.impersonateStore.stopImpersonation()};return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,o],children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.banner,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.userSection,onPress:n,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_UserAvatar.UserAvatar,{userId:e.currentUser.id,name:t,size:"small",showActiveIndicator:false}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.userName,e.isPaused&&styles.userNamePaused],numberOfLines:1,children:t})]}),(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:!e.isPaused,onToggle:c,size:"small",accessibilityLabel:"Toggle impersonation"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.closeButton,onPress:r,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}function ImpersonateBannerMinimal({onPress:n}){const a=(0,_react.useSyncExternalStore)(_impersonateStore.impersonateStore.subscribe,_impersonateStore.impersonateStore.getSnapshot,_impersonateStore.impersonateStore.getSnapshot);if(!a.isActive||!a.currentUser){return null}return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.minimalBanner,onPress:n,activeOpacity:.8,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.minimalDot}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.minimalText,children:"IMP"})]})}const styles=_reactNative.StyleSheet.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:_sharedUi.buoyColors.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:_sharedUi.buoyColors.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:_sharedUi.buoyColors.success},minimalText:{fontSize:10,fontWeight:"700",color:_sharedUi.buoyColors.success,letterSpacing:.5}});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImpersonateBanner=ImpersonateBanner;exports.ImpersonateBannerMinimal=ImpersonateBannerMinimal;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _impersonateStore=require("../utils/impersonateStore");var _UserAvatar=require("./UserAvatar");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,a){if("function"==typeof WeakMap)var l=new WeakMap,i=new WeakMap;return(_interopRequireWildcard=function(e,c){if(!c&&e&&e.__esModule)return e;var t,o,r={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return r;if(t=c?i:l){if(t.has(e))return t.get(e);t.set(e,r)}for(const s in e)"default"!==s&&{}.hasOwnProperty.call(e,s)&&((o=(t=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,s))&&(o.get||o.set)?t(r,s,o):r[s]=e[s]);return r})(n,a)}function ImpersonateBanner({onPress:n,onStopPress:a,position:l="top",offset:i=50}){const e=(0,_react.useSyncExternalStore)(_impersonateStore.impersonateStore.subscribe,_impersonateStore.impersonateStore.getSnapshot,_impersonateStore.impersonateStore.getSnapshot);if(!e.isActive||!e.currentUser||!e.showBanner){return null}const c=async()=>{console.log("[Buoy]","[impersonate] banner pause/resume pressed");if(e.isPaused){await _impersonateStore.impersonateStore.resumeImpersonation()}else{await _impersonateStore.impersonateStore.pauseImpersonation()}};const t=e.currentUser.displayName||e.currentUser.email||e.currentUser.id;const o=l==="top"?{top:i}:{bottom:i};const r=async()=>{console.log("[Buoy]","[impersonate] banner STOP pressed");await _impersonateStore.impersonateStore.stopImpersonation()};return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,o],children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.banner,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.userSection,onPress:n,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_UserAvatar.UserAvatar,{userId:e.currentUser.id,name:t,size:"small",showActiveIndicator:false}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.userName,e.isPaused&&styles.userNamePaused],numberOfLines:1,children:t})]}),(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:!e.isPaused,onToggle:c,size:"small",accessibilityLabel:"Toggle impersonation"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.closeButton,onPress:r,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}function ImpersonateBannerMinimal({onPress:n}){const a=(0,_react.useSyncExternalStore)(_impersonateStore.impersonateStore.subscribe,_impersonateStore.impersonateStore.getSnapshot,_impersonateStore.impersonateStore.getSnapshot);if(!a.isActive||!a.currentUser){return null}return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.minimalBanner,onPress:n,activeOpacity:.8,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.minimalDot}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.minimalText,children:"IMP"})]})}const styles=_reactNative.StyleSheet.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:_sharedUi.buoyColors.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:_sharedUi.buoyColors.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:_sharedUi.buoyColors.success},minimalText:{fontSize:10,fontWeight:"700",color:_sharedUi.buoyColors.success,letterSpacing:.5}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.impersonateStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _impersonateListener=require("./impersonateListener");const STORAGE_KEY="@buoy/impersonate/state";const MAX_HISTORY=10;const DEFAULT_DATA_NUKE_SETTINGS={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};const DEFAULT_STATE={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:DEFAULT_DATA_NUKE_SETTINGS,showBanner:true,history:[]};let isNuking=false;const storage={getItem:i=>{try{if(typeof localStorage!=="undefined"){return localStorage.getItem(i)}return null}catch{return null}},setItem:(i,e)=>{try{if(typeof localStorage!=="undefined"){localStorage.setItem(i,e)}}catch{}},removeItem:i=>{try{if(typeof localStorage!=="undefined"){localStorage.removeItem(i)}}catch{}}};class ImpersonateStore{state={...DEFAULT_STATE};listeners=new Set;nukeCallbacks={};isInitialized=false;asyncStorageRef=null;storageReadyPromise=null;resolveStorageReady=null;developerDefaults=null;constructor(){this.loadFromStorage();Promise.resolve().then(()=>{let e=false;const t=()=>{const s=(0,_sharedUi.getAccountAccess)().status;if(s==="admitted")e=true;else if(s==="locked"&&e){e=false;this.disposeAccountSession()}};(0,_sharedUi.subscribeAccountAccess)(t);t()});if(typeof localStorage!=="undefined"){this.storageReadyPromise=Promise.resolve()}else{this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}}loadFromStorage(){try{const e=storage.getItem(STORAGE_KEY);const t=this.getEffectiveDefaults();if(e){const s=JSON.parse(e);this.state={...DEFAULT_STATE,headerKey:s.headerKey??t.headerKey,ignorePatterns:s.ignorePatterns??DEFAULT_STATE.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??t.showBanner,history:s.history??[],isActive:s.isActive??false,isPaused:s.isPaused??false,currentUser:s.currentUser??null};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}}else{this.state={...DEFAULT_STATE,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e;if(this.resolveStorageReady){this.resolveStorageReady();this.resolveStorageReady=null}}setDeveloperDefaults(e){this.developerDefaults=e;const t=this.getEffectiveDefaults();if(!this.isInitialized){this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??DEFAULT_STATE.headerKey,dataNukeSettings:{...DEFAULT_DATA_NUKE_SETTINGS,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??DEFAULT_STATE.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(!e)return;this.asyncStorageRef=e;try{const t=await e.getItem(STORAGE_KEY);console.log(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.impersonateStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _impersonateListener=require("./impersonateListener");const STORAGE_KEY="@buoy/impersonate/state";const MAX_HISTORY=10;const DEFAULT_DATA_NUKE_SETTINGS={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};const DEFAULT_STATE={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:DEFAULT_DATA_NUKE_SETTINGS,showBanner:true,history:[]};let isNuking=false;const storage={getItem:i=>{try{if(typeof localStorage!=="undefined"){return localStorage.getItem(i)}return null}catch{return null}},setItem:(i,e)=>{try{if(typeof localStorage!=="undefined"){localStorage.setItem(i,e)}}catch{}},removeItem:i=>{try{if(typeof localStorage!=="undefined"){localStorage.removeItem(i)}}catch{}}};class ImpersonateStore{state={...DEFAULT_STATE};listeners=new Set;nukeCallbacks={};isInitialized=false;asyncStorageRef=null;storageReadyPromise=null;resolveStorageReady=null;developerDefaults=null;constructor(){this.loadFromStorage();Promise.resolve().then(()=>{let e=false;const t=()=>{const s=(0,_sharedUi.getAccountAccess)().status;if(s==="admitted")e=true;else if(s==="locked"&&e){e=false;this.disposeAccountSession()}};(0,_sharedUi.subscribeAccountAccess)(t);t()});if(typeof localStorage!=="undefined"){this.storageReadyPromise=Promise.resolve()}else{this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}}loadFromStorage(){try{const e=storage.getItem(STORAGE_KEY);const t=this.getEffectiveDefaults();if(e){const s=JSON.parse(e);this.state={...DEFAULT_STATE,headerKey:s.headerKey??t.headerKey,ignorePatterns:s.ignorePatterns??DEFAULT_STATE.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??t.showBanner,history:s.history??[],isActive:s.isActive??false,isPaused:s.isPaused??false,currentUser:s.currentUser??null};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}}else{this.state={...DEFAULT_STATE,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e;if(this.resolveStorageReady){this.resolveStorageReady();this.resolveStorageReady=null}}setDeveloperDefaults(e){this.developerDefaults=e;const t=this.getEffectiveDefaults();if(!this.isInitialized){this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??DEFAULT_STATE.headerKey,dataNukeSettings:{...DEFAULT_DATA_NUKE_SETTINGS,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??DEFAULT_STATE.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(!e)return;this.asyncStorageRef=e;try{const t=await e.getItem(STORAGE_KEY);console.log("[Buoy]",`[impersonate] initializeAsync read STORAGE_KEY=${STORAGE_KEY} stored=${t?t.slice(0,200):"null"}`);if(t){const s=JSON.parse(t);this.state={...this.state,headerKey:s.headerKey??this.state.headerKey,ignorePatterns:s.ignorePatterns??this.state.ignorePatterns,dataNukeSettings:{...this.state.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??this.state.showBanner,history:s.history??this.state.history,isActive:s.isActive??this.state.isActive,isPaused:s.isPaused??this.state.isPaused,currentUser:s.currentUser??this.state.currentUser};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}this.notify()}}catch{}}registerNukeCallbacks(e){this.nukeCallbacks={...this.nukeCallbacks,...e}}getState(){return{...this.state}}getSnapshot=()=>{return this.state};subscribe=e=>{this.listeners.add(e);return()=>this.listeners.delete(e)};remoteHandler=null;setRemoteHandler(e){this.remoteHandler=e}replaceState(e){this.state=e;this.notify()}async startImpersonation(e){(0,_sharedUi.assertAccountAccess)();if(this.remoteHandler){this.remoteHandler("startImpersonation",{user:e});return}const t={user:e,lastUsedAt:new Date().toISOString()};const s=[t,...this.state.history.filter(a=>a.user.id!==e.id)].slice(0,MAX_HISTORY);this.state={...this.state,isActive:true,currentUser:e,history:s};this.syncWithListener();this.notify();await this.executeDataNuke();await this.persist()}async stopImpersonation(){if(this.remoteHandler){this.remoteHandler("stopImpersonation");return}console.log("[Buoy]",`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`);this.state={...this.state,isActive:false,isPaused:false,currentUser:null};this.syncWithListener();this.notify();await this.executeDataNuke();await this.persist()}async pauseImpersonation(){if(this.remoteHandler){this.remoteHandler("pauseImpersonation");return}if(!this.state.isActive||this.state.isPaused)return;this.state={...this.state,isPaused:true};this.syncWithListener();await this.persist();this.notify()}async resumeImpersonation(){(0,_sharedUi.assertAccountAccess)();if(this.remoteHandler){this.remoteHandler("resumeImpersonation");return}if(!this.state.isActive||!this.state.isPaused)return;this.state={...this.state,isPaused:false};this.syncWithListener();await this.persist();this.notify()}async quickSwitch(e){return this.startImpersonation(e)}async updateSettings(e){if(this.remoteHandler){this.remoteHandler("updateSettings",{settings:e});return}this.state={...this.state,headerKey:e.headerKey??this.state.headerKey,ignorePatterns:e.ignorePatterns??this.state.ignorePatterns,showBanner:e.showBanner??this.state.showBanner,dataNukeSettings:e.dataNukeSettings?{...this.state.dataNukeSettings,...e.dataNukeSettings}:this.state.dataNukeSettings};if(e.headerKey||e.ignorePatterns){this.syncWithListener()}await this.persist();this.notify()}async removeFromHistory(e){if(this.remoteHandler){this.remoteHandler("removeFromHistory",{userId:e});return}this.state={...this.state,history:this.state.history.filter(t=>t.user.id!==e)};await this.persist();this.notify()}async clearHistory(){if(this.remoteHandler){this.remoteHandler("clearHistory");return}this.state={...this.state,history:[]};await this.persist();this.notify()}async executeDataNuke(){if(isNuking){return}isNuking=true;try{const{dataNukeSettings:e}=this.state;const t=[];if(e.reactQuery&&this.nukeCallbacks.reactQuery){t.push(Promise.resolve(this.nukeCallbacks.reactQuery()))}if(e.redux&&this.nukeCallbacks.redux){t.push(Promise.resolve(this.nukeCallbacks.redux()))}if(e.asyncStorage&&this.nukeCallbacks.asyncStorage){t.push(Promise.resolve(this.nukeCallbacks.asyncStorage()))}if(e.mmkv&&this.nukeCallbacks.mmkv){t.push(Promise.resolve(this.nukeCallbacks.mmkv()))}await Promise.allSettled(t)}finally{setTimeout(()=>{isNuking=false},100)}}disposeAccountSession(){if(this.remoteHandler||!this.state.isActive)return;this.state={...this.state,isActive:false,isPaused:false,currentUser:null};this.syncWithListener();this.notify();void this.persist()}syncWithListener(){const e=this.state.isActive&&!this.state.isPaused;(0,_impersonateListener.setImpersonateConfig)({headerKey:this.state.headerKey,userId:e?this.state.currentUser?.id??null:null,ignorePatterns:this.state.ignorePatterns.map(t=>new RegExp(t)),gate:_sharedUi.hasAccountAccess});if(!(0,_impersonateListener.impersonateListener)().isListening){(0,_impersonateListener.impersonateListener)().startListening()}}async persist(){if(this.storageReadyPromise){await this.storageReadyPromise}const e={headerKey:this.state.headerKey,ignorePatterns:this.state.ignorePatterns,dataNukeSettings:this.state.dataNukeSettings,showBanner:this.state.showBanner,history:this.state.history,isActive:this.state.isActive,isPaused:this.state.isPaused,currentUser:this.state.currentUser};const t=JSON.stringify(e);try{if(this.asyncStorageRef){await this.asyncStorageRef.setItem(STORAGE_KEY,t);console.log("[Buoy]",`[impersonate] persist -> AsyncStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)}else{storage.setItem(STORAGE_KEY,t);console.log("[Buoy]",`[impersonate] persist -> localStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)}}catch(s){console.warn("[Buoy]","[impersonate] persist failed",s)}}notify(){this.listeners.forEach(e=>{try{e(this.state)}catch{}})}}const impersonateStore=exports.impersonateStore=new ImpersonateStore;
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"IMPERSONATE_ICON_COLOR",{enumerable:true,get:function(){return _sharedUi.IMPERSONATE_ICON_COLOR}});Object.defineProperty(exports,"ImpersonateIcon",{enumerable:true,get:function(){return _sharedUi.ImpersonateIcon}});exports.createImpersonateTool=createImpersonateTool;var _asyncStoragePeer=require("./impersonate/hooks/asyncStoragePeer");var _react=_interopRequireDefault(require("react"));var _ImpersonateModal=require("./impersonate/components/ImpersonateModal");var _ImpersonateBanner=require("./impersonate/components/ImpersonateBanner");var _impersonateStore=require("./impersonate/utils/impersonateStore");var _impersonateListener=require("./impersonate/utils/impersonateListener");var _impersonateSyncAdapter=require("./sync/impersonateSyncAdapter");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}let bootstrapStarted=false;async function bootstrapImpersonate(){if(typeof window==="undefined"||bootstrapStarted)return;bootstrapStarted=true;console.log("[impersonate] bootstrap: start");if(!(0,_impersonateListener.impersonateListener)().isListening){(0,_impersonateListener.impersonateListener)().startListening()}try{const e=(0,_asyncStoragePeer.getAsyncStorage)();if(!e||typeof e.getItem!=="function"){console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(e??{}));return}const t={getItem:r=>e.getItem(r),setItem:(r,n)=>e.setItem(r,n)};_impersonateStore.impersonateStore.setAsyncStorage(t);console.log("[impersonate] bootstrap: AsyncStorage adapter installed");await _impersonateStore.impersonateStore.initializeAsync(t);console.log("[impersonate] bootstrap: initializeAsync done")}catch(e){console.warn("[impersonate] bootstrap: failed",e)}}function createImpersonateTool(e){const{id:t="impersonate",name:r="IMPERSONATE",description:n="User impersonation for admin testing",defaults:a,showSettingsTab:i=true,onSearchUsers:s,onClearReactQuery:p,onClearRedux:c,onClearAsyncStorage:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"IMPERSONATE_ICON_COLOR",{enumerable:true,get:function(){return _sharedUi.IMPERSONATE_ICON_COLOR}});Object.defineProperty(exports,"ImpersonateIcon",{enumerable:true,get:function(){return _sharedUi.ImpersonateIcon}});exports.createImpersonateTool=createImpersonateTool;var _asyncStoragePeer=require("./impersonate/hooks/asyncStoragePeer");var _react=_interopRequireDefault(require("react"));var _ImpersonateModal=require("./impersonate/components/ImpersonateModal");var _ImpersonateBanner=require("./impersonate/components/ImpersonateBanner");var _impersonateStore=require("./impersonate/utils/impersonateStore");var _impersonateListener=require("./impersonate/utils/impersonateListener");var _impersonateSyncAdapter=require("./sync/impersonateSyncAdapter");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}let bootstrapStarted=false;async function bootstrapImpersonate(){if(typeof window==="undefined"||bootstrapStarted)return;bootstrapStarted=true;console.log("[Buoy]","[impersonate] bootstrap: start");if(!(0,_impersonateListener.impersonateListener)().isListening){(0,_impersonateListener.impersonateListener)().startListening()}try{const e=(0,_asyncStoragePeer.getAsyncStorage)();if(!e||typeof e.getItem!=="function"){console.warn("[Buoy]","[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(e??{}));return}const t={getItem:r=>e.getItem(r),setItem:(r,n)=>e.setItem(r,n)};_impersonateStore.impersonateStore.setAsyncStorage(t);console.log("[Buoy]","[impersonate] bootstrap: AsyncStorage adapter installed");await _impersonateStore.impersonateStore.initializeAsync(t);console.log("[Buoy]","[impersonate] bootstrap: initializeAsync done")}catch(e){console.warn("[Buoy]","[impersonate] bootstrap: failed",e)}}function createImpersonateTool(e){const{id:t="impersonate",name:r="IMPERSONATE",description:n="User impersonation for admin testing",defaults:a,showSettingsTab:i=true,onSearchUsers:s,onClearReactQuery:p,onClearRedux:c,onClearAsyncStorage:u,onClearMMKV:m}=e;if(a){_impersonateStore.impersonateStore.setDeveloperDefaults(a)}(0,_impersonateSyncAdapter.registerImpersonateSearchUsers)(s??null);void bootstrapImpersonate();const l={id:t,name:r,description:n,slot:"both",icon:({size:o,slot:d})=>(0,_jsxRuntime.jsx)(_sharedUi.ImpersonateIcon,{size:d==="dial"?o*1.5:o,color:_sharedUi.IMPERSONATE_ICON_COLOR}),component:o=>(0,_jsxRuntime.jsx)(_ImpersonateModal.ImpersonateModal,{...o,onSearchUsers:s,onClearReactQuery:p,onClearRedux:c,onClearAsyncStorage:u,onClearMMKV:m,showSettingsTab:i}),props:{enableSharedModalDimensions:false},Banner:_ImpersonateBanner.ImpersonateBanner};return l}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import P,{useSyncExternalStore as m}from"react";import{View as a,Text as p,TouchableOpacity as l,StyleSheet as y}from"react-native";import{buoyColors as s,X as w,PowerToggleButton as S}from"@buoy-gg/shared-ui";import{impersonateStore as t}from"../utils/impersonateStore";import{UserAvatar as x}from"./UserAvatar";import{jsx as r,jsxs as c}from"react/jsx-runtime";export function ImpersonateBanner({onPress:n,onStopPress:i,position:g="top",offset:d=50}){const e=m(t.subscribe,t.getSnapshot,t.getSnapshot);if(!e.isActive||!e.currentUser||!e.showBanner){return null}const h=async()=>{console.log("[impersonate] banner pause/resume pressed");if(e.isPaused){await t.resumeImpersonation()}else{await t.pauseImpersonation()}};const u=e.currentUser.displayName||e.currentUser.email||e.currentUser.id;const b=g==="top"?{top:d}:{bottom:d};const f=async()=>{console.log("[impersonate] banner STOP pressed");await t.stopImpersonation()};return r(a,{style:[o.container,b],children:c(a,{style:o.banner,children:[c(l,{style:o.userSection,onPress:n,activeOpacity:.7,children:[r(x,{userId:e.currentUser.id,name:u,size:"small",showActiveIndicator:false}),r(p,{style:[o.userName,e.isPaused&&o.userNamePaused],numberOfLines:1,children:u})]}),r(S,{isEnabled:!e.isPaused,onToggle:h,size:"small",accessibilityLabel:"Toggle impersonation"}),r(l,{style:o.closeButton,onPress:f,activeOpacity:.7,children:r(w,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}export function ImpersonateBannerMinimal({onPress:n}){const i=m(t.subscribe,t.getSnapshot,t.getSnapshot);if(!i.isActive||!i.currentUser){return null}return c(l,{style:o.minimalBanner,onPress:n,activeOpacity:.8,children:[r(a,{style:o.minimalDot}),r(p,{style:o.minimalText,children:"IMP"})]})}const o=y.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:s.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:s.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:s.success},minimalText:{fontSize:10,fontWeight:"700",color:s.success,letterSpacing:.5}});
|
|
1
|
+
"use strict";import P,{useSyncExternalStore as m}from"react";import{View as a,Text as p,TouchableOpacity as l,StyleSheet as y}from"react-native";import{buoyColors as s,X as w,PowerToggleButton as S}from"@buoy-gg/shared-ui";import{impersonateStore as t}from"../utils/impersonateStore";import{UserAvatar as x}from"./UserAvatar";import{jsx as r,jsxs as c}from"react/jsx-runtime";export function ImpersonateBanner({onPress:n,onStopPress:i,position:g="top",offset:d=50}){const e=m(t.subscribe,t.getSnapshot,t.getSnapshot);if(!e.isActive||!e.currentUser||!e.showBanner){return null}const h=async()=>{console.log("[Buoy]","[impersonate] banner pause/resume pressed");if(e.isPaused){await t.resumeImpersonation()}else{await t.pauseImpersonation()}};const u=e.currentUser.displayName||e.currentUser.email||e.currentUser.id;const b=g==="top"?{top:d}:{bottom:d};const f=async()=>{console.log("[Buoy]","[impersonate] banner STOP pressed");await t.stopImpersonation()};return r(a,{style:[o.container,b],children:c(a,{style:o.banner,children:[c(l,{style:o.userSection,onPress:n,activeOpacity:.7,children:[r(x,{userId:e.currentUser.id,name:u,size:"small",showActiveIndicator:false}),r(p,{style:[o.userName,e.isPaused&&o.userNamePaused],numberOfLines:1,children:u})]}),r(S,{isEnabled:!e.isPaused,onToggle:h,size:"small",accessibilityLabel:"Toggle impersonation"}),r(l,{style:o.closeButton,onPress:f,activeOpacity:.7,children:r(w,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}export function ImpersonateBannerMinimal({onPress:n}){const i=m(t.subscribe,t.getSnapshot,t.getSnapshot);if(!i.isActive||!i.currentUser){return null}return c(l,{style:o.minimalBanner,onPress:n,activeOpacity:.8,children:[r(a,{style:o.minimalDot}),r(p,{style:o.minimalText,children:"IMP"})]})}const o=y.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:s.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:s.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:s.success},minimalText:{fontSize:10,fontWeight:"700",color:s.success,letterSpacing:.5}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{assertAccountAccess as o,getAccountAccess as d,hasAccountAccess as y,subscribeAccountAccess as f}from"@buoy-gg/shared-ui";import{impersonateListener as h,setImpersonateConfig as m}from"./impersonateListener";const r="@buoy/impersonate/state";const g=10;const l={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};const a={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:l,showBanner:true,history:[]};let n=false;const c={getItem:i=>{try{if(typeof localStorage!=="undefined"){return localStorage.getItem(i)}return null}catch{return null}},setItem:(i,e)=>{try{if(typeof localStorage!=="undefined"){localStorage.setItem(i,e)}}catch{}},removeItem:i=>{try{if(typeof localStorage!=="undefined"){localStorage.removeItem(i)}}catch{}}};class p{state={...a};listeners=new Set;nukeCallbacks={};isInitialized=false;asyncStorageRef=null;storageReadyPromise=null;resolveStorageReady=null;developerDefaults=null;constructor(){this.loadFromStorage();Promise.resolve().then(()=>{let e=false;const t=()=>{const s=d().status;if(s==="admitted")e=true;else if(s==="locked"&&e){e=false;this.disposeAccountSession()}};f(t);t()});if(typeof localStorage!=="undefined"){this.storageReadyPromise=Promise.resolve()}else{this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}}loadFromStorage(){try{const e=c.getItem(r);const t=this.getEffectiveDefaults();if(e){const s=JSON.parse(e);this.state={...a,headerKey:s.headerKey??t.headerKey,ignorePatterns:s.ignorePatterns??a.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??t.showBanner,history:s.history??[],isActive:s.isActive??false,isPaused:s.isPaused??false,currentUser:s.currentUser??null};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}}else{this.state={...a,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e;if(this.resolveStorageReady){this.resolveStorageReady();this.resolveStorageReady=null}}setDeveloperDefaults(e){this.developerDefaults=e;const t=this.getEffectiveDefaults();if(!this.isInitialized){this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??a.headerKey,dataNukeSettings:{...l,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??a.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(!e)return;this.asyncStorageRef=e;try{const t=await e.getItem(r);console.log(
|
|
1
|
+
"use strict";import{assertAccountAccess as o,getAccountAccess as d,hasAccountAccess as y,subscribeAccountAccess as f}from"@buoy-gg/shared-ui";import{impersonateListener as h,setImpersonateConfig as m}from"./impersonateListener";const r="@buoy/impersonate/state";const g=10;const l={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};const a={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:l,showBanner:true,history:[]};let n=false;const c={getItem:i=>{try{if(typeof localStorage!=="undefined"){return localStorage.getItem(i)}return null}catch{return null}},setItem:(i,e)=>{try{if(typeof localStorage!=="undefined"){localStorage.setItem(i,e)}}catch{}},removeItem:i=>{try{if(typeof localStorage!=="undefined"){localStorage.removeItem(i)}}catch{}}};class p{state={...a};listeners=new Set;nukeCallbacks={};isInitialized=false;asyncStorageRef=null;storageReadyPromise=null;resolveStorageReady=null;developerDefaults=null;constructor(){this.loadFromStorage();Promise.resolve().then(()=>{let e=false;const t=()=>{const s=d().status;if(s==="admitted")e=true;else if(s==="locked"&&e){e=false;this.disposeAccountSession()}};f(t);t()});if(typeof localStorage!=="undefined"){this.storageReadyPromise=Promise.resolve()}else{this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}}loadFromStorage(){try{const e=c.getItem(r);const t=this.getEffectiveDefaults();if(e){const s=JSON.parse(e);this.state={...a,headerKey:s.headerKey??t.headerKey,ignorePatterns:s.ignorePatterns??a.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??t.showBanner,history:s.history??[],isActive:s.isActive??false,isPaused:s.isPaused??false,currentUser:s.currentUser??null};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}}else{this.state={...a,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e;if(this.resolveStorageReady){this.resolveStorageReady();this.resolveStorageReady=null}}setDeveloperDefaults(e){this.developerDefaults=e;const t=this.getEffectiveDefaults();if(!this.isInitialized){this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner}}}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??a.headerKey,dataNukeSettings:{...l,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??a.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(!e)return;this.asyncStorageRef=e;try{const t=await e.getItem(r);console.log("[Buoy]",`[impersonate] initializeAsync read STORAGE_KEY=${r} stored=${t?t.slice(0,200):"null"}`);if(t){const s=JSON.parse(t);this.state={...this.state,headerKey:s.headerKey??this.state.headerKey,ignorePatterns:s.ignorePatterns??this.state.ignorePatterns,dataNukeSettings:{...this.state.dataNukeSettings,...s.dataNukeSettings},showBanner:s.showBanner??this.state.showBanner,history:s.history??this.state.history,isActive:s.isActive??this.state.isActive,isPaused:s.isPaused??this.state.isPaused,currentUser:s.currentUser??this.state.currentUser};if(this.state.isActive&&this.state.currentUser){this.syncWithListener()}this.notify()}}catch{}}registerNukeCallbacks(e){this.nukeCallbacks={...this.nukeCallbacks,...e}}getState(){return{...this.state}}getSnapshot=()=>{return this.state};subscribe=e=>{this.listeners.add(e);return()=>this.listeners.delete(e)};remoteHandler=null;setRemoteHandler(e){this.remoteHandler=e}replaceState(e){this.state=e;this.notify()}async startImpersonation(e){o();if(this.remoteHandler){this.remoteHandler("startImpersonation",{user:e});return}const t={user:e,lastUsedAt:new Date().toISOString()};const s=[t,...this.state.history.filter(u=>u.user.id!==e.id)].slice(0,g);this.state={...this.state,isActive:true,currentUser:e,history:s};this.syncWithListener();this.notify();await this.executeDataNuke();await this.persist()}async stopImpersonation(){if(this.remoteHandler){this.remoteHandler("stopImpersonation");return}console.log("[Buoy]",`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`);this.state={...this.state,isActive:false,isPaused:false,currentUser:null};this.syncWithListener();this.notify();await this.executeDataNuke();await this.persist()}async pauseImpersonation(){if(this.remoteHandler){this.remoteHandler("pauseImpersonation");return}if(!this.state.isActive||this.state.isPaused)return;this.state={...this.state,isPaused:true};this.syncWithListener();await this.persist();this.notify()}async resumeImpersonation(){o();if(this.remoteHandler){this.remoteHandler("resumeImpersonation");return}if(!this.state.isActive||!this.state.isPaused)return;this.state={...this.state,isPaused:false};this.syncWithListener();await this.persist();this.notify()}async quickSwitch(e){return this.startImpersonation(e)}async updateSettings(e){if(this.remoteHandler){this.remoteHandler("updateSettings",{settings:e});return}this.state={...this.state,headerKey:e.headerKey??this.state.headerKey,ignorePatterns:e.ignorePatterns??this.state.ignorePatterns,showBanner:e.showBanner??this.state.showBanner,dataNukeSettings:e.dataNukeSettings?{...this.state.dataNukeSettings,...e.dataNukeSettings}:this.state.dataNukeSettings};if(e.headerKey||e.ignorePatterns){this.syncWithListener()}await this.persist();this.notify()}async removeFromHistory(e){if(this.remoteHandler){this.remoteHandler("removeFromHistory",{userId:e});return}this.state={...this.state,history:this.state.history.filter(t=>t.user.id!==e)};await this.persist();this.notify()}async clearHistory(){if(this.remoteHandler){this.remoteHandler("clearHistory");return}this.state={...this.state,history:[]};await this.persist();this.notify()}async executeDataNuke(){if(n){return}n=true;try{const{dataNukeSettings:e}=this.state;const t=[];if(e.reactQuery&&this.nukeCallbacks.reactQuery){t.push(Promise.resolve(this.nukeCallbacks.reactQuery()))}if(e.redux&&this.nukeCallbacks.redux){t.push(Promise.resolve(this.nukeCallbacks.redux()))}if(e.asyncStorage&&this.nukeCallbacks.asyncStorage){t.push(Promise.resolve(this.nukeCallbacks.asyncStorage()))}if(e.mmkv&&this.nukeCallbacks.mmkv){t.push(Promise.resolve(this.nukeCallbacks.mmkv()))}await Promise.allSettled(t)}finally{setTimeout(()=>{n=false},100)}}disposeAccountSession(){if(this.remoteHandler||!this.state.isActive)return;this.state={...this.state,isActive:false,isPaused:false,currentUser:null};this.syncWithListener();this.notify();void this.persist()}syncWithListener(){const e=this.state.isActive&&!this.state.isPaused;m({headerKey:this.state.headerKey,userId:e?this.state.currentUser?.id??null:null,ignorePatterns:this.state.ignorePatterns.map(t=>new RegExp(t)),gate:y});if(!h().isListening){h().startListening()}}async persist(){if(this.storageReadyPromise){await this.storageReadyPromise}const e={headerKey:this.state.headerKey,ignorePatterns:this.state.ignorePatterns,dataNukeSettings:this.state.dataNukeSettings,showBanner:this.state.showBanner,history:this.state.history,isActive:this.state.isActive,isPaused:this.state.isPaused,currentUser:this.state.currentUser};const t=JSON.stringify(e);try{if(this.asyncStorageRef){await this.asyncStorageRef.setItem(r,t);console.log("[Buoy]",`[impersonate] persist -> AsyncStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)}else{c.setItem(r,t);console.log("[Buoy]",`[impersonate] persist -> localStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)}}catch(s){console.warn("[Buoy]","[impersonate] persist failed",s)}}notify(){this.listeners.forEach(e=>{try{e(this.state)}catch{}})}}export const impersonateStore=new p;
|
package/lib/module/preset.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getAsyncStorage as A}from"./impersonate/hooks/asyncStoragePeer";import
|
|
1
|
+
"use strict";import{getAsyncStorage as A}from"./impersonate/hooks/asyncStoragePeer";import B from"react";import{ImpersonateModal as C}from"./impersonate/components/ImpersonateModal";import{ImpersonateBanner as h}from"./impersonate/components/ImpersonateBanner";import{impersonateStore as s}from"./impersonate/utils/impersonateStore";import{impersonateListener as p}from"./impersonate/utils/impersonateListener";import{registerImpersonateSearchUsers as M}from"./sync/impersonateSyncAdapter";let m=false;async function R(){if(typeof window==="undefined"||m)return;m=true;console.log("[Buoy]","[impersonate] bootstrap: start");if(!p().isListening){p().startListening()}try{const e=A();if(!e||typeof e.getItem!=="function"){console.warn("[Buoy]","[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(e??{}));return}const t={getItem:o=>e.getItem(o),setItem:(o,n)=>e.setItem(o,n)};s.setAsyncStorage(t);console.log("[Buoy]","[impersonate] bootstrap: AsyncStorage adapter installed");await s.initializeAsync(t);console.log("[Buoy]","[impersonate] bootstrap: initializeAsync done")}catch(e){console.warn("[Buoy]","[impersonate] bootstrap: failed",e)}}import{ImpersonateIcon as c,IMPERSONATE_ICON_COLOR as l}from"@buoy-gg/shared-ui";import{jsx as f}from"react/jsx-runtime";export{c as ImpersonateIcon,l as IMPERSONATE_ICON_COLOR};export function createImpersonateTool(e){const{id:t="impersonate",name:o="IMPERSONATE",description:n="User impersonation for admin testing",defaults:a,showSettingsTab:u=true,onSearchUsers:i,onClearReactQuery:d,onClearRedux:y,onClearAsyncStorage:g,onClearMMKV:S}=e;if(a){s.setDeveloperDefaults(a)}M(i??null);void R();const I={id:t,name:o,description:n,slot:"both",icon:({size:r,slot:b})=>f(c,{size:b==="dial"?r*1.5:r,color:l}),component:r=>f(C,{...r,onSearchUsers:i,onClearReactQuery:d,onClearRedux:y,onClearAsyncStorage:g,onClearMMKV:S,showSettingsTab:u}),props:{enableSharedModalDimensions:false},Banner:h};return I}
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use client";var tt=Object.defineProperty;var lr=Object.getOwnPropertyDescriptor;var cr=Object.getOwnPropertyNames;var dr=Object.prototype.hasOwnProperty;var ur=(e,t)=>{for(var r in t)tt(e,r,{get:t[r],enumerable:true})},rt=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of cr(t))!dr.call(e,o)&&o!==r&&tt(e,o,{get:()=>t[o],enumerable:!(a=lr(t,o))||a.enumerable});return e},hr=(e,t,r)=>(rt(e,t,"default"),r&&rt(r,t,"default"));var Va=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import ot from"@buoy-gg/shared-ui/web/asyncStorage";import{getCapacitorAppStorage as gr}from"@buoy-gg/shared-ui/web";function pr(){return ot}function mr(){return gr()??ot}import{useState as xe,useCallback as te,useRef as at,useEffect as nt}from"react";var it={};ur(it,{AccessibilityInfo:()=>br,ActivityIndicator:()=>ct,Alert:()=>mo,Animated:()=>vr,AppRegistry:()=>xr,AppState:()=>Cr,Appearance:()=>wr,BackHandler:()=>Ir,Button:()=>go,CheckBox:()=>Fr,Clipboard:()=>kr,DeviceEventEmitter:()=>to,Dimensions:()=>Tr,Easing:()=>Br,FlatList:()=>Ce,I18nManager:()=>Rr,Image:()=>Mr,ImageBackground:()=>Kr,InteractionManager:()=>Hr,Keyboard:()=>Ar,KeyboardAvoidingView:()=>jr,LayoutAnimation:()=>Pr,Linking:()=>zr,LogBox:()=>eo,Modal:()=>uo,NativeEventEmitter:()=>Dr,NativeModules:()=>Sr,PanResponder:()=>Lr,Picker:()=>Vr,PixelRatio:()=>Ur,Platform:()=>Nr,Pressable:()=>co,ProgressBar:()=>$r,RefreshControl:()=>Xr,SafeAreaView:()=>Qr,ScrollView:()=>lt,SectionList:()=>qr,Share:()=>Er,StatusBar:()=>_r,StyleSheet:()=>M,Switch:()=>ho,Text:()=>y,TextInput:()=>st,Touchable:()=>Jr,TouchableHighlight:()=>so,TouchableNativeFeedback:()=>Yr,TouchableOpacity:()=>H,TouchableWithoutFeedback:()=>lo,UIManager:()=>Or,Vibration:()=>Wr,View:()=>s,VirtualizedList:()=>Gr,YellowBox:()=>Zr,findNodeHandle:()=>po,unstable_createElement:()=>fr,useColorScheme:()=>ro,useLocaleContext:()=>oo,useWindowDimensions:()=>ao});hr(it,yr);import*as yr from"react-native-web";import{unstable_createElement as fr,NativeModules as Sr,AccessibilityInfo as br,Animated as vr,Appearance as wr,AppRegistry as xr,AppState as Cr,BackHandler as Ir,Clipboard as kr,Dimensions as Tr,Easing as Br,I18nManager as Rr,Keyboard as Ar,InteractionManager as Hr,LayoutAnimation as Pr,Linking as zr,NativeEventEmitter as Dr,PanResponder as Lr,PixelRatio as Ur,Platform as Nr,Share as Er,StyleSheet as M,UIManager as Or,Vibration as Wr,CheckBox as Fr,FlatList as Ce,Image as Mr,ImageBackground as Kr,KeyboardAvoidingView as jr,Picker as Vr,ProgressBar as $r,RefreshControl as Xr,SafeAreaView as Qr,SectionList as qr,StatusBar as _r,Touchable as Jr,TouchableNativeFeedback as Yr,VirtualizedList as Gr,YellowBox as Zr,LogBox as eo,DeviceEventEmitter as to,useColorScheme as ro,useLocaleContext as oo,useWindowDimensions as ao}from"react-native-web";import*as z from"react-native-web";import{createElement as no,forwardRef as io}from"react";function U(e){let t=io((a,o)=>{let{accessibilityState:c,accessibilityValue:i,...h}=a;for(let n of["busy","checked","disabled","expanded","selected"])c?.[n]!==void 0&&h[`aria-${n}`]===void 0&&(h[`aria-${n}`]=c[n]);for(let[n,d]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))i?.[n]!==void 0&&h[`aria-${d}`]===void 0&&(h[`aria-${d}`]=i[n]);return no(e,{...h,ref:o})}),r=e.State;return r&&Object.assign(t,{State:r}),t.displayName=e.displayName??e.name??"NativeWebView",t}var s=U(z.View),y=U(z.Text),st=U(z.TextInput),H=U(z.TouchableOpacity),so=U(z.TouchableHighlight),lo=U(z.TouchableWithoutFeedback),co=U(z.Pressable),lt=U(z.ScrollView),uo=U(z.Modal),ho=U(z.Switch),ct=U(z.ActivityIndicator),go=U(z.Button),po=z.findNodeHandle,mo={alert(e,t,r,a){if(typeof document>"u")return;let o=document.createElement("dialog");o.dataset.buoyRoot="",o.setAttribute("aria-label",e),o.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let c=document.createElement("h2");if(c.textContent=e,c.style.cssText="font-size:18px;margin:0 0 12px",o.appendChild(c),t){let d=document.createElement("p");d.textContent=t,d.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",o.appendChild(d)}let i=document.createElement("div");i.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let h=r?.length?r:[{text:"OK"}],n=()=>{o.close?.(),o.remove()};for(let d of h){let g=document.createElement("button");g.type="button",g.textContent=d.text??"OK",g.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${d.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,g.onclick=()=>{n(),d.onPress?.()},i.appendChild(g)}o.addEventListener("cancel",d=>{d.preventDefault(),a?.cancelable!==false&&(n(),a?.onDismiss?.())}),o.appendChild(i),document.body.appendChild(o),o.showModal?o.showModal():o.setAttribute("open","")}};import{JsModal as yo,TabSelector as fo,ModalHeader as re,buoyColors as So,night as dt,Search as bo,TickProvider as ut,windowDragProps as vo}from"@buoy-gg/shared-ui/web";import{useState as pe,useEffect as ht,useCallback as N,useSyncExternalStore as wo}from"react";import{assertAccountAccess as gt,getAccountAccess as xo,hasAccountAccess as Co,subscribeAccountAccess as Io}from"@buoy-gg/shared-ui/web";var pt=[/\/symbolicate$/,/\/logs$/,/\/debugger-proxy/,/\/reload$/,/\/launch-js-devtools/,/localhost:8081/,/100\.64\.\d+\.\d+:8081/,/10\.0\.\d+\.\d+:8081/,/\.hot-update\./,/__metro/];function Ie(e,t){for(let r of Object.keys(t))r.startsWith("__buoy")&&(e[r]=t[r])}var ko=class{constructor(){this.isListeningFlag=false;this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.reportHeader=e=>this.shouldInjectHeader(e)?{[this.config.headerKey]:this.config.userId}:null;this.originalFetch=globalThis.fetch.bind(globalThis),this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.config={headerKey:"x-impersonate-user-id",userId:null,ignorePatterns:[...pt]}}setConfig(e){this.config={...this.config,...e},e.ignorePatterns&&(this.config.ignorePatterns=[...pt,...e.ignorePatterns])}getConfig(){return{...this.config}}shouldInjectHeader(e){return!this.config.userId||this.config.gate&&!this.config.gate()?false:!this.config.ignorePatterns.some(t=>t.test(e))}extractUrl(e){return typeof e=="string"?e:e instanceof URL?e.href:e.url}startListening(){if(this.isListeningFlag)return;let e=globalThis.fetch,t=XMLHttpRequest.prototype.open,r=XMLHttpRequest.prototype.send;this.originalFetch=e.bind(globalThis),this.originalXHROpen=t,this.originalXHRSend=r;let a=this,o=async function(d,g){let w=a.extractUrl(d);if(a.shouldInjectHeader(w)){let x=g?.headers??(typeof d=="object"&&"headers"in d?d.headers:void 0),f=new Headers(x);return f.set(a.config.headerKey,a.config.userId),a.originalFetch(d,{...g,headers:f})}return a.originalFetch(d,g)};Ie(o,e),this.patchedFetch=o,globalThis.fetch=this.patchedFetch;let c=function(d,g,w=true,x,f){let C=this;C._impersonateUrl=typeof g=="string"?g:g.href;let I=typeof g=="string"?g:g.toString();return a.originalXHROpen.call(this,d,I,w,x,f)},i=function(d){let g=this;return g._impersonateUrl&&a.shouldInjectHeader(g._impersonateUrl)&&this.setRequestHeader(a.config.headerKey,a.config.userId),a.originalXHRSend.call(this,d)};Ie(c,t),Ie(i,r),this.patchedXHROpen=c,this.patchedXHRSend=i,XMLHttpRequest.prototype.open=this.patchedXHROpen,XMLHttpRequest.prototype.send=this.patchedXHRSend;let h=globalThis,n=h.__buoyHeaderInjectors??(h.__buoyHeaderInjectors=[]);n.includes(this.reportHeader)||n.push(this.reportHeader),this.isListeningFlag=true}stopListening(){if(!this.isListeningFlag)return;this.patchedFetch&&globalThis.fetch===this.patchedFetch&&(globalThis.fetch=this.originalFetch),this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend),this.patchedFetch=null,this.patchedXHROpen=null,this.patchedXHRSend=null;let e=globalThis.__buoyHeaderInjectors,t=e?.indexOf(this.reportHeader)??-1;e&&t>=0&&e.splice(t,1),this.isListeningFlag=false}get isListening(){return this.isListeningFlag}get isImpersonating(){return this.config.userId!==null&&(this.config.gate?.()??true)}},oe=null;function O(){return oe||(oe=new ko),oe}function To(){O().startListening()}function Bo(){O().stopListening()}function mt(e){O().setConfig(e)}function Ro(){return oe?.isImpersonating??false}function Ao(){return oe?.getConfig().userId??null}var ae="@buoy/impersonate/state",Ho=10,yt={reactQuery:true,redux:true,asyncStorage:false,mmkv:false},Z={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:yt,showBanner:true,history:[]},ke=false,ft={getItem:e=>{try{return typeof localStorage<"u"?localStorage.getItem(e):null}catch{return null}},setItem:(e,t)=>{try{typeof localStorage<"u"&&localStorage.setItem(e,t)}catch{}},removeItem:e=>{try{typeof localStorage<"u"&&localStorage.removeItem(e)}catch{}}},Po=class{constructor(){this.state={...Z};this.listeners=new Set;this.nukeCallbacks={};this.isInitialized=false;this.asyncStorageRef=null;this.storageReadyPromise=null;this.resolveStorageReady=null;this.developerDefaults=null;this.getSnapshot=()=>this.state;this.subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));this.remoteHandler=null;this.loadFromStorage(),Promise.resolve().then(()=>{let e=false,t=()=>{let r=xo().status;r==="admitted"?e=true:r==="locked"&&e&&(e=false,this.disposeAccountSession())};Io(t),t()}),typeof localStorage<"u"?this.storageReadyPromise=Promise.resolve():this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}loadFromStorage(){try{let e=ft.getItem(ae),t=this.getEffectiveDefaults();if(e){let r=JSON.parse(e);this.state={...Z,headerKey:r.headerKey??t.headerKey,ignorePatterns:r.ignorePatterns??Z.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...r.dataNukeSettings},showBanner:r.showBanner??t.showBanner,history:r.history??[],isActive:r.isActive??false,isPaused:r.isPaused??false,currentUser:r.currentUser??null},this.state.isActive&&this.state.currentUser&&this.syncWithListener()}else this.state={...Z,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner};this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e,this.resolveStorageReady&&(this.resolveStorageReady(),this.resolveStorageReady=null)}setDeveloperDefaults(e){this.developerDefaults=e;let t=this.getEffectiveDefaults();this.isInitialized||(this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner})}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??Z.headerKey,dataNukeSettings:{...yt,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??Z.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(e){this.asyncStorageRef=e;try{let t=await e.getItem(ae);if(console.log(`[impersonate] initializeAsync read STORAGE_KEY=${ae} stored=${t?t.slice(0,200):"null"}`),t){let r=JSON.parse(t);this.state={...this.state,headerKey:r.headerKey??this.state.headerKey,ignorePatterns:r.ignorePatterns??this.state.ignorePatterns,dataNukeSettings:{...this.state.dataNukeSettings,...r.dataNukeSettings},showBanner:r.showBanner??this.state.showBanner,history:r.history??this.state.history,isActive:r.isActive??this.state.isActive,isPaused:r.isPaused??this.state.isPaused,currentUser:r.currentUser??this.state.currentUser},this.state.isActive&&this.state.currentUser&&this.syncWithListener(),this.notify()}}catch{}}}registerNukeCallbacks(e){this.nukeCallbacks={...this.nukeCallbacks,...e}}getState(){return{...this.state}}setRemoteHandler(e){this.remoteHandler=e}replaceState(e){this.state=e,this.notify()}async startImpersonation(e){if(gt(),this.remoteHandler){this.remoteHandler("startImpersonation",{user:e});return}let t=[{user:e,lastUsedAt:new Date().toISOString()},...this.state.history.filter(r=>r.user.id!==e.id)].slice(0,Ho);this.state={...this.state,isActive:true,currentUser:e,history:t},this.syncWithListener(),this.notify(),await this.executeDataNuke(),await this.persist()}async stopImpersonation(){if(this.remoteHandler){this.remoteHandler("stopImpersonation");return}console.log(`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`),this.state={...this.state,isActive:false,isPaused:false,currentUser:null},this.syncWithListener(),this.notify(),await this.executeDataNuke(),await this.persist()}async pauseImpersonation(){if(this.remoteHandler){this.remoteHandler("pauseImpersonation");return}!this.state.isActive||this.state.isPaused||(this.state={...this.state,isPaused:true},this.syncWithListener(),await this.persist(),this.notify())}async resumeImpersonation(){if(gt(),this.remoteHandler){this.remoteHandler("resumeImpersonation");return}!this.state.isActive||!this.state.isPaused||(this.state={...this.state,isPaused:false},this.syncWithListener(),await this.persist(),this.notify())}async quickSwitch(e){return this.startImpersonation(e)}async updateSettings(e){if(this.remoteHandler){this.remoteHandler("updateSettings",{settings:e});return}this.state={...this.state,headerKey:e.headerKey??this.state.headerKey,ignorePatterns:e.ignorePatterns??this.state.ignorePatterns,showBanner:e.showBanner??this.state.showBanner,dataNukeSettings:e.dataNukeSettings?{...this.state.dataNukeSettings,...e.dataNukeSettings}:this.state.dataNukeSettings},(e.headerKey||e.ignorePatterns)&&this.syncWithListener(),await this.persist(),this.notify()}async removeFromHistory(e){if(this.remoteHandler){this.remoteHandler("removeFromHistory",{userId:e});return}this.state={...this.state,history:this.state.history.filter(t=>t.user.id!==e)},await this.persist(),this.notify()}async clearHistory(){if(this.remoteHandler){this.remoteHandler("clearHistory");return}this.state={...this.state,history:[]},await this.persist(),this.notify()}async executeDataNuke(){if(!ke){ke=true;try{let{dataNukeSettings:e}=this.state,t=[];e.reactQuery&&this.nukeCallbacks.reactQuery&&t.push(Promise.resolve(this.nukeCallbacks.reactQuery())),e.redux&&this.nukeCallbacks.redux&&t.push(Promise.resolve(this.nukeCallbacks.redux())),e.asyncStorage&&this.nukeCallbacks.asyncStorage&&t.push(Promise.resolve(this.nukeCallbacks.asyncStorage())),e.mmkv&&this.nukeCallbacks.mmkv&&t.push(Promise.resolve(this.nukeCallbacks.mmkv())),await Promise.allSettled(t)}finally{setTimeout(()=>{ke=false},100)}}}disposeAccountSession(){this.remoteHandler||!this.state.isActive||(this.state={...this.state,isActive:false,isPaused:false,currentUser:null},this.syncWithListener(),this.notify(),this.persist())}syncWithListener(){let e=this.state.isActive&&!this.state.isPaused;mt({headerKey:this.state.headerKey,userId:e?this.state.currentUser?.id??null:null,ignorePatterns:this.state.ignorePatterns.map(t=>new RegExp(t)),gate:Co}),O().isListening||O().startListening()}async persist(){this.storageReadyPromise&&await this.storageReadyPromise;let e={headerKey:this.state.headerKey,ignorePatterns:this.state.ignorePatterns,dataNukeSettings:this.state.dataNukeSettings,showBanner:this.state.showBanner,history:this.state.history,isActive:this.state.isActive,isPaused:this.state.isPaused,currentUser:this.state.currentUser},t=JSON.stringify(e);try{this.asyncStorageRef?(await this.asyncStorageRef.setItem(ae,t),console.log(`[impersonate] persist -> AsyncStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)):(ft.setItem(ae,t),console.log(`[impersonate] persist -> localStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`))}catch(r){console.warn("[impersonate] persist failed",r)}}notify(){this.listeners.forEach(e=>{try{e(this.state)}catch{}})}},p=new Po;function St(e={}){let[t,r]=pe(""),[a,o]=pe([]),[c,i]=pe(false),[h,n]=pe(null),d=wo(p.subscribe,p.getSnapshot,p.getSnapshot);ht(()=>{p.registerNukeCallbacks({reactQuery:e.onClearReactQuery,redux:e.onClearRedux,asyncStorage:e.onClearAsyncStorage,mmkv:e.onClearMMKV})},[e.onClearReactQuery,e.onClearRedux,e.onClearAsyncStorage,e.onClearMMKV]),ht(()=>{let S=true;return(async()=>{try{let b=await import("@buoy-gg/shared-ui/web/asyncStorage").then(F=>F.default),G={getItem:F=>b.getItem(F),setItem:(F,ve)=>b.setItem(F,ve)};p.setAsyncStorage(G),S&&await p.initializeAsync(G)}catch{}})(),O().isListening||O().startListening(),()=>{S=false}},[]);let g=N(async S=>{if(r(S),n(null),!S.trim()){o([]);return}if(!e.onSearchUsers){n("Search not configured"),o([]);return}i(true);try{let b=await e.onSearchUsers(S);o(b)}catch(b){n(b instanceof Error?b.message:"Search failed"),o([])}finally{i(false)}},[e.onSearchUsers]),w=N(()=>{r(""),o([]),n(null)},[]),x=N(async S=>{await p.startImpersonation(S)},[]),f=N(async()=>{await p.stopImpersonation()},[]),C=N(async S=>{await p.quickSwitch(S)},[]),I=N(async S=>{await p.updateSettings({headerKey:S})},[]),ge=N(async S=>{await p.updateSettings({ignorePatterns:S})},[]),X=N(async S=>{await p.updateSettings({dataNukeSettings:S})},[]),Y=N(async S=>{await p.updateSettings({showBanner:S})},[]),W=N(async S=>{await p.removeFromHistory(S)},[]),ee=N(async()=>{await p.clearHistory()},[]);return{isActive:d.isActive,currentUser:d.currentUser,headerKey:d.headerKey,ignorePatterns:d.ignorePatterns,dataNukeSettings:d.dataNukeSettings,showBanner:d.showBanner,history:d.history,searchQuery:t,searchResults:a,isSearching:c,searchError:h,searchUsers:g,clearSearch:w,startImpersonation:x,stopImpersonation:f,quickSwitch:C,updateHeaderKey:I,updateIgnorePatterns:ge,updateDataNukeSettings:X,updateShowBanner:Y,removeFromHistory:W,clearHistory:ee}}import{useCallback as zo}from"react";import{dispatchToolAction as bt,getToolAdapters as Do}from"@buoy-gg/shared-ui/web";function Lo(){let e=!!Do().query,t=zo(async()=>{await bt("query","clearQueryCache"),await bt("query","clearMutationCache")},[]);return{isAvailable:e,error:e?null:"Connect React Query to Buoy or provide onClearReactQuery.",clearCache:e?t:null}}import{useCallback as Uo}from"react";import{dispatchToolAction as No,getToolAdapters as Eo}from"@buoy-gg/shared-ui/web";var Oo="@@RESET";function Wo({resetActionType:e=Oo}={}){let t=!!Eo().redux,r=Uo(async()=>{await No("redux","dispatch",{action:{type:e}})},[e]);return{isAvailable:t,error:t?null:"Connect Redux to Buoy or provide onClearRedux.",resetStore:t?r:null}}import{isDevToolsStorageKey as Fo}from"@buoy-gg/shared-ui/web";import{useCallback as Mo,useMemo as Ko,useState as vt,useEffect as jo}from"react";var Te=false;function Vo(){let[e,t]=vt(null),[r,a]=vt(null);jo(()=>{let c=mr();c?(t(c),a(null)):a("@react-native-async-storage/async-storage is not installed")},[]);let o=Mo(async()=>{if(!Te){Te=true;try{if(e){let c=(await e.getAllKeys()).filter(i=>!Fo(i));c.length>0&&await e.multiRemove([...c])}}finally{setTimeout(()=>{Te=false},100)}}},[e]);return Ko(()=>!e||r?{isAvailable:false,error:r||"@react-native-async-storage/async-storage is not available",clearStorage:null}:{isAvailable:true,error:null,clearStorage:o},[e,r,o])}import{useCallback as $o}from"react";import{SectionHeader as Be,EmptyState as Xo,night as A,Search as Qo,AlertTriangle as wt,Users as qo}from"@buoy-gg/shared-ui/web";import{buoyColors as Re,night as D,Play as _o,X as Jo,PowerToggleButton as Yo,monoFont as Go}from"@buoy-gg/shared-ui/web";import{useMemo as xt}from"react";import{buoyColors as Zo,night as ea}from"@buoy-gg/shared-ui/web";import{jsx as Ae,jsxs as ta}from"react/jsx-runtime";var Ct=["#6366F1","#8B5CF6","#EC4899","#F43F5E","#F97316","#EAB308","#22C55E","#14B8A6","#06B6D4","#3B82F6"],ra={small:{container:24,font:10,indicator:8},medium:{container:36,font:14,indicator:10},large:{container:44,font:16,indicator:12}};function oa(e){if(!e)return"?";if(e.includes("@"))return e.charAt(0).toUpperCase();let t=e.trim().split(/\s+/);return t.length===1?t[0].charAt(0).toUpperCase():(t[0].charAt(0)+t[t.length-1].charAt(0)).toUpperCase()}function aa(e){let t=0;for(let r=0;r<e.length;r++)t=e.charCodeAt(r)+((t<<5)-t);return Ct[Math.abs(t)%Ct.length]}function He({userId:e,name:t,size:r="medium",showActiveIndicator:a=false,backgroundColor:o}){let c=ra[r],i=xt(()=>o??aa(e),[e,o]),h=xt(()=>oa(t),[t]);return ta(s,{style:me.wrapper,children:[Ae(s,{style:[me.container,{width:c.container,height:c.container,borderRadius:c.container/2,backgroundColor:i}],children:Ae(y,{style:[me.initials,{fontSize:c.font}],children:h})}),a&&Ae(s,{style:[me.indicator,{width:c.indicator,height:c.indicator,borderRadius:c.indicator/2,right:-1,bottom:-1}]})]})}var me=M.create({wrapper:{position:"relative"},container:{alignItems:"center",justifyContent:"center"},initials:{color:"#FFFFFF",fontWeight:"600",letterSpacing:.5},indicator:{position:"absolute",backgroundColor:Zo.success,borderWidth:2,borderColor:ea.color.surface}});import{jsx as L,jsxs as ne}from"react/jsx-runtime";function It({user:e,isActive:t=false,onPress:r,onStop:a,onRemove:o,showRemoveButton:c=false,lastUsedTime:i,variant:h="default"}){let n=e.displayName||e.email||e.id,d=e.email&&e.displayName,g=typeof e.metadata?.role=="string"?e.metadata.role:null;return ne(H,{testID:`buoy-impersonate-user-${e.id}`,style:[R.container,t&&R.activeContainer,h==="compact"&&R.compactContainer],onPress:r,disabled:t,activeOpacity:.7,children:[L(s,{style:R.avatarSection,children:L(He,{userId:e.id,name:n,size:h==="compact"?"small":"medium",showActiveIndicator:t})}),ne(s,{style:R.content,children:[ne(s,{style:R.nameRow,children:[L(y,{style:[R.name,t&&R.activeName],numberOfLines:1,children:n}),g?L(s,{style:R.roleBadge,children:L(y,{style:R.roleBadgeText,children:g.toUpperCase()})}):null]}),d&&L(y,{style:R.email,numberOfLines:1,children:e.email}),L(s,{style:R.metadataRow,children:ne(y,{style:R.userId,children:["ID: ",e.id]})})]}),ne(s,{style:R.actions,children:[t?L(Yo,{isEnabled:true,onToggle:a||(()=>{}),accessibilityLabel:"Stop impersonation"}):L(H,{style:R.actionButton,onPress:r,activeOpacity:.7,children:L(_o,{size:14,color:D.color.onAccent})}),c&&o&&!t&&L(H,{style:R.removeButton,onPress:o,activeOpacity:.7,children:L(Jo,{size:12,color:D.color.textTertiary})})]}),i?L(y,{style:R.lastUsed,children:i}):null]})}var R=M.create({container:{flexDirection:"row",alignItems:"center",backgroundColor:D.color.surface,borderRadius:10,borderWidth:1,borderColor:D.color.border,padding:12,gap:12},activeContainer:{backgroundColor:Re.success+"10",borderColor:Re.success+"40"},compactContainer:{padding:10,gap:10},avatarSection:{flexShrink:0},content:{flex:1,minWidth:0},nameRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:2},name:{fontSize:15,fontWeight:"600",color:D.color.text,flexShrink:1},activeName:{color:Re.success},roleBadge:{backgroundColor:D.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},roleBadgeText:{fontSize:9,fontWeight:"700",color:D.color.textTertiary,letterSpacing:.5},email:{fontSize:13,color:D.color.textSecondary,marginBottom:4},metadataRow:{flexDirection:"row",alignItems:"center",gap:4},userId:{fontSize:11,color:D.color.textTertiary,fontFamily:Go},lastUsed:{position:"absolute",bottom:8,right:10,fontSize:10,color:D.color.textTertiary},actions:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:0},actionButton:{width:36,height:36,borderRadius:8,backgroundColor:D.color.accent,alignItems:"center",justifyContent:"center"},removeButton:{width:28,height:28,borderRadius:6,backgroundColor:D.color.surfaceElevated,borderWidth:1,borderColor:D.color.border,alignItems:"center",justifyContent:"center"}});import{jsx as T,jsxs as K}from"react/jsx-runtime";function kt({currentUser:e,searchQuery:t,searchResults:r,isSearching:a,searchError:o,onSelectUser:c,onStopImpersonation:i,searchAvailable:h=true}){let n=$o(({item:d})=>{let g=e?.id===d.id;return T(It,{user:d,isActive:g,onPress:()=>!g&&c(d),onStop:g?i:void 0})},[e,c,i]);return K(s,{style:B.container,children:[!h&&T(s,{style:B.section,children:K(s,{style:B.warningCard,children:[T(wt,{size:18,color:A.color.warning}),K(s,{style:B.warningContent,children:[T(y,{style:B.warningTitle,children:"Search Not Available"}),T(y,{style:B.warningText,children:"Configure the onSearchUsers callback to enable user search."})]})]})}),a&&K(s,{style:B.loadingContainer,children:[T(ct,{size:"small",color:A.color.accent}),T(y,{style:B.loadingText,children:"Searching users..."})]}),o?T(s,{style:B.section,children:K(s,{style:B.errorCard,children:[T(wt,{size:16,color:A.color.danger}),T(y,{style:B.errorText,children:o})]})}):null,r.length>0&&K(s,{style:B.resultsSection,children:[K(Be,{children:[T(Be.Title,{children:"Results"}),T(Be.Badge,{count:r.length})]}),T(Ce,{data:r,keyExtractor:d=>d.id,renderItem:n,ItemSeparatorComponent:()=>T(s,{style:B.separator}),contentContainerStyle:B.listContent,showsVerticalScrollIndicator:false})]}),!!t&&!a&&r.length===0&&!o&&K(s,{style:B.emptyStateContainer,children:[T(s,{style:B.emptyStateIcon,children:T(qo,{size:28,color:A.color.textTertiary})}),T(y,{style:B.emptyStateTitle,children:"No users found"}),K(y,{style:B.emptyStateDescription,children:['No results for "',t,'"']}),T(y,{style:B.emptyStateHint,children:"Try a different search term"})]}),!t&&r.length===0&&!a&&h&&T(Xo,{title:"Search for users",description:"Tap the search icon in the header to find users by email, name, or ID",icon:Qo,variant:"minimal"})]})}var B=M.create({container:{flex:1},section:{padding:16,paddingBottom:8},loadingContainer:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10,paddingVertical:20},loadingText:{fontSize:13,color:A.color.textSecondary},resultsSection:{flex:1,paddingHorizontal:16},listContent:{paddingBottom:16},separator:{height:8},warningCard:{flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:A.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:A.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:14,fontWeight:"600",color:A.color.warning,marginBottom:4},warningText:{fontSize:13,color:A.color.textSecondary,lineHeight:18},errorCard:{flexDirection:"row",alignItems:"center",gap:10,backgroundColor:A.color.dangerSoft,borderRadius:10,borderWidth:1,borderColor:A.color.danger+"25",padding:12},errorText:{flex:1,fontSize:13,color:A.color.danger},emptyStateContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyStateIcon:{width:56,height:56,borderRadius:28,backgroundColor:A.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyStateTitle:{fontSize:16,fontWeight:"600",color:A.color.text,marginBottom:6},emptyStateDescription:{fontSize:14,color:A.color.textSecondary,textAlign:"center",marginBottom:8},emptyStateHint:{fontSize:12,color:A.color.textTertiary}});import{useCallback as na}from"react";import{night as Q,Trash2 as ia,useRelativeTime as sa,ToolEmptyState as la}from"@buoy-gg/shared-ui/web";import{jsx as E,jsxs as Tt}from"react/jsx-runtime";function ca({item:e,isActive:t,onSelect:r,onStop:a,onRemove:o,showRemoveButton:c}){let i=sa(new Date(e.lastUsedAt));return E(It,{user:e.user,isActive:t,onPress:()=>!t&&r(e.user),onStop:t?a:void 0,onRemove:o,showRemoveButton:c,lastUsedTime:i})}function Bt({history:e,currentUserId:t,onSelectUser:r,onStopImpersonation:a,onRemoveFromHistory:o,onClearHistory:c}){let i=na(({item:h})=>{let n=t===h.user.id;return E(ca,{item:h,isActive:n,onSelect:r,onStop:a,onRemove:o?()=>o(h.user.id):void 0,showRemoveButton:!!o})},[t,r,a,o]);return e.length===0?E(la,{testID:"buoy-impersonate-history-empty",otto:"disguise",title:"No History",message:"Users you impersonate will appear here for quick access"}):Tt(s,{style:j.container,children:[Tt(s,{style:j.headerRow,children:[E(y,{style:j.headerTitle,children:"Recent"}),E(s,{style:j.headerBadge,children:E(y,{style:j.headerBadgeText,children:e.length})}),E(s,{style:j.headerSpacer}),c&&E(H,{style:j.clearButton,onPress:c,activeOpacity:.7,children:E(ia,{size:12,color:Q.color.textTertiary})})]}),E(Ce,{data:e,keyExtractor:h=>h.user.id,renderItem:i,ItemSeparatorComponent:()=>E(s,{style:j.separator}),contentContainerStyle:j.listContent,showsVerticalScrollIndicator:false})]})}var j=M.create({container:{flex:1,paddingHorizontal:16},headerRow:{flexDirection:"row",alignItems:"center",paddingVertical:10,gap:8},headerTitle:{fontSize:12,fontWeight:"600",color:Q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},headerBadge:{backgroundColor:Q.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},headerBadgeText:{fontSize:10,fontWeight:"600",color:Q.color.textTertiary},headerSpacer:{flex:1},clearButton:{width:24,height:24,alignItems:"center",justifyContent:"center",backgroundColor:Q.color.surfaceElevated,borderRadius:4},listContent:{paddingBottom:20},separator:{height:8},emptyContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyIcon:{width:56,height:56,borderRadius:28,backgroundColor:Q.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyTitle:{fontSize:16,fontWeight:"600",color:Q.color.text,marginBottom:6},emptyDescription:{fontSize:14,color:Q.color.textSecondary,textAlign:"center"}});import{useState as ye,useEffect as Pe,useMemo as ze}from"react";import{CollapsibleSection as ie,buoyColors as se,night as m,Settings as da,AlertTriangle as Rt,Info as ua,Zap as ha,RefreshCw as ga,Check as De,X as At,Copy as Ht,Eye as pa,copyToClipboard as ma,ToggleRow as ya,monoFont as Le}from"@buoy-gg/shared-ui/web";import{DataViewer as fa}from"@buoy-gg/shared-ui/web/dataViewer";import{Fragment as Ue,jsx as u,jsxs as v}from"react/jsx-runtime";var le="x-impersonate-user-id",Ne=true,ce={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};function de({label:e,description:t,value:r,onChange:a,recommended:o,dangerous:c,detected:i}){let h=v(Ue,{children:[i!==void 0&&v(s,{style:[l.detectedBadge,i?l.detectedBadgeActive:l.detectedBadgeInactive],children:[i?u(De,{size:10,color:se.success}):u(At,{size:10,color:m.color.textTertiary}),u(y,{style:[l.detectedText,i?l.detectedTextActive:l.detectedTextInactive],children:i?"Detected":"Not Detected"})]}),o&&i!==false&&v(s,{style:l.recommendedBadge,children:[u(ha,{size:10,color:m.color.accent}),u(y,{style:l.recommendedText,children:"Recommended"})]})]});return u(ya,{variant:"plain",label:e,description:t,value:r,onValueChange:a,tone:c?"warning":"accent",emphasizeLabel:c,accessory:h})}function Pt({headerKey:e,settings:t,showBanner:r,onSave:a,onShowBannerChange:o,detectionStatus:c}){let[i,h]=ye(e),[n,d]=ye(t),[g,w]=ye(r),[x,f]=ye(false);Pe(()=>{h(e)},[e]),Pe(()=>{d(t)},[t]),Pe(()=>{w(r)},[r]);let C=ze(()=>i!==e||n.reactQuery!==t.reactQuery||n.redux!==t.redux||n.asyncStorage!==t.asyncStorage||n.mmkv!==t.mmkv,[i,n,e,t]),I=ze(()=>i===le&&g===Ne&&n.reactQuery===ce.reactQuery&&n.redux===ce.redux&&n.asyncStorage===ce.asyncStorage&&n.mmkv===ce.mmkv,[i,g,n]),ge=()=>{a(i.trim()||le,n,g)},X=()=>{h(e),d(t),w(r)},Y=()=>{h(le),d(ce),w(Ne),o(Ne)},W=(b,G)=>{d(F=>({...F,[b]:G}))},ee=ze(()=>({defaults:{headerKey:i,showBanner:g,dataNukeSettings:{reactQuery:n.reactQuery,redux:n.redux,asyncStorage:n.asyncStorage,mmkv:n.mmkv}}}),[i,g,n]),S=async()=>{let b=`defaults: {
|
|
2
|
-
headerKey: '${
|
|
3
|
-
showBanner: ${
|
|
1
|
+
"use client";var ot=Object.defineProperty;var pr=Object.getOwnPropertyDescriptor;var mr=Object.getOwnPropertyNames;var yr=Object.prototype.hasOwnProperty;var fr=(e,t)=>{for(var r in t)ot(e,r,{get:t[r],enumerable:true})},nt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of mr(t))!yr.call(e,o)&&o!==r&&ot(e,o,{get:()=>t[o],enumerable:!(n=pr(t,o))||n.enumerable});return e},br=(e,t,r)=>(nt(e,t,"default"),r&&nt(r,t,"default"));var oa=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import at from"@buoy-gg/shared-ui/web/asyncStorage";import{getCapacitorAppStorage as Sr}from"@buoy-gg/shared-ui/web";function vr(){return at}function wr(){return Sr()??at}import{useState as xe,useCallback as te,useRef as st,useEffect as it}from"react";var lt={};fr(lt,{AccessibilityInfo:()=>kr,ActivityIndicator:()=>mt,Alert:()=>Bo,Animated:()=>Tr,AppRegistry:()=>Rr,AppState:()=>Ar,Appearance:()=>Br,BackHandler:()=>Hr,Button:()=>ko,CheckBox:()=>Xr,Clipboard:()=>Pr,DeviceEventEmitter:()=>io,Dimensions:()=>zr,Easing:()=>Er,FlatList:()=>Ie,I18nManager:()=>Lr,Image:()=>Qr,ImageBackground:()=>qr,InteractionManager:()=>Nr,Keyboard:()=>Dr,KeyboardAvoidingView:()=>_r,LayoutAnimation:()=>Ur,Linking:()=>Or,LogBox:()=>so,Modal:()=>xo,NativeEventEmitter:()=>Kr,NativeModules:()=>Ir,PanResponder:()=>Wr,Picker:()=>Jr,PixelRatio:()=>Fr,Platform:()=>Mr,Pressable:()=>Co,ProgressBar:()=>Yr,RefreshControl:()=>Gr,SafeAreaView:()=>Zr,ScrollView:()=>gt,SectionList:()=>eo,Share:()=>jr,StatusBar:()=>to,StyleSheet:()=>F,Switch:()=>Io,Text:()=>y,TextInput:()=>ht,Touchable:()=>ro,TouchableHighlight:()=>vo,TouchableNativeFeedback:()=>oo,TouchableOpacity:()=>H,TouchableWithoutFeedback:()=>wo,UIManager:()=>Vr,Vibration:()=>$r,View:()=>d,VirtualizedList:()=>no,YellowBox:()=>ao,findNodeHandle:()=>To,unstable_createElement:()=>xr,useColorScheme:()=>lo,useLocaleContext:()=>co,useWindowDimensions:()=>uo});br(lt,Cr);import*as Cr from"react-native-web";import{unstable_createElement as xr,NativeModules as Ir,AccessibilityInfo as kr,Animated as Tr,Appearance as Br,AppRegistry as Rr,AppState as Ar,BackHandler as Hr,Clipboard as Pr,Dimensions as zr,Easing as Er,I18nManager as Lr,Keyboard as Dr,InteractionManager as Nr,LayoutAnimation as Ur,Linking as Or,NativeEventEmitter as Kr,PanResponder as Wr,PixelRatio as Fr,Platform as Mr,Share as jr,StyleSheet as F,UIManager as Vr,Vibration as $r,CheckBox as Xr,FlatList as Ie,Image as Qr,ImageBackground as qr,KeyboardAvoidingView as _r,Picker as Jr,ProgressBar as Yr,RefreshControl as Gr,SafeAreaView as Zr,SectionList as eo,StatusBar as to,Touchable as ro,TouchableNativeFeedback as oo,VirtualizedList as no,YellowBox as ao,LogBox as so,DeviceEventEmitter as io,useColorScheme as lo,useLocaleContext as co,useWindowDimensions as uo}from"react-native-web";import*as z from"react-native-web";import{createElement as ke,forwardRef as ct,useCallback as ho,useRef as go}from"react";import{useEffect as po,useState as mo}from"react";import{createPortal as yo}from"react-dom";var fo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as bo}from"react/jsx-runtime";var re=Symbol.for("@buoy-gg/portal-host"),dt=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function ut(){let e=document;if(e[re])return e[re].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:fo});let r=()=>{let s=document.fullscreenElement,b=s&&s.tagName!=="CANVAS"?s:document.body;t.parentElement!==b&&b.appendChild(t)},n=new Map,o=s=>{(!t.contains(s.target)||!dt(s.target))&&n.set(s.code||s.key,{key:s.key,code:s.code,location:s.location,keyCode:s.keyCode,which:s.which,altKey:s.altKey,ctrlKey:s.ctrlKey,metaKey:s.metaKey,shiftKey:s.shiftKey})},i=s=>{n.delete(s.code||s.key)},l=()=>n.clear(),h=()=>{let s=[...n.values()];n.clear();for(let b of s)document.dispatchEvent(new KeyboardEvent("keyup",{...b,bubbles:true}))},a=s=>{dt(s.target)&&s.stopPropagation()},c=s=>s.stopPropagation();return r(),document.addEventListener("fullscreenchange",r),document.addEventListener("keydown",o,true),document.addEventListener("keyup",i,true),window.addEventListener("blur",l),t.addEventListener("focusin",h),t.addEventListener("keydown",a),t.addEventListener("keyup",a),t.addEventListener("keypress",a),t.addEventListener("wheel",c,{passive:true}),e[re]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",r),document.removeEventListener("keydown",o,true),document.removeEventListener("keyup",i,true),window.removeEventListener("blur",l),t.remove(),delete e[re]}},t}function So({children:e}){let[t,r]=mo(null);return po(()=>{let n=ut(),o=document[re];return o.users++,r(n),()=>{--o.users===0&&o.dispose()}},[]),t?yo(bo("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function D(e){let t=ct((n,o)=>{let{accessibilityState:i,accessibilityValue:l,...h}=n;for(let a of["busy","checked","disabled","expanded","selected"])i?.[a]!==void 0&&h[`aria-${a}`]===void 0&&(h[`aria-${a}`]=i[a]);for(let[a,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))l?.[a]!==void 0&&h[`aria-${c}`]===void 0&&(h[`aria-${c}`]=l[a]);return ke(e,{...h,ref:o})}),r=e.State;return r&&Object.assign(t,{State:r}),t.displayName=e.displayName??e.name??"NativeWebView",t}var d=D(z.View),y=D(z.Text),ht=D(z.TextInput),H=D(z.TouchableOpacity),vo=D(z.TouchableHighlight),wo=D(z.TouchableWithoutFeedback),Co=D(z.Pressable),gt=D(z.ScrollView),pt=ct((e,t)=>{let r=go(null),n=ho(o=>{if(o){let i=o;for(;i.parentElement&&i.parentElement!==document.body;)i=i.parentElement;i.parentElement===document.body&&(r.current=i,Object.assign(i.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),ut().appendChild(i))}else r.current&&(document.body.appendChild(r.current),r.current=null);typeof t=="function"?t(o):t&&(t.current=o)},[t]);return ke(So,null,ke(z.Modal,{...e,ref:n}))});pt.displayName="Modal";var xo=D(pt),Io=D(z.Switch),mt=D(z.ActivityIndicator),ko=D(z.Button),To=z.findNodeHandle,Bo={alert(e,t,r,n){if(typeof document>"u")return;let o=document.createElement("dialog");o.dataset.buoyRoot="",o.setAttribute("aria-label",e),o.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let i=document.createElement("h2");if(i.textContent=e,i.style.cssText="font-size:18px;margin:0 0 12px",o.appendChild(i),t){let c=document.createElement("p");c.textContent=t,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",o.appendChild(c)}let l=document.createElement("div");l.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let h=r?.length?r:[{text:"OK"}],a=()=>{o.close?.(),o.remove()};for(let c of h){let s=document.createElement("button");s.type="button",s.textContent=c.text??"OK",s.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,s.onclick=()=>{a(),c.onPress?.()},l.appendChild(s)}o.addEventListener("cancel",c=>{c.preventDefault(),n?.cancelable!==false&&(a(),n?.onDismiss?.())}),o.appendChild(l),document.body.appendChild(o),o.showModal?o.showModal():o.setAttribute("open","")}};import{JsModal as Ro,TabSelector as Ao,ModalHeader as oe,buoyColors as Ho,night as yt,Search as Po,TickProvider as ft,windowDragProps as zo}from"@buoy-gg/shared-ui/web";import{useState as me,useEffect as bt,useCallback as N,useSyncExternalStore as Eo}from"react";import{assertAccountAccess as St,getAccountAccess as Lo,hasAccountAccess as Do,subscribeAccountAccess as No}from"@buoy-gg/shared-ui/web";var vt=[/\/symbolicate$/,/\/logs$/,/\/debugger-proxy/,/\/reload$/,/\/launch-js-devtools/,/localhost:8081/,/100\.64\.\d+\.\d+:8081/,/10\.0\.\d+\.\d+:8081/,/\.hot-update\./,/__metro/];function Te(e,t){for(let r of Object.keys(t))r.startsWith("__buoy")&&(e[r]=t[r])}var Uo=class{constructor(){this.isListeningFlag=false;this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.reportHeader=e=>this.shouldInjectHeader(e)?{[this.config.headerKey]:this.config.userId}:null;this.originalFetch=globalThis.fetch.bind(globalThis),this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.config={headerKey:"x-impersonate-user-id",userId:null,ignorePatterns:[...vt]}}setConfig(e){this.config={...this.config,...e},e.ignorePatterns&&(this.config.ignorePatterns=[...vt,...e.ignorePatterns])}getConfig(){return{...this.config}}shouldInjectHeader(e){return!this.config.userId||this.config.gate&&!this.config.gate()?false:!this.config.ignorePatterns.some(t=>t.test(e))}extractUrl(e){return typeof e=="string"?e:e instanceof URL?e.href:e.url}startListening(){if(this.isListeningFlag)return;let e=globalThis.fetch,t=XMLHttpRequest.prototype.open,r=XMLHttpRequest.prototype.send;this.originalFetch=e.bind(globalThis),this.originalXHROpen=t,this.originalXHRSend=r;let n=this,o=async function(c,s){let b=n.extractUrl(c);if(n.shouldInjectHeader(b)){let C=s?.headers??(typeof c=="object"&&"headers"in c?c.headers:void 0),f=new Headers(C);return f.set(n.config.headerKey,n.config.userId),n.originalFetch(c,{...s,headers:f})}return n.originalFetch(c,s)};Te(o,e),this.patchedFetch=o,globalThis.fetch=this.patchedFetch;let i=function(c,s,b=true,C,f){let x=this;x._impersonateUrl=typeof s=="string"?s:s.href;let I=typeof s=="string"?s:s.toString();return n.originalXHROpen.call(this,c,I,b,C,f)},l=function(c){let s=this;return s._impersonateUrl&&n.shouldInjectHeader(s._impersonateUrl)&&this.setRequestHeader(n.config.headerKey,n.config.userId),n.originalXHRSend.call(this,c)};Te(i,t),Te(l,r),this.patchedXHROpen=i,this.patchedXHRSend=l,XMLHttpRequest.prototype.open=this.patchedXHROpen,XMLHttpRequest.prototype.send=this.patchedXHRSend;let h=globalThis,a=h.__buoyHeaderInjectors??(h.__buoyHeaderInjectors=[]);a.includes(this.reportHeader)||a.push(this.reportHeader),this.isListeningFlag=true}stopListening(){if(!this.isListeningFlag)return;this.patchedFetch&&globalThis.fetch===this.patchedFetch&&(globalThis.fetch=this.originalFetch),this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend),this.patchedFetch=null,this.patchedXHROpen=null,this.patchedXHRSend=null;let e=globalThis.__buoyHeaderInjectors,t=e?.indexOf(this.reportHeader)??-1;e&&t>=0&&e.splice(t,1),this.isListeningFlag=false}get isListening(){return this.isListeningFlag}get isImpersonating(){return this.config.userId!==null&&(this.config.gate?.()??true)}},ne=null;function O(){return ne||(ne=new Uo),ne}function Oo(){O().startListening()}function Ko(){O().stopListening()}function wt(e){O().setConfig(e)}function Wo(){return ne?.isImpersonating??false}function Fo(){return ne?.getConfig().userId??null}var ae="@buoy/impersonate/state",Mo=10,Ct={reactQuery:true,redux:true,asyncStorage:false,mmkv:false},Z={isActive:false,isPaused:false,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:Ct,showBanner:true,history:[]},Be=false,xt={getItem:e=>{try{return typeof localStorage<"u"?localStorage.getItem(e):null}catch{return null}},setItem:(e,t)=>{try{typeof localStorage<"u"&&localStorage.setItem(e,t)}catch{}},removeItem:e=>{try{typeof localStorage<"u"&&localStorage.removeItem(e)}catch{}}},jo=class{constructor(){this.state={...Z};this.listeners=new Set;this.nukeCallbacks={};this.isInitialized=false;this.asyncStorageRef=null;this.storageReadyPromise=null;this.resolveStorageReady=null;this.developerDefaults=null;this.getSnapshot=()=>this.state;this.subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));this.remoteHandler=null;this.loadFromStorage(),Promise.resolve().then(()=>{let e=false,t=()=>{let r=Lo().status;r==="admitted"?e=true:r==="locked"&&e&&(e=false,this.disposeAccountSession())};No(t),t()}),typeof localStorage<"u"?this.storageReadyPromise=Promise.resolve():this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}loadFromStorage(){try{let e=xt.getItem(ae),t=this.getEffectiveDefaults();if(e){let r=JSON.parse(e);this.state={...Z,headerKey:r.headerKey??t.headerKey,ignorePatterns:r.ignorePatterns??Z.ignorePatterns,dataNukeSettings:{...t.dataNukeSettings,...r.dataNukeSettings},showBanner:r.showBanner??t.showBanner,history:r.history??[],isActive:r.isActive??false,isPaused:r.isPaused??false,currentUser:r.currentUser??null},this.state.isActive&&this.state.currentUser&&this.syncWithListener()}else this.state={...Z,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner};this.isInitialized=true}catch{this.isInitialized=true}}setAsyncStorage(e){this.asyncStorageRef=e,this.resolveStorageReady&&(this.resolveStorageReady(),this.resolveStorageReady=null)}setDeveloperDefaults(e){this.developerDefaults=e;let t=this.getEffectiveDefaults();this.isInitialized||(this.state={...this.state,headerKey:t.headerKey,dataNukeSettings:t.dataNukeSettings,showBanner:t.showBanner})}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??Z.headerKey,dataNukeSettings:{...Ct,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??Z.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(e){this.asyncStorageRef=e;try{let t=await e.getItem(ae);if(console.log("[Buoy]",`[impersonate] initializeAsync read STORAGE_KEY=${ae} stored=${t?t.slice(0,200):"null"}`),t){let r=JSON.parse(t);this.state={...this.state,headerKey:r.headerKey??this.state.headerKey,ignorePatterns:r.ignorePatterns??this.state.ignorePatterns,dataNukeSettings:{...this.state.dataNukeSettings,...r.dataNukeSettings},showBanner:r.showBanner??this.state.showBanner,history:r.history??this.state.history,isActive:r.isActive??this.state.isActive,isPaused:r.isPaused??this.state.isPaused,currentUser:r.currentUser??this.state.currentUser},this.state.isActive&&this.state.currentUser&&this.syncWithListener(),this.notify()}}catch{}}}registerNukeCallbacks(e){this.nukeCallbacks={...this.nukeCallbacks,...e}}getState(){return{...this.state}}setRemoteHandler(e){this.remoteHandler=e}replaceState(e){this.state=e,this.notify()}async startImpersonation(e){if(St(),this.remoteHandler){this.remoteHandler("startImpersonation",{user:e});return}let t=[{user:e,lastUsedAt:new Date().toISOString()},...this.state.history.filter(r=>r.user.id!==e.id)].slice(0,Mo);this.state={...this.state,isActive:true,currentUser:e,history:t},this.syncWithListener(),this.notify(),await this.executeDataNuke(),await this.persist()}async stopImpersonation(){if(this.remoteHandler){this.remoteHandler("stopImpersonation");return}console.log("[Buoy]",`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`),this.state={...this.state,isActive:false,isPaused:false,currentUser:null},this.syncWithListener(),this.notify(),await this.executeDataNuke(),await this.persist()}async pauseImpersonation(){if(this.remoteHandler){this.remoteHandler("pauseImpersonation");return}!this.state.isActive||this.state.isPaused||(this.state={...this.state,isPaused:true},this.syncWithListener(),await this.persist(),this.notify())}async resumeImpersonation(){if(St(),this.remoteHandler){this.remoteHandler("resumeImpersonation");return}!this.state.isActive||!this.state.isPaused||(this.state={...this.state,isPaused:false},this.syncWithListener(),await this.persist(),this.notify())}async quickSwitch(e){return this.startImpersonation(e)}async updateSettings(e){if(this.remoteHandler){this.remoteHandler("updateSettings",{settings:e});return}this.state={...this.state,headerKey:e.headerKey??this.state.headerKey,ignorePatterns:e.ignorePatterns??this.state.ignorePatterns,showBanner:e.showBanner??this.state.showBanner,dataNukeSettings:e.dataNukeSettings?{...this.state.dataNukeSettings,...e.dataNukeSettings}:this.state.dataNukeSettings},(e.headerKey||e.ignorePatterns)&&this.syncWithListener(),await this.persist(),this.notify()}async removeFromHistory(e){if(this.remoteHandler){this.remoteHandler("removeFromHistory",{userId:e});return}this.state={...this.state,history:this.state.history.filter(t=>t.user.id!==e)},await this.persist(),this.notify()}async clearHistory(){if(this.remoteHandler){this.remoteHandler("clearHistory");return}this.state={...this.state,history:[]},await this.persist(),this.notify()}async executeDataNuke(){if(!Be){Be=true;try{let{dataNukeSettings:e}=this.state,t=[];e.reactQuery&&this.nukeCallbacks.reactQuery&&t.push(Promise.resolve(this.nukeCallbacks.reactQuery())),e.redux&&this.nukeCallbacks.redux&&t.push(Promise.resolve(this.nukeCallbacks.redux())),e.asyncStorage&&this.nukeCallbacks.asyncStorage&&t.push(Promise.resolve(this.nukeCallbacks.asyncStorage())),e.mmkv&&this.nukeCallbacks.mmkv&&t.push(Promise.resolve(this.nukeCallbacks.mmkv())),await Promise.allSettled(t)}finally{setTimeout(()=>{Be=false},100)}}}disposeAccountSession(){this.remoteHandler||!this.state.isActive||(this.state={...this.state,isActive:false,isPaused:false,currentUser:null},this.syncWithListener(),this.notify(),this.persist())}syncWithListener(){let e=this.state.isActive&&!this.state.isPaused;wt({headerKey:this.state.headerKey,userId:e?this.state.currentUser?.id??null:null,ignorePatterns:this.state.ignorePatterns.map(t=>new RegExp(t)),gate:Do}),O().isListening||O().startListening()}async persist(){this.storageReadyPromise&&await this.storageReadyPromise;let e={headerKey:this.state.headerKey,ignorePatterns:this.state.ignorePatterns,dataNukeSettings:this.state.dataNukeSettings,showBanner:this.state.showBanner,history:this.state.history,isActive:this.state.isActive,isPaused:this.state.isPaused,currentUser:this.state.currentUser},t=JSON.stringify(e);try{this.asyncStorageRef?(await this.asyncStorageRef.setItem(ae,t),console.log("[Buoy]",`[impersonate] persist -> AsyncStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)):(xt.setItem(ae,t),console.log("[Buoy]",`[impersonate] persist -> localStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`))}catch(r){console.warn("[Buoy]","[impersonate] persist failed",r)}}notify(){this.listeners.forEach(e=>{try{e(this.state)}catch{}})}},p=new jo;function It(e={}){let[t,r]=me(""),[n,o]=me([]),[i,l]=me(false),[h,a]=me(null),c=Eo(p.subscribe,p.getSnapshot,p.getSnapshot);bt(()=>{p.registerNukeCallbacks({reactQuery:e.onClearReactQuery,redux:e.onClearRedux,asyncStorage:e.onClearAsyncStorage,mmkv:e.onClearMMKV})},[e.onClearReactQuery,e.onClearRedux,e.onClearAsyncStorage,e.onClearMMKV]),bt(()=>{let S=true;return(async()=>{try{let v=await import("@buoy-gg/shared-ui/web/asyncStorage").then(W=>W.default),G={getItem:W=>v.getItem(W),setItem:(W,we)=>v.setItem(W,we)};p.setAsyncStorage(G),S&&await p.initializeAsync(G)}catch{}})(),O().isListening||O().startListening(),()=>{S=false}},[]);let s=N(async S=>{if(r(S),a(null),!S.trim()){o([]);return}if(!e.onSearchUsers){a("Search not configured"),o([]);return}l(true);try{let v=await e.onSearchUsers(S);o(v)}catch(v){a(v instanceof Error?v.message:"Search failed"),o([])}finally{l(false)}},[e.onSearchUsers]),b=N(()=>{r(""),o([]),a(null)},[]),C=N(async S=>{await p.startImpersonation(S)},[]),f=N(async()=>{await p.stopImpersonation()},[]),x=N(async S=>{await p.quickSwitch(S)},[]),I=N(async S=>{await p.updateSettings({headerKey:S})},[]),pe=N(async S=>{await p.updateSettings({ignorePatterns:S})},[]),X=N(async S=>{await p.updateSettings({dataNukeSettings:S})},[]),Y=N(async S=>{await p.updateSettings({showBanner:S})},[]),K=N(async S=>{await p.removeFromHistory(S)},[]),ee=N(async()=>{await p.clearHistory()},[]);return{isActive:c.isActive,currentUser:c.currentUser,headerKey:c.headerKey,ignorePatterns:c.ignorePatterns,dataNukeSettings:c.dataNukeSettings,showBanner:c.showBanner,history:c.history,searchQuery:t,searchResults:n,isSearching:i,searchError:h,searchUsers:s,clearSearch:b,startImpersonation:C,stopImpersonation:f,quickSwitch:x,updateHeaderKey:I,updateIgnorePatterns:pe,updateDataNukeSettings:X,updateShowBanner:Y,removeFromHistory:K,clearHistory:ee}}import{useCallback as Vo}from"react";import{dispatchToolAction as kt,getToolAdapters as $o}from"@buoy-gg/shared-ui/web";function Xo(){let e=!!$o().query,t=Vo(async()=>{await kt("query","clearQueryCache"),await kt("query","clearMutationCache")},[]);return{isAvailable:e,error:e?null:"Connect React Query to Buoy or provide onClearReactQuery.",clearCache:e?t:null}}import{useCallback as Qo}from"react";import{dispatchToolAction as qo,getToolAdapters as _o}from"@buoy-gg/shared-ui/web";var Jo="@@RESET";function Yo({resetActionType:e=Jo}={}){let t=!!_o().redux,r=Qo(async()=>{await qo("redux","dispatch",{action:{type:e}})},[e]);return{isAvailable:t,error:t?null:"Connect Redux to Buoy or provide onClearRedux.",resetStore:t?r:null}}import{isDevToolsStorageKey as Go}from"@buoy-gg/shared-ui/web";import{useCallback as Zo,useMemo as en,useState as Tt,useEffect as tn}from"react";var Re=false;function rn(){let[e,t]=Tt(null),[r,n]=Tt(null);tn(()=>{let i=wr();i?(t(i),n(null)):n("@react-native-async-storage/async-storage is not installed")},[]);let o=Zo(async()=>{if(!Re){Re=true;try{if(e){let i=(await e.getAllKeys()).filter(l=>!Go(l));i.length>0&&await e.multiRemove([...i])}}finally{setTimeout(()=>{Re=false},100)}}},[e]);return en(()=>!e||r?{isAvailable:false,error:r||"@react-native-async-storage/async-storage is not available",clearStorage:null}:{isAvailable:true,error:null,clearStorage:o},[e,r,o])}import{useCallback as on}from"react";import{SectionHeader as Ae,EmptyState as nn,night as A,Search as an,AlertTriangle as Bt,Users as sn}from"@buoy-gg/shared-ui/web";import{buoyColors as He,night as E,Play as ln,X as cn,PowerToggleButton as dn,monoFont as un}from"@buoy-gg/shared-ui/web";import{useMemo as Rt}from"react";import{buoyColors as hn,night as gn}from"@buoy-gg/shared-ui/web";import{jsx as Pe,jsxs as pn}from"react/jsx-runtime";var At=["#6366F1","#8B5CF6","#EC4899","#F43F5E","#F97316","#EAB308","#22C55E","#14B8A6","#06B6D4","#3B82F6"],mn={small:{container:24,font:10,indicator:8},medium:{container:36,font:14,indicator:10},large:{container:44,font:16,indicator:12}};function yn(e){if(!e)return"?";if(e.includes("@"))return e.charAt(0).toUpperCase();let t=e.trim().split(/\s+/);return t.length===1?t[0].charAt(0).toUpperCase():(t[0].charAt(0)+t[t.length-1].charAt(0)).toUpperCase()}function fn(e){let t=0;for(let r=0;r<e.length;r++)t=e.charCodeAt(r)+((t<<5)-t);return At[Math.abs(t)%At.length]}function ze({userId:e,name:t,size:r="medium",showActiveIndicator:n=false,backgroundColor:o}){let i=mn[r],l=Rt(()=>o??fn(e),[e,o]),h=Rt(()=>yn(t),[t]);return pn(d,{style:ye.wrapper,children:[Pe(d,{style:[ye.container,{width:i.container,height:i.container,borderRadius:i.container/2,backgroundColor:l}],children:Pe(y,{style:[ye.initials,{fontSize:i.font}],children:h})}),n&&Pe(d,{style:[ye.indicator,{width:i.indicator,height:i.indicator,borderRadius:i.indicator/2,right:-1,bottom:-1}]})]})}var ye=F.create({wrapper:{position:"relative"},container:{alignItems:"center",justifyContent:"center"},initials:{color:"#FFFFFF",fontWeight:"600",letterSpacing:.5},indicator:{position:"absolute",backgroundColor:hn.success,borderWidth:2,borderColor:gn.color.surface}});import{jsx as L,jsxs as se}from"react/jsx-runtime";function Ht({user:e,isActive:t=false,onPress:r,onStop:n,onRemove:o,showRemoveButton:i=false,lastUsedTime:l,variant:h="default"}){let a=e.displayName||e.email||e.id,c=e.email&&e.displayName,s=typeof e.metadata?.role=="string"?e.metadata.role:null;return se(H,{testID:`buoy-impersonate-user-${e.id}`,style:[R.container,t&&R.activeContainer,h==="compact"&&R.compactContainer],onPress:r,disabled:t,activeOpacity:.7,children:[L(d,{style:R.avatarSection,children:L(ze,{userId:e.id,name:a,size:h==="compact"?"small":"medium",showActiveIndicator:t})}),se(d,{style:R.content,children:[se(d,{style:R.nameRow,children:[L(y,{style:[R.name,t&&R.activeName],numberOfLines:1,children:a}),s?L(d,{style:R.roleBadge,children:L(y,{style:R.roleBadgeText,children:s.toUpperCase()})}):null]}),c&&L(y,{style:R.email,numberOfLines:1,children:e.email}),L(d,{style:R.metadataRow,children:se(y,{style:R.userId,children:["ID: ",e.id]})})]}),se(d,{style:R.actions,children:[t?L(dn,{isEnabled:true,onToggle:n||(()=>{}),accessibilityLabel:"Stop impersonation"}):L(H,{style:R.actionButton,onPress:r,activeOpacity:.7,children:L(ln,{size:14,color:E.color.onAccent})}),i&&o&&!t&&L(H,{style:R.removeButton,onPress:o,activeOpacity:.7,children:L(cn,{size:12,color:E.color.textTertiary})})]}),l?L(y,{style:R.lastUsed,children:l}):null]})}var R=F.create({container:{flexDirection:"row",alignItems:"center",backgroundColor:E.color.surface,borderRadius:10,borderWidth:1,borderColor:E.color.border,padding:12,gap:12},activeContainer:{backgroundColor:He.success+"10",borderColor:He.success+"40"},compactContainer:{padding:10,gap:10},avatarSection:{flexShrink:0},content:{flex:1,minWidth:0},nameRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:2},name:{fontSize:15,fontWeight:"600",color:E.color.text,flexShrink:1},activeName:{color:He.success},roleBadge:{backgroundColor:E.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},roleBadgeText:{fontSize:9,fontWeight:"700",color:E.color.textTertiary,letterSpacing:.5},email:{fontSize:13,color:E.color.textSecondary,marginBottom:4},metadataRow:{flexDirection:"row",alignItems:"center",gap:4},userId:{fontSize:11,color:E.color.textTertiary,fontFamily:un},lastUsed:{position:"absolute",bottom:8,right:10,fontSize:10,color:E.color.textTertiary},actions:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:0},actionButton:{width:36,height:36,borderRadius:8,backgroundColor:E.color.accent,alignItems:"center",justifyContent:"center"},removeButton:{width:28,height:28,borderRadius:6,backgroundColor:E.color.surfaceElevated,borderWidth:1,borderColor:E.color.border,alignItems:"center",justifyContent:"center"}});import{jsx as T,jsxs as M}from"react/jsx-runtime";function Pt({currentUser:e,searchQuery:t,searchResults:r,isSearching:n,searchError:o,onSelectUser:i,onStopImpersonation:l,searchAvailable:h=true}){let a=on(({item:c})=>{let s=e?.id===c.id;return T(Ht,{user:c,isActive:s,onPress:()=>!s&&i(c),onStop:s?l:void 0})},[e,i,l]);return M(d,{style:B.container,children:[!h&&T(d,{style:B.section,children:M(d,{style:B.warningCard,children:[T(Bt,{size:18,color:A.color.warning}),M(d,{style:B.warningContent,children:[T(y,{style:B.warningTitle,children:"Search Not Available"}),T(y,{style:B.warningText,children:"Configure the onSearchUsers callback to enable user search."})]})]})}),n&&M(d,{style:B.loadingContainer,children:[T(mt,{size:"small",color:A.color.accent}),T(y,{style:B.loadingText,children:"Searching users..."})]}),o?T(d,{style:B.section,children:M(d,{style:B.errorCard,children:[T(Bt,{size:16,color:A.color.danger}),T(y,{style:B.errorText,children:o})]})}):null,r.length>0&&M(d,{style:B.resultsSection,children:[M(Ae,{children:[T(Ae.Title,{children:"Results"}),T(Ae.Badge,{count:r.length})]}),T(Ie,{data:r,keyExtractor:c=>c.id,renderItem:a,ItemSeparatorComponent:()=>T(d,{style:B.separator}),contentContainerStyle:B.listContent,showsVerticalScrollIndicator:false})]}),!!t&&!n&&r.length===0&&!o&&M(d,{style:B.emptyStateContainer,children:[T(d,{style:B.emptyStateIcon,children:T(sn,{size:28,color:A.color.textTertiary})}),T(y,{style:B.emptyStateTitle,children:"No users found"}),M(y,{style:B.emptyStateDescription,children:['No results for "',t,'"']}),T(y,{style:B.emptyStateHint,children:"Try a different search term"})]}),!t&&r.length===0&&!n&&h&&T(nn,{title:"Search for users",description:"Tap the search icon in the header to find users by email, name, or ID",icon:an,variant:"minimal"})]})}var B=F.create({container:{flex:1},section:{padding:16,paddingBottom:8},loadingContainer:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10,paddingVertical:20},loadingText:{fontSize:13,color:A.color.textSecondary},resultsSection:{flex:1,paddingHorizontal:16},listContent:{paddingBottom:16},separator:{height:8},warningCard:{flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:A.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:A.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:14,fontWeight:"600",color:A.color.warning,marginBottom:4},warningText:{fontSize:13,color:A.color.textSecondary,lineHeight:18},errorCard:{flexDirection:"row",alignItems:"center",gap:10,backgroundColor:A.color.dangerSoft,borderRadius:10,borderWidth:1,borderColor:A.color.danger+"25",padding:12},errorText:{flex:1,fontSize:13,color:A.color.danger},emptyStateContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyStateIcon:{width:56,height:56,borderRadius:28,backgroundColor:A.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyStateTitle:{fontSize:16,fontWeight:"600",color:A.color.text,marginBottom:6},emptyStateDescription:{fontSize:14,color:A.color.textSecondary,textAlign:"center",marginBottom:8},emptyStateHint:{fontSize:12,color:A.color.textTertiary}});import{useCallback as bn}from"react";import{night as Q,Trash2 as Sn,useRelativeTime as vn,ToolEmptyState as wn}from"@buoy-gg/shared-ui/web";import{jsx as U,jsxs as zt}from"react/jsx-runtime";function Cn({item:e,isActive:t,onSelect:r,onStop:n,onRemove:o,showRemoveButton:i}){let l=vn(new Date(e.lastUsedAt));return U(Ht,{user:e.user,isActive:t,onPress:()=>!t&&r(e.user),onStop:t?n:void 0,onRemove:o,showRemoveButton:i,lastUsedTime:l})}function Et({history:e,currentUserId:t,onSelectUser:r,onStopImpersonation:n,onRemoveFromHistory:o,onClearHistory:i}){let l=bn(({item:h})=>{let a=t===h.user.id;return U(Cn,{item:h,isActive:a,onSelect:r,onStop:n,onRemove:o?()=>o(h.user.id):void 0,showRemoveButton:!!o})},[t,r,n,o]);return e.length===0?U(wn,{testID:"buoy-impersonate-history-empty",otto:"disguise",title:"No History",message:"Users you impersonate will appear here for quick access"}):zt(d,{style:j.container,children:[zt(d,{style:j.headerRow,children:[U(y,{style:j.headerTitle,children:"Recent"}),U(d,{style:j.headerBadge,children:U(y,{style:j.headerBadgeText,children:e.length})}),U(d,{style:j.headerSpacer}),i&&U(H,{style:j.clearButton,onPress:i,activeOpacity:.7,children:U(Sn,{size:12,color:Q.color.textTertiary})})]}),U(Ie,{data:e,keyExtractor:h=>h.user.id,renderItem:l,ItemSeparatorComponent:()=>U(d,{style:j.separator}),contentContainerStyle:j.listContent,showsVerticalScrollIndicator:false})]})}var j=F.create({container:{flex:1,paddingHorizontal:16},headerRow:{flexDirection:"row",alignItems:"center",paddingVertical:10,gap:8},headerTitle:{fontSize:12,fontWeight:"600",color:Q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},headerBadge:{backgroundColor:Q.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},headerBadgeText:{fontSize:10,fontWeight:"600",color:Q.color.textTertiary},headerSpacer:{flex:1},clearButton:{width:24,height:24,alignItems:"center",justifyContent:"center",backgroundColor:Q.color.surfaceElevated,borderRadius:4},listContent:{paddingBottom:20},separator:{height:8},emptyContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyIcon:{width:56,height:56,borderRadius:28,backgroundColor:Q.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyTitle:{fontSize:16,fontWeight:"600",color:Q.color.text,marginBottom:6},emptyDescription:{fontSize:14,color:Q.color.textSecondary,textAlign:"center"}});import{useState as fe,useEffect as Ee,useMemo as Le}from"react";import{CollapsibleSection as ie,buoyColors as le,night as m,Settings as xn,AlertTriangle as Lt,Info as In,Zap as kn,RefreshCw as Tn,Check as De,X as Dt,Copy as Nt,Eye as Bn,copyToClipboard as Rn,ToggleRow as An,monoFont as Ne}from"@buoy-gg/shared-ui/web";import{DataViewer as Hn}from"@buoy-gg/shared-ui/web/dataViewer";import{Fragment as Ue,jsx as g,jsxs as w}from"react/jsx-runtime";var ce="x-impersonate-user-id",Oe=true,de={reactQuery:true,redux:true,asyncStorage:false,mmkv:false};function ue({label:e,description:t,value:r,onChange:n,recommended:o,dangerous:i,detected:l}){let h=w(Ue,{children:[l!==void 0&&w(d,{style:[u.detectedBadge,l?u.detectedBadgeActive:u.detectedBadgeInactive],children:[l?g(De,{size:10,color:le.success}):g(Dt,{size:10,color:m.color.textTertiary}),g(y,{style:[u.detectedText,l?u.detectedTextActive:u.detectedTextInactive],children:l?"Detected":"Not Detected"})]}),o&&l!==false&&w(d,{style:u.recommendedBadge,children:[g(kn,{size:10,color:m.color.accent}),g(y,{style:u.recommendedText,children:"Recommended"})]})]});return g(An,{variant:"plain",label:e,description:t,value:r,onValueChange:n,tone:i?"warning":"accent",emphasizeLabel:i,accessory:h})}function Ut({headerKey:e,settings:t,showBanner:r,onSave:n,onShowBannerChange:o,detectionStatus:i}){let[l,h]=fe(e),[a,c]=fe(t),[s,b]=fe(r),[C,f]=fe(false);Ee(()=>{h(e)},[e]),Ee(()=>{c(t)},[t]),Ee(()=>{b(r)},[r]);let x=Le(()=>l!==e||a.reactQuery!==t.reactQuery||a.redux!==t.redux||a.asyncStorage!==t.asyncStorage||a.mmkv!==t.mmkv,[l,a,e,t]),I=Le(()=>l===ce&&s===Oe&&a.reactQuery===de.reactQuery&&a.redux===de.redux&&a.asyncStorage===de.asyncStorage&&a.mmkv===de.mmkv,[l,s,a]),pe=()=>{n(l.trim()||ce,a,s)},X=()=>{h(e),c(t),b(r)},Y=()=>{h(ce),c(de),b(Oe),o(Oe)},K=(v,G)=>{c(W=>({...W,[v]:G}))},ee=Le(()=>({defaults:{headerKey:l,showBanner:s,dataNukeSettings:{reactQuery:a.reactQuery,redux:a.redux,asyncStorage:a.asyncStorage,mmkv:a.mmkv}}}),[l,s,a]),S=async()=>{let v=`defaults: {
|
|
2
|
+
headerKey: '${l}',
|
|
3
|
+
showBanner: ${s},
|
|
4
4
|
dataNukeSettings: {
|
|
5
|
-
reactQuery: ${
|
|
6
|
-
redux: ${
|
|
7
|
-
asyncStorage: ${
|
|
8
|
-
mmkv: ${
|
|
5
|
+
reactQuery: ${a.reactQuery},
|
|
6
|
+
redux: ${a.redux},
|
|
7
|
+
asyncStorage: ${a.asyncStorage},
|
|
8
|
+
mmkv: ${a.mmkv},
|
|
9
9
|
},
|
|
10
|
-
},`;try{await ma(b),f(true),setTimeout(()=>f(false),2e3)}catch{}};return v(lt,{style:l.container,contentContainerStyle:l.contentContainer,children:[C&&u(s,{style:l.actionBar,children:v(s,{style:l.actionBarContent,children:[u(y,{style:l.unsavedText,children:"Unsaved changes"}),v(s,{style:l.actionButtons,children:[v(H,{style:l.discardButton,onPress:X,children:[u(At,{size:14,color:m.color.textSecondary}),u(y,{style:l.discardButtonText,children:"Discard"})]}),v(H,{style:l.saveButton,onPress:ge,children:[u(De,{size:14,color:m.color.onAccent}),u(y,{style:l.saveButtonText,children:"Save"})]})]})]})}),u(ie,{title:"Header Configuration",icon:da,defaultOpen:true,variant:"bordered",children:v(s,{style:l.sectionContent,children:[u(y,{style:l.inputLabel,children:"Header Key"}),u(st,{style:l.input,value:i,onChangeText:h,placeholder:"x-impersonate-user-id",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false}),v(s,{style:l.inputFooter,children:[u(y,{style:l.helperText,children:"The HTTP header key used for impersonation. Value will be the user ID."}),i!==le&&u(H,{onPress:()=>h(le),style:l.resetLink,children:u(y,{style:l.resetLinkText,children:"Reset to default"})})]})]})}),u(ie,{title:"Display",icon:pa,defaultOpen:true,variant:"bordered",children:u(s,{style:l.sectionContent,children:u(s,{style:l.togglesCard,children:u(de,{label:"Floating Banner",description:"Show a floating banner when impersonation is active",value:g,onChange:b=>{w(b),o(b)},recommended:true})})})}),u(ie,{title:"Data Clearing",icon:Rt,defaultOpen:true,variant:"bordered",children:v(s,{style:l.sectionContent,children:[u(y,{style:l.sectionDescription,children:"Choose what data to clear when impersonation starts or stops. This ensures you see fresh data for the impersonated user."}),v(s,{style:l.togglesCard,children:[u(de,{label:"React Query",description:"Clear query cache and cancel pending queries",value:n.reactQuery,onChange:b=>W("reactQuery",b),recommended:true,detected:c?.reactQuery}),u(s,{style:l.divider}),u(de,{label:"Redux",description:"Reset Redux store to initial state",value:n.redux,onChange:b=>W("redux",b),recommended:true,detected:c?.redux})]}),v(s,{style:l.advancedSection,children:[u(y,{style:l.advancedLabel,children:"Storage Options"}),v(s,{style:[l.togglesCard,l.dangerousCard],children:[u(de,{label:"AsyncStorage",description:"Clear app data (preserves @buoy/* keys)",value:n.asyncStorage,onChange:b=>W("asyncStorage",b),dangerous:true,detected:c?.asyncStorage}),u(s,{style:l.divider}),u(de,{label:"MMKV",description:"Clear MMKV storage (preserves @buoy/* keys)",value:n.mmkv,onChange:b=>W("mmkv",b),dangerous:true,detected:c?.mmkv})]})]}),(n.asyncStorage||n.mmkv)&&v(s,{style:l.warningCard,children:[u(Rt,{size:16,color:m.color.warning}),v(s,{style:l.warningContent,children:[u(y,{style:l.warningTitle,children:"Storage Clearing Enabled"}),u(y,{style:l.warningText,children:"This will remove app data like settings and cached content. Auth tokens managed by @buoy/* are preserved."})]})]})]})}),!I&&v(H,{style:l.restoreButton,onPress:Y,children:[u(ga,{size:14,color:m.color.textSecondary}),u(y,{style:l.restoreButtonText,children:"Restore Defaults"})]}),u(ie,{title:"How It Works",icon:ua,defaultOpen:false,variant:"bordered",children:v(s,{style:l.sectionContent,children:[u(y,{style:l.infoText,children:"When impersonation is enabled, the configured header is automatically added to all outgoing fetch and XMLHttpRequest calls."}),u(y,{style:[l.infoText,l.infoTextSpaced],children:"Your backend should check for this header and return data for the specified user ID instead of the authenticated user."}),v(s,{style:l.codeBlock,children:[u(y,{style:l.codeComment,children:"// Example request header"}),v(y,{style:l.codeText,children:[i||"x-impersonate-user-id",": ",u(y,{style:l.codeValue,children:"user_123"})]})]})]})}),u(ie,{title:"Export Configuration",icon:Ht,defaultOpen:false,variant:"bordered",children:v(s,{style:l.sectionContent,children:[u(y,{style:l.infoText,children:"Copy current settings to use in createImpersonateTool()."}),u(s,{style:l.dataViewerContainer,children:u(fa,{title:"",data:ee,showTypeFilter:true,rawMode:true,initialExpanded:true})}),u(H,{style:l.copyButton,onPress:S,children:x?v(Ue,{children:[u(De,{size:14,color:se.success}),u(y,{style:[l.copyButtonText,l.copySuccessText],children:"Copied!"})]}):v(Ue,{children:[u(Ht,{size:14,color:m.color.accent}),u(y,{style:l.copyButtonText,children:"Copy Config"})]})})]})})]})}var l=M.create({container:{flex:1},contentContainer:{padding:16,gap:12,paddingBottom:32},actionBar:{backgroundColor:m.color.accentSoft,borderRadius:10,borderWidth:1,borderColor:m.color.accentBorder,padding:12},actionBarContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},unsavedText:{fontSize:13,fontWeight:"500",color:m.color.accent},actionButtons:{flexDirection:"row",gap:8},saveButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:m.color.accent,paddingHorizontal:14,paddingVertical:8,borderRadius:6},saveButtonText:{fontSize:13,fontWeight:"600",color:m.color.onAccent},discardButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:m.color.surfaceElevated,paddingHorizontal:14,paddingVertical:8,borderRadius:6,borderWidth:1,borderColor:m.color.border},discardButtonText:{fontSize:13,fontWeight:"500",color:m.color.textSecondary},restoreButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,paddingVertical:12,borderRadius:8,borderWidth:1,borderColor:m.color.border,borderStyle:"dashed"},restoreButtonText:{fontSize:13,color:m.color.textSecondary},sectionContent:{paddingTop:8},sectionDescription:{fontSize:13,color:m.color.textSecondary,lineHeight:18,marginBottom:14},togglesCard:{backgroundColor:m.color.surface,borderRadius:10,borderWidth:1,borderColor:m.color.border,padding:4},dangerousCard:{borderColor:m.color.warning+"30"},advancedSection:{marginTop:16},advancedLabel:{fontSize:11,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,marginBottom:8,marginLeft:2},inputLabel:{fontSize:12,fontWeight:"600",color:m.color.textSecondary,marginBottom:8},input:{height:42,backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:14,fontSize:14,color:m.color.text,fontFamily:Le},inputFooter:{flexDirection:"row",justifyContent:"space-between",alignItems:"flex-start",marginTop:8,gap:12},helperText:{flex:1,fontSize:12,color:m.color.textTertiary,lineHeight:16},resetLink:{paddingVertical:2},resetLinkText:{fontSize:12,color:m.color.accent,fontWeight:"500"},recommendedBadge:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:m.color.accentSoft,paddingHorizontal:8,paddingVertical:3,borderRadius:4},recommendedText:{fontSize:10,fontWeight:"600",color:m.color.accent},detectedBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:8,paddingVertical:3,borderRadius:4},detectedBadgeActive:{backgroundColor:se.success+"15"},detectedBadgeInactive:{backgroundColor:m.color.textTertiary+"15"},detectedText:{fontSize:10,fontWeight:"600"},detectedTextActive:{color:se.success},detectedTextInactive:{color:m.color.textTertiary},divider:{height:1,backgroundColor:m.color.separator,marginHorizontal:12},warningCard:{marginTop:14,flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:m.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:m.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:13,fontWeight:"600",color:m.color.warning,marginBottom:4},warningText:{fontSize:12,color:m.color.textSecondary,lineHeight:17},infoText:{fontSize:13,color:m.color.textSecondary,lineHeight:19},infoTextSpaced:{marginTop:10},codeBlock:{marginTop:14,backgroundColor:m.color.bg,borderRadius:8,padding:14},codeComment:{fontSize:12,color:m.color.textTertiary,fontFamily:Le,marginBottom:6},codeText:{fontSize:13,color:m.color.text,fontFamily:Le},codeValue:{color:m.color.accent},dataViewerContainer:{marginTop:12,borderRadius:8,overflow:"hidden",borderWidth:1,borderColor:m.color.border},copyButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,marginTop:14,backgroundColor:m.color.accentSoft,paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderColor:m.color.accentBorder},copyButtonText:{fontSize:13,fontWeight:"600",color:m.color.accent},copySuccessText:{color:se.success}});import{jsx as P,jsxs as Ee}from"react/jsx-runtime";var Sa=yo,ba=[{key:"search",label:"Search"},{key:"history",label:"History"},{key:"settings",label:"Settings"}],va=[{key:"search",label:"Search"},{key:"history",label:"History"}];function Oe({visible:e,onClose:t,onBack:r,onMinimize:a,onSearchUsers:o,onClearReactQuery:c,onClearRedux:i,onClearAsyncStorage:h,onClearMMKV:n,showSettingsTab:d=true,inline:g=false}){let w=d?ba:va,[x,f]=xe("search"),[C,I]=xe(false),ge=at(false),[X,Y]=xe(""),W=at(null),{clearCache:ee,isAvailable:S}=Lo(),{resetStore:b,isAvailable:G}=Wo(),{clearStorage:F,isAvailable:ve}=Vo(),Mt=c??ee??void 0,Kt=i??b??void 0,jt=h??F??void 0,Vt={reactQuery:!!c||S,redux:!!i||G,asyncStorage:!!h||ve,mmkv:!!n},{isActive:$t,currentUser:Xe,headerKey:Xt,dataNukeSettings:Qt,showBanner:qt,searchQuery:_t,searchResults:Jt,isSearching:Yt,searchError:Gt,searchUsers:Qe,startImpersonation:qe,stopImpersonation:_e,updateHeaderKey:Je,updateDataNukeSettings:Ye,updateShowBanner:we,history:Zt,removeFromHistory:er,clearHistory:tr}=St({onSearchUsers:o,onClearReactQuery:Mt,onClearRedux:Kt,onClearAsyncStorage:jt,onClearMMKV:n});nt(()=>{C&&W.current&&setTimeout(()=>{W.current?.focus()},100)},[C]),nt(()=>{!d&&x==="settings"&&f("search")},[d,x]);let rr=te(_=>{Y(_)},[]),or=te(()=>{X.trim()&&Qe(X.trim()),I(false)},[X,Qe]),Ge=te(async _=>{await qe(_)},[qe]),ar=te(async(_,ir,sr)=>{await Je(_),await Ye(ir),await we(sr)},[Je,Ye,we]),nr=te(_=>{f(_),I(false)},[]),Ze=()=>Ee(re,{children:[r&&P(re.Navigation,{onBack:r}),P(re.Content,{title:"",children:C?P(re.Search,{value:X,onChangeText:rr,onCancel:()=>{Y(""),I(false)},onDismiss:()=>I(false),dismissOnBlur:true,placeholder:"Search by email, name, or ID...",iconSize:14,testID:"buoy-impersonate-search-input",inputProps:{onSubmitEditing:or}}):P(fo,{tabs:w,activeTab:x,onTabChange:nr})}),P(re.Actions,{children:x==="search"&&!C&&P(H,{testID:"buoy-impersonate-search-toggle",onPress:()=>I(true),style:fe.headerActionButton,children:P(bo,{size:14,color:dt.color.textSecondary})})})]});if(!e)return null;let et=Ee(s,{style:fe.container,children:[x==="search"&&P(kt,{currentUser:Xe,isActive:$t,searchQuery:_t,searchResults:Jt,isSearching:Yt,searchError:Gt,onSelectUser:Ge,onStopImpersonation:_e,searchAvailable:!!o}),x==="history"&&P(Bt,{history:Zt,currentUserId:Xe?.id??null,onSelectUser:Ge,onStopImpersonation:_e,onRemoveFromHistory:er,onClearHistory:tr}),x==="settings"&&P(Pt,{headerKey:Xt,settings:Qt,showBanner:qt,onSave:ar,onShowBannerChange:we,detectionStatus:Vt})]});return g?P(ut,{children:Ee(s,{style:fe.inlineRoot,children:[P(s,{style:fe.inlineHeader,...vo,children:Ze()}),et]})}):P(ut,{children:P(Sa,{visible:e,onClose:t,onMinimize:a,header:{showToggleButton:true,customContent:Ze()},enablePersistence:true,initialMode:"bottomSheet",disableScrollWrapper:true,children:et})})}function wa(e){return P(Oe,{...e,inline:true,visible:true,onClose:()=>{}})}var fe=M.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:So.border,backgroundColor:"transparent"},container:{flex:1},headerActionButton:{width:28,height:28,borderRadius:6,backgroundColor:dt.color.buttonSurface,justifyContent:"center",alignItems:"center"}});import{useSyncExternalStore as zt}from"react";import{buoyColors as Se,X as xa,PowerToggleButton as Ca}from"@buoy-gg/shared-ui/web";import{jsx as q,jsxs as We}from"react/jsx-runtime";function Fe({onPress:e,onStopPress:t,position:r="top",offset:a=50}){let o=zt(p.subscribe,p.getSnapshot,p.getSnapshot);if(!o.isActive||!o.currentUser||!o.showBanner)return null;let c=async()=>{console.log("[impersonate] banner pause/resume pressed"),o.isPaused?await p.resumeImpersonation():await p.pauseImpersonation()},i=o.currentUser.displayName||o.currentUser.email||o.currentUser.id,h=r==="top"?{top:a}:{bottom:a},n=async()=>{console.log("[impersonate] banner STOP pressed"),await p.stopImpersonation()};return q(s,{style:[V.container,h],children:We(s,{style:V.banner,children:[We(H,{style:V.userSection,onPress:e,activeOpacity:.7,children:[q(He,{userId:o.currentUser.id,name:i,size:"small",showActiveIndicator:false}),q(y,{style:[V.userName,o.isPaused&&V.userNamePaused],numberOfLines:1,children:i})]}),q(Ca,{isEnabled:!o.isPaused,onToggle:c,size:"small",accessibilityLabel:"Toggle impersonation"}),q(H,{style:V.closeButton,onPress:n,activeOpacity:.7,children:q(xa,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}function Ia({onPress:e}){let t=zt(p.subscribe,p.getSnapshot,p.getSnapshot);return!t.isActive||!t.currentUser?null:We(H,{style:V.minimalBanner,onPress:e,activeOpacity:.8,children:[q(s,{style:V.minimalDot}),q(y,{style:V.minimalText,children:"IMP"})]})}var V=M.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:Se.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:Se.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:Se.success},minimalText:{fontSize:10,fontWeight:"700",color:Se.success,letterSpacing:.5}});import{hasAccountAccess as ka,isOverWireBudget as Ta}from"@buoy-gg/shared-ui/web";var Me=null;function Ba(e){Me=e}var Ke=2*1024,Ra=16*1024,Dt=Object.freeze({__buoyOmitted:"user-metadata",note:"User metadata stays on the device."});function Aa(e){if(!e)return e;if(e.startsWith("data:")){let t=e.indexOf(",");return`${t>=0?e.slice(0,Math.min(t+1,64)):"data:"}[${e.length} chars]`}return e.length<=Ke?e:`${e.slice(0,Ke)}\u2026 [${e.length-Ke} more]`}function Ha(e){if(!e)return e;let t=typeof e.role=="string"?e.role:void 0;return Ta(e,Ra)?t?{role:t,...Dt}:{...Dt}:e}function je(e){return{...e,avatarUrl:Aa(e.avatarUrl),metadata:Ha(e.metadata)}}function Lt(e){return{...e,currentUser:e.currentUser?je(e.currentUser):null,history:e.history.map(t=>({...t,user:je(t.user)}))}}var Ve=new Map;function Ut(e){for(let t of e)t&&typeof t=="object"&&t.id&&Ve.set(String(t.id),t)}function Pa(e){let t=Ve.get(e);if(t)return t;let r=p.getState();return r.currentUser?.id===e?r.currentUser:r.history.find(a=>a.user.id===e)?.user}function Nt(e){if(!e||typeof e!="object"||!e.id)return false;if(Ve.has(String(e.id)))return true;let t=p.getState();return t.currentUser?.id===e.id?true:t.history.some(r=>r.user.id===e.id)}async function za(e,t){let r=k(t.userId),a=r??k(t.user?.id),o=(k(t.email)??k(t.user?.email))?.toLowerCase(),c=[k(t.user?.name),k(t.user?.displayName),k(t.query)].map(f=>f?.toLowerCase()).filter(f=>!!f),i=[o,a,k(t.query),k(t.user?.name),k(t.user?.displayName)].filter((f,C,I)=>!!f&&I.indexOf(f)===C),h=new Map;for(let f of i){let C;try{C=await e(f)}catch{continue}if(Array.isArray(C)){Ut(C);for(let I of C)I?.id&&h.set(String(I.id),I)}}let n=[...h.values()],d=f=>k(f.email)?.toLowerCase(),g=a?n.filter(f=>String(f.id)===a):[],w=o?n.filter(f=>d(f)===o):[];if(g.length===1&&w.length&&w[0].id!==g[0].id)throw new Error(`The id ${a} and the email ${o} belong to different users. Pass one of them.`);if(g.length===1)return g[0];if(r)return;if(w.length===1)return w[0];if(a||o)return;let x=n.filter(f=>{let C=f;return[k(C.displayName),k(C.name)].some(I=>I&&c.includes(I.toLowerCase()))});if(x.length>1)throw new Error(`${x.length} users are named that (${x.map(f=>f.id).join(", ")}). Pass the user's id or email.`);return x[0]}function k(e){return typeof e=="string"&&e.trim()?e.trim():typeof e=="number"?String(e):void 0}function Et(e){return{searchUsers:async t=>{let r=String(t?.query??""),a=await e(r);return Array.isArray(a)&&Ut(a),Array.isArray(a)?a.map(je):a},startImpersonation:async t=>{let r=t??{},a=r.user,o=k(r.userId),c=k(a?.id);if(o&&c&&o!==c)throw new Error(`userId ${o} and user.id ${c} are different users. Pass one of them.`);let i=k(r.email)?.toLowerCase(),h=k(a?.email)?.toLowerCase();if(i&&h&&i!==h)throw new Error(`email ${i} and user.email ${h} are different users. Pass one of them.`);let n;if(a?.id&&Nt(a)&&r.userId===void 0&&r.email===void 0?n=Pa(String(a.id)):n=await za(e,r),!n||!Nt(n))throw new Error("That user isn't in this app's directory. Call searchUsers and impersonate one of its results \u2014 a user object that didn't come from search impersonates nobody.");let d=(k(r.email)??k(a?.email))?.toLowerCase(),g=k(n.email)?.toLowerCase();if(d&&g&&d!==g)throw new Error(`User ${n.id} has a different email than ${d}. Pass the id or the email of one user.`);return await p.startImpersonation(n),{ok:true,userId:n.id}},stopImpersonation:()=>p.stopImpersonation(),pauseImpersonation:()=>p.pauseImpersonation(),resumeImpersonation:()=>p.resumeImpersonation(),updateSettings:t=>{let r=t??{},a=r.settings??(["headerKey","ignorePatterns","showBanner","dataNukeSettings"].some(o=>o in r)?r:void 0);if(!a)throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");return p.updateSettings(a)},removeFromHistory:t=>p.removeFromHistory(t.userId),clearHistory:()=>p.clearHistory()}}function Da({onSearchUsers:e}){return{version:1,getSnapshot:()=>Lt(p.getState()),subscribe:t=>p.subscribe(t),actions:Et(e)}}var La={dispose:()=>{ka()||p.disposeAccountSession()},version:1,getSnapshot:()=>Lt(p.getState()),subscribe:e=>p.subscribe(e),actions:Et(e=>{if(!Me)throw new Error("No onSearchUsers configured \u2014 pass it to createImpersonateTool()");return Me(e)})};import{ImpersonateIcon as Ot,IMPERSONATE_ICON_COLOR as Ua}from"@buoy-gg/shared-ui/web";import{jsx as Wt}from"react/jsx-runtime";var Ft=false;async function Na(){if(!(typeof window>"u"||Ft)){Ft=true,console.log("[impersonate] bootstrap: start"),O().isListening||O().startListening();try{let e=pr();if(!e||typeof e.getItem!="function"){console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(e??{}));return}let t={getItem:r=>e.getItem(r),setItem:(r,a)=>e.setItem(r,a)};p.setAsyncStorage(t),console.log("[impersonate] bootstrap: AsyncStorage adapter installed"),await p.initializeAsync(t),console.log("[impersonate] bootstrap: initializeAsync done")}catch(e){console.warn("[impersonate] bootstrap: failed",e)}}}function Ea(e){let{id:t="impersonate",name:r="IMPERSONATE",description:a="User impersonation for admin testing",defaults:o,showSettingsTab:c=true,onSearchUsers:i,onClearReactQuery:h,onClearRedux:n,onClearAsyncStorage:d,onClearMMKV:g}=e;return o&&p.setDeveloperDefaults(o),Ba(i??null),Na(),{id:t,name:r,description:a,slot:"both",icon:({size:w,slot:x})=>Wt(Ot,{size:x==="dial"?w*1.5:w,color:Ua}),component:w=>Wt(Oe,{...w,onSearchUsers:i,onClearReactQuery:h,onClearRedux:n,onClearAsyncStorage:d,onClearMMKV:g,showSettingsTab:c}),props:{enableSharedModalDimensions:false},Banner:Fe}}import{jsx as Oa}from"react/jsx-runtime";function Wa(){return Oa(Fe,{position:"top",offset:50})}import{buoyColors as ue,night as he,X as Fa}from"@buoy-gg/shared-ui/web";import{jsx as J,jsxs as be}from"react/jsx-runtime";function Ma({user:e,onStopImpersonation:t}){let r=e.displayName||e.email||e.id;return be(s,{style:$.container,children:[be(s,{style:$.userSection,children:[J(He,{userId:e.id,name:r,size:"small",showActiveIndicator:false}),J(s,{style:$.userInfo,children:J(y,{style:$.userName,numberOfLines:1,children:r})})]}),be(s,{style:$.statusPill,children:[J(s,{style:$.pulseDot}),J(y,{style:$.statusText,children:"Active"})]}),be(H,{style:$.stopButton,onPress:t,activeOpacity:.7,children:[J(Fa,{size:12,color:he.color.danger}),J(y,{style:$.stopButtonText,children:"Stop"})]})]})}var $=M.create({container:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:10,paddingHorizontal:16,backgroundColor:ue.success+"10",borderBottomWidth:1,borderBottomColor:ue.success+"25",gap:12},userSection:{flexDirection:"row",alignItems:"center",flex:1,gap:10,minWidth:0},userInfo:{flex:1,minWidth:0},userName:{fontSize:14,fontWeight:"600",color:he.color.text},statusPill:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:ue.success+"20",paddingHorizontal:10,paddingVertical:5,borderRadius:12},pulseDot:{width:6,height:6,borderRadius:3,backgroundColor:ue.success},statusText:{fontSize:11,fontWeight:"600",color:ue.success,textTransform:"uppercase",letterSpacing:.5},stopButton:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:12,paddingVertical:6,backgroundColor:he.color.dangerSoft,borderRadius:6,borderWidth:1,borderColor:he.color.danger+"30"},stopButtonText:{fontSize:12,fontWeight:"600",color:he.color.danger}});import{useCallback as $e,useSyncExternalStore as Ka}from"react";function ja(){let e=Ka(p.subscribe,p.getSnapshot,p.getSnapshot),t=$e(async o=>{await p.quickSwitch(o)},[]),r=$e(async o=>{await p.removeFromHistory(o)},[]),a=$e(async()=>{await p.clearHistory()},[]);return{history:e.history,currentUserId:e.currentUser?.id??null,quickSwitch:t,removeFromHistory:r,clearHistory:a}}export{Pt as DataNukeSettingsComponent,Fe as ImpersonateBanner,Ia as ImpersonateBannerMinimal,Bt as ImpersonateHistoryList,Ot as ImpersonateIcon,Oe as ImpersonateModal,Wa as ImpersonateOverlay,Ma as ImpersonateStatusBar,wa as ImpersonateToolView,kt as UserSearchView,Da as createImpersonateSyncAdapter,Ea as createImpersonateTool,Ao as getImpersonatedUserId,O as impersonateListener,p as impersonateStore,La as impersonateSyncAdapter,Ro as isImpersonating,mt as setImpersonateConfig,To as startImpersonateListener,Bo as stopImpersonateListener,St as useImpersonate,ja as useImpersonateHistory};
|
|
10
|
+
},`;try{await Rn(v),f(true),setTimeout(()=>f(false),2e3)}catch{}};return w(gt,{style:u.container,contentContainerStyle:u.contentContainer,children:[x&&g(d,{style:u.actionBar,children:w(d,{style:u.actionBarContent,children:[g(y,{style:u.unsavedText,children:"Unsaved changes"}),w(d,{style:u.actionButtons,children:[w(H,{style:u.discardButton,onPress:X,children:[g(Dt,{size:14,color:m.color.textSecondary}),g(y,{style:u.discardButtonText,children:"Discard"})]}),w(H,{style:u.saveButton,onPress:pe,children:[g(De,{size:14,color:m.color.onAccent}),g(y,{style:u.saveButtonText,children:"Save"})]})]})]})}),g(ie,{title:"Header Configuration",icon:xn,defaultOpen:true,variant:"bordered",children:w(d,{style:u.sectionContent,children:[g(y,{style:u.inputLabel,children:"Header Key"}),g(ht,{style:u.input,value:l,onChangeText:h,placeholder:"x-impersonate-user-id",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false}),w(d,{style:u.inputFooter,children:[g(y,{style:u.helperText,children:"The HTTP header key used for impersonation. Value will be the user ID."}),l!==ce&&g(H,{onPress:()=>h(ce),style:u.resetLink,children:g(y,{style:u.resetLinkText,children:"Reset to default"})})]})]})}),g(ie,{title:"Display",icon:Bn,defaultOpen:true,variant:"bordered",children:g(d,{style:u.sectionContent,children:g(d,{style:u.togglesCard,children:g(ue,{label:"Floating Banner",description:"Show a floating banner when impersonation is active",value:s,onChange:v=>{b(v),o(v)},recommended:true})})})}),g(ie,{title:"Data Clearing",icon:Lt,defaultOpen:true,variant:"bordered",children:w(d,{style:u.sectionContent,children:[g(y,{style:u.sectionDescription,children:"Choose what data to clear when impersonation starts or stops. This ensures you see fresh data for the impersonated user."}),w(d,{style:u.togglesCard,children:[g(ue,{label:"React Query",description:"Clear query cache and cancel pending queries",value:a.reactQuery,onChange:v=>K("reactQuery",v),recommended:true,detected:i?.reactQuery}),g(d,{style:u.divider}),g(ue,{label:"Redux",description:"Reset Redux store to initial state",value:a.redux,onChange:v=>K("redux",v),recommended:true,detected:i?.redux})]}),w(d,{style:u.advancedSection,children:[g(y,{style:u.advancedLabel,children:"Storage Options"}),w(d,{style:[u.togglesCard,u.dangerousCard],children:[g(ue,{label:"AsyncStorage",description:"Clear app data (preserves @buoy/* keys)",value:a.asyncStorage,onChange:v=>K("asyncStorage",v),dangerous:true,detected:i?.asyncStorage}),g(d,{style:u.divider}),g(ue,{label:"MMKV",description:"Clear MMKV storage (preserves @buoy/* keys)",value:a.mmkv,onChange:v=>K("mmkv",v),dangerous:true,detected:i?.mmkv})]})]}),(a.asyncStorage||a.mmkv)&&w(d,{style:u.warningCard,children:[g(Lt,{size:16,color:m.color.warning}),w(d,{style:u.warningContent,children:[g(y,{style:u.warningTitle,children:"Storage Clearing Enabled"}),g(y,{style:u.warningText,children:"This will remove app data like settings and cached content. Auth tokens managed by @buoy/* are preserved."})]})]})]})}),!I&&w(H,{style:u.restoreButton,onPress:Y,children:[g(Tn,{size:14,color:m.color.textSecondary}),g(y,{style:u.restoreButtonText,children:"Restore Defaults"})]}),g(ie,{title:"How It Works",icon:In,defaultOpen:false,variant:"bordered",children:w(d,{style:u.sectionContent,children:[g(y,{style:u.infoText,children:"When impersonation is enabled, the configured header is automatically added to all outgoing fetch and XMLHttpRequest calls."}),g(y,{style:[u.infoText,u.infoTextSpaced],children:"Your backend should check for this header and return data for the specified user ID instead of the authenticated user."}),w(d,{style:u.codeBlock,children:[g(y,{style:u.codeComment,children:"// Example request header"}),w(y,{style:u.codeText,children:[l||"x-impersonate-user-id",": ",g(y,{style:u.codeValue,children:"user_123"})]})]})]})}),g(ie,{title:"Export Configuration",icon:Nt,defaultOpen:false,variant:"bordered",children:w(d,{style:u.sectionContent,children:[g(y,{style:u.infoText,children:"Copy current settings to use in createImpersonateTool()."}),g(d,{style:u.dataViewerContainer,children:g(Hn,{title:"",data:ee,showTypeFilter:true,rawMode:true,initialExpanded:true})}),g(H,{style:u.copyButton,onPress:S,children:C?w(Ue,{children:[g(De,{size:14,color:le.success}),g(y,{style:[u.copyButtonText,u.copySuccessText],children:"Copied!"})]}):w(Ue,{children:[g(Nt,{size:14,color:m.color.accent}),g(y,{style:u.copyButtonText,children:"Copy Config"})]})})]})})]})}var u=F.create({container:{flex:1},contentContainer:{padding:16,gap:12,paddingBottom:32},actionBar:{backgroundColor:m.color.accentSoft,borderRadius:10,borderWidth:1,borderColor:m.color.accentBorder,padding:12},actionBarContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},unsavedText:{fontSize:13,fontWeight:"500",color:m.color.accent},actionButtons:{flexDirection:"row",gap:8},saveButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:m.color.accent,paddingHorizontal:14,paddingVertical:8,borderRadius:6},saveButtonText:{fontSize:13,fontWeight:"600",color:m.color.onAccent},discardButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:m.color.surfaceElevated,paddingHorizontal:14,paddingVertical:8,borderRadius:6,borderWidth:1,borderColor:m.color.border},discardButtonText:{fontSize:13,fontWeight:"500",color:m.color.textSecondary},restoreButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,paddingVertical:12,borderRadius:8,borderWidth:1,borderColor:m.color.border,borderStyle:"dashed"},restoreButtonText:{fontSize:13,color:m.color.textSecondary},sectionContent:{paddingTop:8},sectionDescription:{fontSize:13,color:m.color.textSecondary,lineHeight:18,marginBottom:14},togglesCard:{backgroundColor:m.color.surface,borderRadius:10,borderWidth:1,borderColor:m.color.border,padding:4},dangerousCard:{borderColor:m.color.warning+"30"},advancedSection:{marginTop:16},advancedLabel:{fontSize:11,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,marginBottom:8,marginLeft:2},inputLabel:{fontSize:12,fontWeight:"600",color:m.color.textSecondary,marginBottom:8},input:{height:42,backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:14,fontSize:14,color:m.color.text,fontFamily:Ne},inputFooter:{flexDirection:"row",justifyContent:"space-between",alignItems:"flex-start",marginTop:8,gap:12},helperText:{flex:1,fontSize:12,color:m.color.textTertiary,lineHeight:16},resetLink:{paddingVertical:2},resetLinkText:{fontSize:12,color:m.color.accent,fontWeight:"500"},recommendedBadge:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:m.color.accentSoft,paddingHorizontal:8,paddingVertical:3,borderRadius:4},recommendedText:{fontSize:10,fontWeight:"600",color:m.color.accent},detectedBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:8,paddingVertical:3,borderRadius:4},detectedBadgeActive:{backgroundColor:le.success+"15"},detectedBadgeInactive:{backgroundColor:m.color.textTertiary+"15"},detectedText:{fontSize:10,fontWeight:"600"},detectedTextActive:{color:le.success},detectedTextInactive:{color:m.color.textTertiary},divider:{height:1,backgroundColor:m.color.separator,marginHorizontal:12},warningCard:{marginTop:14,flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:m.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:m.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:13,fontWeight:"600",color:m.color.warning,marginBottom:4},warningText:{fontSize:12,color:m.color.textSecondary,lineHeight:17},infoText:{fontSize:13,color:m.color.textSecondary,lineHeight:19},infoTextSpaced:{marginTop:10},codeBlock:{marginTop:14,backgroundColor:m.color.bg,borderRadius:8,padding:14},codeComment:{fontSize:12,color:m.color.textTertiary,fontFamily:Ne,marginBottom:6},codeText:{fontSize:13,color:m.color.text,fontFamily:Ne},codeValue:{color:m.color.accent},dataViewerContainer:{marginTop:12,borderRadius:8,overflow:"hidden",borderWidth:1,borderColor:m.color.border},copyButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,marginTop:14,backgroundColor:m.color.accentSoft,paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderColor:m.color.accentBorder},copyButtonText:{fontSize:13,fontWeight:"600",color:m.color.accent},copySuccessText:{color:le.success}});import{jsx as P,jsxs as Ke}from"react/jsx-runtime";var Pn=Ro,zn=[{key:"search",label:"Search"},{key:"history",label:"History"},{key:"settings",label:"Settings"}],En=[{key:"search",label:"Search"},{key:"history",label:"History"}];function We({visible:e,onClose:t,onBack:r,onMinimize:n,onSearchUsers:o,onClearReactQuery:i,onClearRedux:l,onClearAsyncStorage:h,onClearMMKV:a,showSettingsTab:c=true,inline:s=false}){let b=c?zn:En,[C,f]=xe("search"),[x,I]=xe(false),pe=st(false),[X,Y]=xe(""),K=st(null),{clearCache:ee,isAvailable:S}=Xo(),{resetStore:v,isAvailable:G}=Yo(),{clearStorage:W,isAvailable:we}=rn(),Qt=i??ee??void 0,qt=l??v??void 0,_t=h??W??void 0,Jt={reactQuery:!!i||S,redux:!!l||G,asyncStorage:!!h||we,mmkv:!!a},{isActive:Yt,currentUser:qe,headerKey:Gt,dataNukeSettings:Zt,showBanner:er,searchQuery:tr,searchResults:rr,isSearching:or,searchError:nr,searchUsers:_e,startImpersonation:Je,stopImpersonation:Ye,updateHeaderKey:Ge,updateDataNukeSettings:Ze,updateShowBanner:Ce,history:ar,removeFromHistory:sr,clearHistory:ir}=It({onSearchUsers:o,onClearReactQuery:Qt,onClearRedux:qt,onClearAsyncStorage:_t,onClearMMKV:a});it(()=>{x&&K.current&&setTimeout(()=>{K.current?.focus()},100)},[x]),it(()=>{!c&&C==="settings"&&f("search")},[c,C]);let lr=te(_=>{Y(_)},[]),cr=te(()=>{X.trim()&&_e(X.trim()),I(false)},[X,_e]),et=te(async _=>{await Je(_)},[Je]),dr=te(async(_,hr,gr)=>{await Ge(_),await Ze(hr),await Ce(gr)},[Ge,Ze,Ce]),ur=te(_=>{f(_),I(false)},[]),tt=()=>Ke(oe,{children:[r&&P(oe.Navigation,{onBack:r}),P(oe.Content,{title:"",children:x?P(oe.Search,{value:X,onChangeText:lr,onCancel:()=>{Y(""),I(false)},onDismiss:()=>I(false),dismissOnBlur:true,placeholder:"Search by email, name, or ID...",iconSize:14,testID:"buoy-impersonate-search-input",inputProps:{onSubmitEditing:cr}}):P(Ao,{tabs:b,activeTab:C,onTabChange:ur})}),P(oe.Actions,{children:C==="search"&&!x&&P(H,{testID:"buoy-impersonate-search-toggle",onPress:()=>I(true),style:be.headerActionButton,children:P(Po,{size:14,color:yt.color.textSecondary})})})]});if(!e)return null;let rt=Ke(d,{style:be.container,children:[C==="search"&&P(Pt,{currentUser:qe,isActive:Yt,searchQuery:tr,searchResults:rr,isSearching:or,searchError:nr,onSelectUser:et,onStopImpersonation:Ye,searchAvailable:!!o}),C==="history"&&P(Et,{history:ar,currentUserId:qe?.id??null,onSelectUser:et,onStopImpersonation:Ye,onRemoveFromHistory:sr,onClearHistory:ir}),C==="settings"&&P(Ut,{headerKey:Gt,settings:Zt,showBanner:er,onSave:dr,onShowBannerChange:Ce,detectionStatus:Jt})]});return s?P(ft,{children:Ke(d,{style:be.inlineRoot,children:[P(d,{style:be.inlineHeader,...zo,children:tt()}),rt]})}):P(ft,{children:P(Pn,{visible:e,onClose:t,onMinimize:n,header:{showToggleButton:true,customContent:tt()},enablePersistence:true,initialMode:"bottomSheet",disableScrollWrapper:true,children:rt})})}function Ln(e){return P(We,{...e,inline:true,visible:true,onClose:()=>{}})}var be=F.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Ho.border,backgroundColor:"transparent"},container:{flex:1},headerActionButton:{width:28,height:28,borderRadius:6,backgroundColor:yt.color.buttonSurface,justifyContent:"center",alignItems:"center"}});import{useSyncExternalStore as Ot}from"react";import{buoyColors as Se,X as Dn,PowerToggleButton as Nn}from"@buoy-gg/shared-ui/web";import{jsx as q,jsxs as Fe}from"react/jsx-runtime";function Me({onPress:e,onStopPress:t,position:r="top",offset:n=50}){let o=Ot(p.subscribe,p.getSnapshot,p.getSnapshot);if(!o.isActive||!o.currentUser||!o.showBanner)return null;let i=async()=>{console.log("[Buoy]","[impersonate] banner pause/resume pressed"),o.isPaused?await p.resumeImpersonation():await p.pauseImpersonation()},l=o.currentUser.displayName||o.currentUser.email||o.currentUser.id,h=r==="top"?{top:n}:{bottom:n},a=async()=>{console.log("[Buoy]","[impersonate] banner STOP pressed"),await p.stopImpersonation()};return q(d,{style:[V.container,h],children:Fe(d,{style:V.banner,children:[Fe(H,{style:V.userSection,onPress:e,activeOpacity:.7,children:[q(ze,{userId:o.currentUser.id,name:l,size:"small",showActiveIndicator:false}),q(y,{style:[V.userName,o.isPaused&&V.userNamePaused],numberOfLines:1,children:l})]}),q(Nn,{isEnabled:!o.isPaused,onToggle:i,size:"small",accessibilityLabel:"Toggle impersonation"}),q(H,{style:V.closeButton,onPress:a,activeOpacity:.7,children:q(Dn,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}function Un({onPress:e}){let t=Ot(p.subscribe,p.getSnapshot,p.getSnapshot);return!t.isActive||!t.currentUser?null:Fe(H,{style:V.minimalBanner,onPress:e,activeOpacity:.8,children:[q(d,{style:V.minimalDot}),q(y,{style:V.minimalText,children:"IMP"})]})}var V=F.create({container:{position:"absolute",left:0,right:0,alignItems:"center",zIndex:9999,pointerEvents:"box-none"},banner:{flexDirection:"row",alignItems:"center",backgroundColor:"rgba(20, 20, 20, 0.94)",borderWidth:1,borderColor:Se.success+"40",borderRadius:22,paddingVertical:7,paddingLeft:7,paddingRight:10,gap:10,marginTop:3,shadowColor:"#000",shadowOffset:{width:0,height:6},shadowOpacity:.3,shadowRadius:14,elevation:10},userSection:{flexDirection:"row",alignItems:"center",gap:10},userName:{fontSize:14,fontWeight:"600",color:"#fff",maxWidth:180},userNamePaused:{opacity:.6},closeButton:{width:22,height:22,borderRadius:11,backgroundColor:"rgba(128, 128, 128, 0.16)",alignItems:"center",justifyContent:"center",marginLeft:-4},minimalBanner:{position:"absolute",top:60,right:16,flexDirection:"row",alignItems:"center",backgroundColor:"rgba(26, 26, 26, 0.92)",borderWidth:1,borderColor:Se.success+"35",borderRadius:12,paddingVertical:5,paddingHorizontal:10,gap:5,zIndex:9999,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.2,shadowRadius:6,elevation:4},minimalDot:{width:6,height:6,borderRadius:3,backgroundColor:Se.success},minimalText:{fontSize:10,fontWeight:"700",color:Se.success,letterSpacing:.5}});import{hasAccountAccess as On,isOverWireBudget as Kn}from"@buoy-gg/shared-ui/web";var je=null;function Wn(e){je=e}var Ve=2*1024,Fn=16*1024,Kt=Object.freeze({__buoyOmitted:"user-metadata",note:"User metadata stays on the device."});function Mn(e){if(!e)return e;if(e.startsWith("data:")){let t=e.indexOf(",");return`${t>=0?e.slice(0,Math.min(t+1,64)):"data:"}[${e.length} chars]`}return e.length<=Ve?e:`${e.slice(0,Ve)}\u2026 [${e.length-Ve} more]`}function jn(e){if(!e)return e;let t=typeof e.role=="string"?e.role:void 0;return Kn(e,Fn)?t?{role:t,...Kt}:{...Kt}:e}function $e(e){return{...e,avatarUrl:Mn(e.avatarUrl),metadata:jn(e.metadata)}}function Wt(e){return{...e,currentUser:e.currentUser?$e(e.currentUser):null,history:e.history.map(t=>({...t,user:$e(t.user)}))}}var Xe=new Map;function Ft(e){for(let t of e)t&&typeof t=="object"&&t.id&&Xe.set(String(t.id),t)}function Vn(e){let t=Xe.get(e);if(t)return t;let r=p.getState();return r.currentUser?.id===e?r.currentUser:r.history.find(n=>n.user.id===e)?.user}function Mt(e){if(!e||typeof e!="object"||!e.id)return false;if(Xe.has(String(e.id)))return true;let t=p.getState();return t.currentUser?.id===e.id?true:t.history.some(r=>r.user.id===e.id)}async function $n(e,t){let r=k(t.userId),n=r??k(t.user?.id),o=(k(t.email)??k(t.user?.email))?.toLowerCase(),i=[k(t.user?.name),k(t.user?.displayName),k(t.query)].map(f=>f?.toLowerCase()).filter(f=>!!f),l=[o,n,k(t.query),k(t.user?.name),k(t.user?.displayName)].filter((f,x,I)=>!!f&&I.indexOf(f)===x),h=new Map;for(let f of l){let x;try{x=await e(f)}catch{continue}if(Array.isArray(x)){Ft(x);for(let I of x)I?.id&&h.set(String(I.id),I)}}let a=[...h.values()],c=f=>k(f.email)?.toLowerCase(),s=n?a.filter(f=>String(f.id)===n):[],b=o?a.filter(f=>c(f)===o):[];if(s.length===1&&b.length&&b[0].id!==s[0].id)throw new Error(`The id ${n} and the email ${o} belong to different users. Pass one of them.`);if(s.length===1)return s[0];if(r)return;if(b.length===1)return b[0];if(n||o)return;let C=a.filter(f=>{let x=f;return[k(x.displayName),k(x.name)].some(I=>I&&i.includes(I.toLowerCase()))});if(C.length>1)throw new Error(`${C.length} users are named that (${C.map(f=>f.id).join(", ")}). Pass the user's id or email.`);return C[0]}function k(e){return typeof e=="string"&&e.trim()?e.trim():typeof e=="number"?String(e):void 0}function jt(e){return{searchUsers:async t=>{let r=String(t?.query??""),n=await e(r);return Array.isArray(n)&&Ft(n),Array.isArray(n)?n.map($e):n},startImpersonation:async t=>{let r=t??{},n=r.user,o=k(r.userId),i=k(n?.id);if(o&&i&&o!==i)throw new Error(`userId ${o} and user.id ${i} are different users. Pass one of them.`);let l=k(r.email)?.toLowerCase(),h=k(n?.email)?.toLowerCase();if(l&&h&&l!==h)throw new Error(`email ${l} and user.email ${h} are different users. Pass one of them.`);let a;if(n?.id&&Mt(n)&&r.userId===void 0&&r.email===void 0?a=Vn(String(n.id)):a=await $n(e,r),!a||!Mt(a))throw new Error("That user isn't in this app's directory. Call searchUsers and impersonate one of its results \u2014 a user object that didn't come from search impersonates nobody.");let c=(k(r.email)??k(n?.email))?.toLowerCase(),s=k(a.email)?.toLowerCase();if(c&&s&&c!==s)throw new Error(`User ${a.id} has a different email than ${c}. Pass the id or the email of one user.`);return await p.startImpersonation(a),{ok:true,userId:a.id}},stopImpersonation:()=>p.stopImpersonation(),pauseImpersonation:()=>p.pauseImpersonation(),resumeImpersonation:()=>p.resumeImpersonation(),updateSettings:t=>{let r=t??{},n=r.settings??(["headerKey","ignorePatterns","showBanner","dataNukeSettings"].some(o=>o in r)?r:void 0);if(!n)throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");return p.updateSettings(n)},removeFromHistory:t=>p.removeFromHistory(t.userId),clearHistory:()=>p.clearHistory()}}function Xn({onSearchUsers:e}){return{version:1,getSnapshot:()=>Wt(p.getState()),subscribe:t=>p.subscribe(t),actions:jt(e)}}var Qn={dispose:()=>{On()||p.disposeAccountSession()},version:1,getSnapshot:()=>Wt(p.getState()),subscribe:e=>p.subscribe(e),actions:jt(e=>{if(!je)throw new Error("No onSearchUsers configured \u2014 pass it to createImpersonateTool()");return je(e)})};import{ImpersonateIcon as Vt,IMPERSONATE_ICON_COLOR as qn}from"@buoy-gg/shared-ui/web";import{jsx as $t}from"react/jsx-runtime";var Xt=false;async function _n(){if(!(typeof window>"u"||Xt)){Xt=true,console.log("[Buoy]","[impersonate] bootstrap: start"),O().isListening||O().startListening();try{let e=vr();if(!e||typeof e.getItem!="function"){console.warn("[Buoy]","[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(e??{}));return}let t={getItem:r=>e.getItem(r),setItem:(r,n)=>e.setItem(r,n)};p.setAsyncStorage(t),console.log("[Buoy]","[impersonate] bootstrap: AsyncStorage adapter installed"),await p.initializeAsync(t),console.log("[Buoy]","[impersonate] bootstrap: initializeAsync done")}catch(e){console.warn("[Buoy]","[impersonate] bootstrap: failed",e)}}}function Jn(e){let{id:t="impersonate",name:r="IMPERSONATE",description:n="User impersonation for admin testing",defaults:o,showSettingsTab:i=true,onSearchUsers:l,onClearReactQuery:h,onClearRedux:a,onClearAsyncStorage:c,onClearMMKV:s}=e;return o&&p.setDeveloperDefaults(o),Wn(l??null),_n(),{id:t,name:r,description:n,slot:"both",icon:({size:b,slot:C})=>$t(Vt,{size:C==="dial"?b*1.5:b,color:qn}),component:b=>$t(We,{...b,onSearchUsers:l,onClearReactQuery:h,onClearRedux:a,onClearAsyncStorage:c,onClearMMKV:s,showSettingsTab:i}),props:{enableSharedModalDimensions:false},Banner:Me}}import{jsx as Yn}from"react/jsx-runtime";function Gn(){return Yn(Me,{position:"top",offset:50})}import{buoyColors as he,night as ge,X as Zn}from"@buoy-gg/shared-ui/web";import{jsx as J,jsxs as ve}from"react/jsx-runtime";function ea({user:e,onStopImpersonation:t}){let r=e.displayName||e.email||e.id;return ve(d,{style:$.container,children:[ve(d,{style:$.userSection,children:[J(ze,{userId:e.id,name:r,size:"small",showActiveIndicator:false}),J(d,{style:$.userInfo,children:J(y,{style:$.userName,numberOfLines:1,children:r})})]}),ve(d,{style:$.statusPill,children:[J(d,{style:$.pulseDot}),J(y,{style:$.statusText,children:"Active"})]}),ve(H,{style:$.stopButton,onPress:t,activeOpacity:.7,children:[J(Zn,{size:12,color:ge.color.danger}),J(y,{style:$.stopButtonText,children:"Stop"})]})]})}var $=F.create({container:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:10,paddingHorizontal:16,backgroundColor:he.success+"10",borderBottomWidth:1,borderBottomColor:he.success+"25",gap:12},userSection:{flexDirection:"row",alignItems:"center",flex:1,gap:10,minWidth:0},userInfo:{flex:1,minWidth:0},userName:{fontSize:14,fontWeight:"600",color:ge.color.text},statusPill:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:he.success+"20",paddingHorizontal:10,paddingVertical:5,borderRadius:12},pulseDot:{width:6,height:6,borderRadius:3,backgroundColor:he.success},statusText:{fontSize:11,fontWeight:"600",color:he.success,textTransform:"uppercase",letterSpacing:.5},stopButton:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:12,paddingVertical:6,backgroundColor:ge.color.dangerSoft,borderRadius:6,borderWidth:1,borderColor:ge.color.danger+"30"},stopButtonText:{fontSize:12,fontWeight:"600",color:ge.color.danger}});import{useCallback as Qe,useSyncExternalStore as ta}from"react";function ra(){let e=ta(p.subscribe,p.getSnapshot,p.getSnapshot),t=Qe(async o=>{await p.quickSwitch(o)},[]),r=Qe(async o=>{await p.removeFromHistory(o)},[]),n=Qe(async()=>{await p.clearHistory()},[]);return{history:e.history,currentUserId:e.currentUser?.id??null,quickSwitch:t,removeFromHistory:r,clearHistory:n}}export{Ut as DataNukeSettingsComponent,Me as ImpersonateBanner,Un as ImpersonateBannerMinimal,Et as ImpersonateHistoryList,Vt as ImpersonateIcon,We as ImpersonateModal,Gn as ImpersonateOverlay,ea as ImpersonateStatusBar,Ln as ImpersonateToolView,Pt as UserSearchView,Xn as createImpersonateSyncAdapter,Jn as createImpersonateTool,Fo as getImpersonatedUserId,O as impersonateListener,p as impersonateStore,Qn as impersonateSyncAdapter,Wo as isImpersonating,wt as setImpersonateConfig,Oo as startImpersonateListener,Ko as stopImpersonateListener,It as useImpersonate,ra as useImpersonateHistory};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/impersonate",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.64",
|
|
4
4
|
"description": "Configure impersonation headers for supported app requests. Your backend must authenticate and authorize user changes.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"sideEffects": false,
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
37
|
+
"@buoy-gg/shared-ui": "^7.0.64"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react": "*"
|