@buoy-gg/impersonate 7.0.41 → 7.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -80
- package/lib/commonjs/impersonate/components/DataNukeSettings.js +8 -675
- package/lib/commonjs/impersonate/components/ImpersonateBanner.js +1 -221
- package/lib/commonjs/impersonate/components/ImpersonateHistoryList.js +1 -181
- package/lib/commonjs/impersonate/components/ImpersonateModal.js +1 -319
- package/lib/commonjs/impersonate/components/ImpersonateOverlay.js +1 -26
- package/lib/commonjs/impersonate/components/ImpersonateStatusBar.js +1 -130
- package/lib/commonjs/impersonate/components/UserAvatar.js +1 -146
- package/lib/commonjs/impersonate/components/UserCard.js +1 -201
- package/lib/commonjs/impersonate/components/UserSearchView.js +1 -227
- package/lib/commonjs/impersonate/hooks/asyncStoragePeer.js +1 -17
- package/lib/commonjs/impersonate/hooks/asyncStoragePeer.web.js +1 -11
- package/lib/commonjs/impersonate/hooks/useAutoClearAsyncStorage.js +1 -134
- package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.js +1 -155
- package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.web.js +1 -20
- package/lib/commonjs/impersonate/hooks/useAutoClearRedux.js +1 -188
- package/lib/commonjs/impersonate/hooks/useAutoClearRedux.web.js +1 -27
- package/lib/commonjs/impersonate/hooks/useImpersonate.js +1 -215
- package/lib/commonjs/impersonate/hooks/useImpersonateHistory.js +1 -56
- package/lib/commonjs/impersonate/types/index.js +1 -16
- package/lib/commonjs/impersonate/types/types.js +1 -1
- package/lib/commonjs/impersonate/utils/impersonateListener.js +1 -350
- package/lib/commonjs/impersonate/utils/impersonateStore.js +1 -689
- package/lib/commonjs/index.js +1 -150
- package/lib/commonjs/preset.js +1 -232
- package/lib/commonjs/sync/impersonateSyncAdapter.js +1 -170
- package/lib/module/impersonate/components/DataNukeSettings.js +8 -670
- package/lib/module/impersonate/components/ImpersonateBanner.js +1 -215
- package/lib/module/impersonate/components/ImpersonateHistoryList.js +1 -176
- package/lib/module/impersonate/components/ImpersonateModal.js +1 -314
- package/lib/module/impersonate/components/ImpersonateOverlay.js +1 -21
- package/lib/module/impersonate/components/ImpersonateStatusBar.js +1 -125
- package/lib/module/impersonate/components/UserAvatar.js +1 -140
- package/lib/module/impersonate/components/UserCard.js +1 -196
- package/lib/module/impersonate/components/UserSearchView.js +1 -222
- package/lib/module/impersonate/hooks/asyncStoragePeer.js +1 -13
- package/lib/module/impersonate/hooks/asyncStoragePeer.web.js +1 -6
- package/lib/module/impersonate/hooks/useAutoClearAsyncStorage.js +1 -130
- package/lib/module/impersonate/hooks/useAutoClearReactQuery.js +1 -151
- package/lib/module/impersonate/hooks/useAutoClearReactQuery.web.js +1 -16
- package/lib/module/impersonate/hooks/useAutoClearRedux.js +1 -183
- package/lib/module/impersonate/hooks/useAutoClearRedux.web.js +1 -22
- package/lib/module/impersonate/hooks/useImpersonate.js +1 -212
- package/lib/module/impersonate/hooks/useImpersonateHistory.js +1 -52
- package/lib/module/impersonate/types/index.js +1 -3
- package/lib/module/impersonate/types/types.js +1 -1
- package/lib/module/impersonate/utils/impersonateListener.js +1 -341
- package/lib/module/impersonate/utils/impersonateStore.js +1 -686
- package/lib/module/index.js +1 -117
- package/lib/module/preset.js +1 -216
- package/lib/module/sync/impersonateSyncAdapter.js +1 -162
- package/lib/web/index.mjs +7 -8
- package/package.json +3 -6
- package/lib/typescript/impersonate/components/DataNukeSettings.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/ImpersonateBanner.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/ImpersonateHistoryList.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/ImpersonateModal.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/ImpersonateOverlay.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/ImpersonateStatusBar.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/UserAvatar.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/UserCard.d.ts.map +0 -1
- package/lib/typescript/impersonate/components/UserSearchView.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useAutoClearRedux.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useImpersonate.d.ts.map +0 -1
- package/lib/typescript/impersonate/hooks/useImpersonateHistory.d.ts.map +0 -1
- package/lib/typescript/impersonate/types/index.d.ts.map +0 -1
- package/lib/typescript/impersonate/types/types.d.ts.map +0 -1
- package/lib/typescript/impersonate/utils/impersonateListener.d.ts.map +0 -1
- package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +0 -1
package/lib/commonjs/index.js
CHANGED
|
@@ -1,150 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "DataNukeSettingsComponent", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _DataNukeSettings.DataNukeSettings;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "ImpersonateBanner", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _ImpersonateBanner.ImpersonateBanner;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, "ImpersonateBannerMinimal", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
21
|
-
return _ImpersonateBanner.ImpersonateBannerMinimal;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, "ImpersonateHistoryList", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
27
|
-
return _ImpersonateHistoryList.ImpersonateHistoryList;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
Object.defineProperty(exports, "ImpersonateIcon", {
|
|
31
|
-
enumerable: true,
|
|
32
|
-
get: function () {
|
|
33
|
-
return _preset.ImpersonateIcon;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
Object.defineProperty(exports, "ImpersonateModal", {
|
|
37
|
-
enumerable: true,
|
|
38
|
-
get: function () {
|
|
39
|
-
return _ImpersonateModal.ImpersonateModal;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
Object.defineProperty(exports, "ImpersonateOverlay", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
get: function () {
|
|
45
|
-
return _ImpersonateOverlay.ImpersonateOverlay;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
Object.defineProperty(exports, "ImpersonateStatusBar", {
|
|
49
|
-
enumerable: true,
|
|
50
|
-
get: function () {
|
|
51
|
-
return _ImpersonateStatusBar.ImpersonateStatusBar;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
Object.defineProperty(exports, "ImpersonateToolView", {
|
|
55
|
-
enumerable: true,
|
|
56
|
-
get: function () {
|
|
57
|
-
return _ImpersonateModal.ImpersonateToolView;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
Object.defineProperty(exports, "UserSearchView", {
|
|
61
|
-
enumerable: true,
|
|
62
|
-
get: function () {
|
|
63
|
-
return _UserSearchView.UserSearchView;
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
Object.defineProperty(exports, "createImpersonateSyncAdapter", {
|
|
67
|
-
enumerable: true,
|
|
68
|
-
get: function () {
|
|
69
|
-
return _impersonateSyncAdapter.createImpersonateSyncAdapter;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
Object.defineProperty(exports, "createImpersonateTool", {
|
|
73
|
-
enumerable: true,
|
|
74
|
-
get: function () {
|
|
75
|
-
return _preset.createImpersonateTool;
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
Object.defineProperty(exports, "getImpersonatedUserId", {
|
|
79
|
-
enumerable: true,
|
|
80
|
-
get: function () {
|
|
81
|
-
return _impersonateListener.getImpersonatedUserId;
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
Object.defineProperty(exports, "impersonateListener", {
|
|
85
|
-
enumerable: true,
|
|
86
|
-
get: function () {
|
|
87
|
-
return _impersonateListener.impersonateListener;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
Object.defineProperty(exports, "impersonateStore", {
|
|
91
|
-
enumerable: true,
|
|
92
|
-
get: function () {
|
|
93
|
-
return _impersonateStore.impersonateStore;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
Object.defineProperty(exports, "impersonateSyncAdapter", {
|
|
97
|
-
enumerable: true,
|
|
98
|
-
get: function () {
|
|
99
|
-
return _impersonateSyncAdapter.impersonateSyncAdapter;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
Object.defineProperty(exports, "isImpersonating", {
|
|
103
|
-
enumerable: true,
|
|
104
|
-
get: function () {
|
|
105
|
-
return _impersonateListener.isImpersonating;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
Object.defineProperty(exports, "setImpersonateConfig", {
|
|
109
|
-
enumerable: true,
|
|
110
|
-
get: function () {
|
|
111
|
-
return _impersonateListener.setImpersonateConfig;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
Object.defineProperty(exports, "startImpersonateListener", {
|
|
115
|
-
enumerable: true,
|
|
116
|
-
get: function () {
|
|
117
|
-
return _impersonateListener.startImpersonateListener;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
Object.defineProperty(exports, "stopImpersonateListener", {
|
|
121
|
-
enumerable: true,
|
|
122
|
-
get: function () {
|
|
123
|
-
return _impersonateListener.stopImpersonateListener;
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
Object.defineProperty(exports, "useImpersonate", {
|
|
127
|
-
enumerable: true,
|
|
128
|
-
get: function () {
|
|
129
|
-
return _useImpersonate.useImpersonate;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
Object.defineProperty(exports, "useImpersonateHistory", {
|
|
133
|
-
enumerable: true,
|
|
134
|
-
get: function () {
|
|
135
|
-
return _useImpersonateHistory.useImpersonateHistory;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
var _preset = require("./preset");
|
|
139
|
-
var _impersonateSyncAdapter = require("./sync/impersonateSyncAdapter");
|
|
140
|
-
var _ImpersonateModal = require("./impersonate/components/ImpersonateModal");
|
|
141
|
-
var _ImpersonateBanner = require("./impersonate/components/ImpersonateBanner");
|
|
142
|
-
var _ImpersonateOverlay = require("./impersonate/components/ImpersonateOverlay");
|
|
143
|
-
var _UserSearchView = require("./impersonate/components/UserSearchView");
|
|
144
|
-
var _DataNukeSettings = require("./impersonate/components/DataNukeSettings");
|
|
145
|
-
var _ImpersonateHistoryList = require("./impersonate/components/ImpersonateHistoryList");
|
|
146
|
-
var _ImpersonateStatusBar = require("./impersonate/components/ImpersonateStatusBar");
|
|
147
|
-
var _useImpersonate = require("./impersonate/hooks/useImpersonate");
|
|
148
|
-
var _useImpersonateHistory = require("./impersonate/hooks/useImpersonateHistory");
|
|
149
|
-
var _impersonateStore = require("./impersonate/utils/impersonateStore");
|
|
150
|
-
var _impersonateListener = require("./impersonate/utils/impersonateListener");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"DataNukeSettingsComponent",{enumerable:true,get:function(){return _DataNukeSettings.DataNukeSettings}});Object.defineProperty(exports,"ImpersonateBanner",{enumerable:true,get:function(){return _ImpersonateBanner.ImpersonateBanner}});Object.defineProperty(exports,"ImpersonateBannerMinimal",{enumerable:true,get:function(){return _ImpersonateBanner.ImpersonateBannerMinimal}});Object.defineProperty(exports,"ImpersonateHistoryList",{enumerable:true,get:function(){return _ImpersonateHistoryList.ImpersonateHistoryList}});Object.defineProperty(exports,"ImpersonateIcon",{enumerable:true,get:function(){return _preset.ImpersonateIcon}});Object.defineProperty(exports,"ImpersonateModal",{enumerable:true,get:function(){return _ImpersonateModal.ImpersonateModal}});Object.defineProperty(exports,"ImpersonateOverlay",{enumerable:true,get:function(){return _ImpersonateOverlay.ImpersonateOverlay}});Object.defineProperty(exports,"ImpersonateStatusBar",{enumerable:true,get:function(){return _ImpersonateStatusBar.ImpersonateStatusBar}});Object.defineProperty(exports,"ImpersonateToolView",{enumerable:true,get:function(){return _ImpersonateModal.ImpersonateToolView}});Object.defineProperty(exports,"UserSearchView",{enumerable:true,get:function(){return _UserSearchView.UserSearchView}});Object.defineProperty(exports,"createImpersonateSyncAdapter",{enumerable:true,get:function(){return _impersonateSyncAdapter.createImpersonateSyncAdapter}});Object.defineProperty(exports,"createImpersonateTool",{enumerable:true,get:function(){return _preset.createImpersonateTool}});Object.defineProperty(exports,"getImpersonatedUserId",{enumerable:true,get:function(){return _impersonateListener.getImpersonatedUserId}});Object.defineProperty(exports,"impersonateListener",{enumerable:true,get:function(){return _impersonateListener.impersonateListener}});Object.defineProperty(exports,"impersonateStore",{enumerable:true,get:function(){return _impersonateStore.impersonateStore}});Object.defineProperty(exports,"impersonateSyncAdapter",{enumerable:true,get:function(){return _impersonateSyncAdapter.impersonateSyncAdapter}});Object.defineProperty(exports,"isImpersonating",{enumerable:true,get:function(){return _impersonateListener.isImpersonating}});Object.defineProperty(exports,"setImpersonateConfig",{enumerable:true,get:function(){return _impersonateListener.setImpersonateConfig}});Object.defineProperty(exports,"startImpersonateListener",{enumerable:true,get:function(){return _impersonateListener.startImpersonateListener}});Object.defineProperty(exports,"stopImpersonateListener",{enumerable:true,get:function(){return _impersonateListener.stopImpersonateListener}});Object.defineProperty(exports,"useImpersonate",{enumerable:true,get:function(){return _useImpersonate.useImpersonate}});Object.defineProperty(exports,"useImpersonateHistory",{enumerable:true,get:function(){return _useImpersonateHistory.useImpersonateHistory}});var _preset=require("./preset");var _impersonateSyncAdapter=require("./sync/impersonateSyncAdapter");var _ImpersonateModal=require("./impersonate/components/ImpersonateModal");var _ImpersonateBanner=require("./impersonate/components/ImpersonateBanner");var _ImpersonateOverlay=require("./impersonate/components/ImpersonateOverlay");var _UserSearchView=require("./impersonate/components/UserSearchView");var _DataNukeSettings=require("./impersonate/components/DataNukeSettings");var _ImpersonateHistoryList=require("./impersonate/components/ImpersonateHistoryList");var _ImpersonateStatusBar=require("./impersonate/components/ImpersonateStatusBar");var _useImpersonate=require("./impersonate/hooks/useImpersonate");var _useImpersonateHistory=require("./impersonate/hooks/useImpersonateHistory");var _impersonateStore=require("./impersonate/utils/impersonateStore");var _impersonateListener=require("./impersonate/utils/impersonateListener");
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -1,232 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "IMPERSONATE_ICON_COLOR", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _sharedUi.IMPERSONATE_ICON_COLOR;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "ImpersonateIcon", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _sharedUi.ImpersonateIcon;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
exports.createImpersonateTool = createImpersonateTool;
|
|
19
|
-
var _asyncStoragePeer = require("./impersonate/hooks/asyncStoragePeer");
|
|
20
|
-
var _react = _interopRequireDefault(require("react"));
|
|
21
|
-
var _ImpersonateModal = require("./impersonate/components/ImpersonateModal");
|
|
22
|
-
var _ImpersonateBanner = require("./impersonate/components/ImpersonateBanner");
|
|
23
|
-
var _impersonateStore = require("./impersonate/utils/impersonateStore");
|
|
24
|
-
var _impersonateListener = require("./impersonate/utils/impersonateListener");
|
|
25
|
-
var _impersonateSyncAdapter = require("./sync/impersonateSyncAdapter");
|
|
26
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
27
|
-
var _jsxRuntime = require("react/jsx-runtime");
|
|
28
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
|
-
/**
|
|
30
|
-
* Impersonate Tool Preset
|
|
31
|
-
*
|
|
32
|
-
* Factory function to create a configured impersonate tool for FloatingDevTools.
|
|
33
|
-
* No default preset is exported because configuration (onSearchUsers) is required.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
// =============================================================================
|
|
37
|
-
// EAGER BOOTSTRAP
|
|
38
|
-
// =============================================================================
|
|
39
|
-
// Patch fetch/XHR and restore persisted state the moment createImpersonateTool
|
|
40
|
-
// runs (typically at module load in the host app). If we waited until the
|
|
41
|
-
// modal mounts (the original lazy design), every request fired during app
|
|
42
|
-
// boot — bridge polls, user-data fetches, etc. — goes out without the
|
|
43
|
-
// impersonation header, even when the user already had impersonation active
|
|
44
|
-
// from a previous session. React Query then caches the real-account response,
|
|
45
|
-
// so even after the listener does eventually patch, no refetch happens.
|
|
46
|
-
//
|
|
47
|
-
// Side effect: any later fetch interceptor (e.g. @buoy-gg/network) installed
|
|
48
|
-
// AFTER us will wrap our wrapper, so its captured init.headers won't show the
|
|
49
|
-
// impersonation header. The wire request still includes it.
|
|
50
|
-
|
|
51
|
-
let bootstrapStarted = false;
|
|
52
|
-
async function bootstrapImpersonate() {
|
|
53
|
-
if (typeof window === 'undefined' || bootstrapStarted) return;
|
|
54
|
-
bootstrapStarted = true;
|
|
55
|
-
|
|
56
|
-
// eslint-disable-next-line no-console
|
|
57
|
-
console.log("[impersonate] bootstrap: start");
|
|
58
|
-
|
|
59
|
-
// Patch fetch/XHR synchronously so any request between now and the async
|
|
60
|
-
// storage load goes through our wrapper. The wrapper is a no-op until
|
|
61
|
-
// userId is set (which happens once initializeAsync resolves).
|
|
62
|
-
if (!(0, _impersonateListener.impersonateListener)().isListening) {
|
|
63
|
-
(0, _impersonateListener.impersonateListener)().startListening();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// React Native: require AsyncStorage. require() is more reliable under
|
|
67
|
-
// Metro than dynamic import(); on web this throws and the store falls
|
|
68
|
-
// back to localStorage handled synchronously in its constructor.
|
|
69
|
-
try {
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
71
|
-
const AsyncStorage = (0, _asyncStoragePeer.getAsyncStorage)();
|
|
72
|
-
if (!AsyncStorage || typeof AsyncStorage.getItem !== "function") {
|
|
73
|
-
// eslint-disable-next-line no-console
|
|
74
|
-
console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected", Object.keys(AsyncStorage ?? {}));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const adapter = {
|
|
78
|
-
getItem: key => AsyncStorage.getItem(key),
|
|
79
|
-
setItem: (key, value) => AsyncStorage.setItem(key, value)
|
|
80
|
-
};
|
|
81
|
-
_impersonateStore.impersonateStore.setAsyncStorage(adapter);
|
|
82
|
-
// eslint-disable-next-line no-console
|
|
83
|
-
console.log("[impersonate] bootstrap: AsyncStorage adapter installed");
|
|
84
|
-
await _impersonateStore.impersonateStore.initializeAsync(adapter);
|
|
85
|
-
// eslint-disable-next-line no-console
|
|
86
|
-
console.log("[impersonate] bootstrap: initializeAsync done");
|
|
87
|
-
} catch (e) {
|
|
88
|
-
// eslint-disable-next-line no-console
|
|
89
|
-
console.warn("[impersonate] bootstrap: failed", e);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// =============================================================================
|
|
94
|
-
// ICON COMPONENT
|
|
95
|
-
// =============================================================================
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Impersonate tool icon — a masked figure with a second identity behind it.
|
|
99
|
-
*
|
|
100
|
-
* The artwork lives in shared/icons/impersonate.json (Buoy Icon Format) and is
|
|
101
|
-
* generated into @buoy-gg/floating-tools-core, so React Native, the desktop
|
|
102
|
-
* dashboard and Flutter all render the same drawing. Edit the JSON, then
|
|
103
|
-
* `pnpm icons`.
|
|
104
|
-
*/
|
|
105
|
-
|
|
106
|
-
// =============================================================================
|
|
107
|
-
// WRAPPER COMPONENT
|
|
108
|
-
// =============================================================================
|
|
109
|
-
|
|
110
|
-
// =============================================================================
|
|
111
|
-
// FACTORY FUNCTION
|
|
112
|
-
// =============================================================================
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Create an impersonate tool with custom configuration
|
|
116
|
-
*
|
|
117
|
-
* The tool automatically displays a floating banner when impersonation is active.
|
|
118
|
-
* This can be toggled in the Settings tab or via developer defaults.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```tsx
|
|
122
|
-
* import { createImpersonateTool } from '@buoy-gg/impersonate';
|
|
123
|
-
* import { queryClient } from './queryClient';
|
|
124
|
-
*
|
|
125
|
-
* const impersonateTool = createImpersonateTool({
|
|
126
|
-
* onSearchUsers: async (query) => {
|
|
127
|
-
* const response = await api.searchUsers({ email: query });
|
|
128
|
-
* return response.users.map(u => ({
|
|
129
|
-
* id: u.id,
|
|
130
|
-
* displayName: u.name,
|
|
131
|
-
* email: u.email,
|
|
132
|
-
* metadata: { role: u.role, createdAt: u.createdAt }
|
|
133
|
-
* }));
|
|
134
|
-
* },
|
|
135
|
-
* onClearReactQuery: () => queryClient.clear(),
|
|
136
|
-
* onClearRedux: () => store.dispatch({ type: 'RESET' }),
|
|
137
|
-
*
|
|
138
|
-
* // Optional: Developer defaults (override hardcoded, overridden by persisted)
|
|
139
|
-
* defaults: {
|
|
140
|
-
* headerKey: 'x-admin-impersonate',
|
|
141
|
-
* showBanner: true, // Show floating banner when impersonating
|
|
142
|
-
* dataNukeSettings: {
|
|
143
|
-
* reactQuery: true,
|
|
144
|
-
* redux: false,
|
|
145
|
-
* },
|
|
146
|
-
* },
|
|
147
|
-
*
|
|
148
|
-
* // Optional: Hide settings tab for simple testing
|
|
149
|
-
* showSettingsTab: true,
|
|
150
|
-
* });
|
|
151
|
-
*
|
|
152
|
-
* // In your app — mount the banner globally (outside FloatingDevTools)
|
|
153
|
-
* // so it survives reloads and stays visible after the modal is closed.
|
|
154
|
-
* <FloatingDevTools apps={[impersonateTool]} />
|
|
155
|
-
* <ImpersonateBanner position="top" offset={50} />
|
|
156
|
-
* ```
|
|
157
|
-
*/
|
|
158
|
-
function createImpersonateTool(config) {
|
|
159
|
-
const {
|
|
160
|
-
id = "impersonate",
|
|
161
|
-
name = "IMPERSONATE",
|
|
162
|
-
description = "User impersonation for admin testing",
|
|
163
|
-
defaults,
|
|
164
|
-
showSettingsTab = true,
|
|
165
|
-
onSearchUsers,
|
|
166
|
-
onClearReactQuery,
|
|
167
|
-
onClearRedux,
|
|
168
|
-
onClearAsyncStorage,
|
|
169
|
-
onClearMMKV
|
|
170
|
-
} = config;
|
|
171
|
-
|
|
172
|
-
// Initialize store with developer defaults if provided
|
|
173
|
-
if (defaults) {
|
|
174
|
-
_impersonateStore.impersonateStore.setDeveloperDefaults(defaults);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Make the app's user search available to the zero-config external-sync
|
|
178
|
-
// adapter (FloatingDevTools auto-sync), so the desktop dashboard can proxy
|
|
179
|
-
// searches without separate wiring.
|
|
180
|
-
(0, _impersonateSyncAdapter.registerImpersonateSearchUsers)(onSearchUsers ?? null);
|
|
181
|
-
|
|
182
|
-
// Patch fetch and restore persisted impersonation state up-front. Fire and
|
|
183
|
-
// forget — bootstrapImpersonate guards itself against double-invocation.
|
|
184
|
-
void bootstrapImpersonate();
|
|
185
|
-
|
|
186
|
-
// Create the tool configuration object
|
|
187
|
-
const tool = {
|
|
188
|
-
id,
|
|
189
|
-
name,
|
|
190
|
-
description,
|
|
191
|
-
slot: "both",
|
|
192
|
-
icon: ({
|
|
193
|
-
size,
|
|
194
|
-
slot
|
|
195
|
-
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ImpersonateIcon, {
|
|
196
|
-
size: slot === "dial" ? size * 1.5 : size,
|
|
197
|
-
color: _sharedUi.IMPERSONATE_ICON_COLOR
|
|
198
|
-
}),
|
|
199
|
-
component: props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImpersonateModal.ImpersonateModal, {
|
|
200
|
-
...props,
|
|
201
|
-
onSearchUsers: onSearchUsers,
|
|
202
|
-
onClearReactQuery: onClearReactQuery,
|
|
203
|
-
onClearRedux: onClearRedux,
|
|
204
|
-
onClearAsyncStorage: onClearAsyncStorage,
|
|
205
|
-
onClearMMKV: onClearMMKV,
|
|
206
|
-
showSettingsTab: showSettingsTab
|
|
207
|
-
}),
|
|
208
|
-
props: {
|
|
209
|
-
enableSharedModalDimensions: false
|
|
210
|
-
},
|
|
211
|
-
// Export banner component for host app to use
|
|
212
|
-
Banner: _ImpersonateBanner.ImpersonateBanner
|
|
213
|
-
};
|
|
214
|
-
return tool;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// =============================================================================
|
|
218
|
-
// STYLES
|
|
219
|
-
// =============================================================================
|
|
220
|
-
|
|
221
|
-
// =============================================================================
|
|
222
|
-
// NOTE: No default preset export
|
|
223
|
-
// =============================================================================
|
|
224
|
-
// Unlike other tools, the impersonate tool REQUIRES configuration
|
|
225
|
-
// (specifically the onSearchUsers callback). Therefore, we don't export
|
|
226
|
-
// a default preset. Users must call createImpersonateTool() with their config.
|
|
227
|
-
//
|
|
228
|
-
// If you want a basic preset for testing without search:
|
|
229
|
-
//
|
|
230
|
-
// export const impersonateToolPresetBasic = createImpersonateTool({
|
|
231
|
-
// onSearchUsers: async () => [],
|
|
232
|
-
// });
|
|
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:m,onClearMMKV:u}=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:m,onClearMMKV:u,showSettingsTab:i}),props:{enableSharedModalDimensions:false},Banner:_ImpersonateBanner.ImpersonateBanner};return l}
|
|
@@ -1,170 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.SNAPSHOT_URI_INLINE_LIMIT = exports.SNAPSHOT_METADATA_INLINE_LIMIT = void 0;
|
|
7
|
-
exports.createImpersonateSyncAdapter = createImpersonateSyncAdapter;
|
|
8
|
-
exports.impersonateSyncAdapter = void 0;
|
|
9
|
-
exports.registerImpersonateSearchUsers = registerImpersonateSearchUsers;
|
|
10
|
-
exports.toWireUri = toWireUri;
|
|
11
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
12
|
-
var _impersonateStore = require("../impersonate/utils/impersonateStore");
|
|
13
|
-
// Registered by createImpersonateTool, so the zero-config adapter (see
|
|
14
|
-
// FloatingDevTools' auto external sync) can proxy the dashboard's user
|
|
15
|
-
// search without the app wiring anything twice.
|
|
16
|
-
let registeredSearchUsers = null;
|
|
17
|
-
|
|
18
|
-
/** @internal Called by createImpersonateTool with the app's onSearchUsers. */
|
|
19
|
-
function registerImpersonateSearchUsers(handler) {
|
|
20
|
-
registeredSearchUsers = handler;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* `data:` avatar URLs (and any URL over this) are NOT copied onto the
|
|
25
|
-
* snapshot. UserCard renders initials, not the image, but apps still put
|
|
26
|
-
* base64 photos on `avatarUrl` / dump the API user into `metadata`. Ten
|
|
27
|
-
* history entries of those blow the 2MB emit budget and drop the panel.
|
|
28
|
-
*/
|
|
29
|
-
const SNAPSHOT_URI_INLINE_LIMIT = exports.SNAPSHOT_URI_INLINE_LIMIT = 2 * 1024;
|
|
30
|
-
const SNAPSHOT_METADATA_INLINE_LIMIT = exports.SNAPSHOT_METADATA_INLINE_LIMIT = 16 * 1024;
|
|
31
|
-
const METADATA_ON_DEVICE = Object.freeze({
|
|
32
|
-
__buoyOmitted: "user-metadata",
|
|
33
|
-
note: "User metadata stays on the device."
|
|
34
|
-
});
|
|
35
|
-
function toWireUri(uri) {
|
|
36
|
-
if (!uri) return uri;
|
|
37
|
-
if (uri.startsWith("data:")) {
|
|
38
|
-
const comma = uri.indexOf(",");
|
|
39
|
-
const header = comma >= 0 ? uri.slice(0, Math.min(comma + 1, 64)) : "data:";
|
|
40
|
-
return `${header}[${uri.length} chars]`;
|
|
41
|
-
}
|
|
42
|
-
if (uri.length <= SNAPSHOT_URI_INLINE_LIMIT) return uri;
|
|
43
|
-
return `${uri.slice(0, SNAPSHOT_URI_INLINE_LIMIT)}… [${uri.length - SNAPSHOT_URI_INLINE_LIMIT} more]`;
|
|
44
|
-
}
|
|
45
|
-
function toWireMetadata(metadata) {
|
|
46
|
-
if (!metadata) return metadata;
|
|
47
|
-
const role = typeof metadata.role === "string" ? metadata.role : undefined;
|
|
48
|
-
if (!(0, _sharedUi.isOverWireBudget)(metadata, SNAPSHOT_METADATA_INLINE_LIMIT)) return metadata;
|
|
49
|
-
// Keep `role` so UserCard still badges the impersonated user.
|
|
50
|
-
return role ? {
|
|
51
|
-
role,
|
|
52
|
-
...METADATA_ON_DEVICE
|
|
53
|
-
} : {
|
|
54
|
-
...METADATA_ON_DEVICE
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function toWireUser(user) {
|
|
58
|
-
return {
|
|
59
|
-
...user,
|
|
60
|
-
avatarUrl: toWireUri(user.avatarUrl),
|
|
61
|
-
metadata: toWireMetadata(user.metadata)
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function toWireState(state) {
|
|
65
|
-
return {
|
|
66
|
-
...state,
|
|
67
|
-
currentUser: state.currentUser ? toWireUser(state.currentUser) : null,
|
|
68
|
-
history: state.history.map(entry => ({
|
|
69
|
-
...entry,
|
|
70
|
-
user: toWireUser(entry.user)
|
|
71
|
-
}))
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Users this device has actually seen — search results from the app's own
|
|
77
|
-
* directory. `startImpersonation` refuses anything else: a live eval showed
|
|
78
|
-
* the model INVENTING a plausible user object when search returned nothing,
|
|
79
|
-
* and impersonating a fabricated user is a silent half-state (headers patched
|
|
80
|
-
* for a person who does not exist). History and the current user also count,
|
|
81
|
-
* so the desktop's re-impersonate-from-history flow keeps working.
|
|
82
|
-
*/
|
|
83
|
-
const seenUserIds = new Set();
|
|
84
|
-
function rememberUsers(users) {
|
|
85
|
-
for (const u of users) {
|
|
86
|
-
if (u && typeof u === "object" && u.id) seenUserIds.add(String(u.id));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function isKnownUser(user) {
|
|
90
|
-
if (!user || typeof user !== "object" || !user.id) return false;
|
|
91
|
-
if (seenUserIds.has(String(user.id))) return true;
|
|
92
|
-
const state = _impersonateStore.impersonateStore.getState();
|
|
93
|
-
if (state.currentUser?.id === user.id) return true;
|
|
94
|
-
return state.history.some(entry => entry.user.id === user.id);
|
|
95
|
-
}
|
|
96
|
-
function buildActions(onSearchUsers) {
|
|
97
|
-
return {
|
|
98
|
-
searchUsers: async params => {
|
|
99
|
-
const query = String(params?.query ?? "");
|
|
100
|
-
const users = await onSearchUsers(query);
|
|
101
|
-
if (Array.isArray(users)) rememberUsers(users);
|
|
102
|
-
return Array.isArray(users) ? users.map(toWireUser) : users;
|
|
103
|
-
},
|
|
104
|
-
startImpersonation: async params => {
|
|
105
|
-
const user = params?.user;
|
|
106
|
-
if (!isKnownUser(user)) {
|
|
107
|
-
throw new Error("That user isn't in this app's directory. Call searchUsers and impersonate one of its results — a user object that didn't come from search impersonates nobody.");
|
|
108
|
-
}
|
|
109
|
-
await _impersonateStore.impersonateStore.startImpersonation(user);
|
|
110
|
-
return {
|
|
111
|
-
ok: true,
|
|
112
|
-
userId: user.id
|
|
113
|
-
};
|
|
114
|
-
},
|
|
115
|
-
stopImpersonation: () => _impersonateStore.impersonateStore.stopImpersonation(),
|
|
116
|
-
pauseImpersonation: () => _impersonateStore.impersonateStore.pauseImpersonation(),
|
|
117
|
-
resumeImpersonation: () => _impersonateStore.impersonateStore.resumeImpersonation(),
|
|
118
|
-
updateSettings: params => {
|
|
119
|
-
// The documented shape is { settings: {...} }, but the flat patch is the
|
|
120
|
-
// obvious guess and used to crash with "Cannot read property 'headerKey'
|
|
121
|
-
// of undefined". Accept both; refuse anything else by name.
|
|
122
|
-
|
|
123
|
-
const p = params ?? {};
|
|
124
|
-
const settings = p.settings ?? (["headerKey", "ignorePatterns", "showBanner", "dataNukeSettings"].some(k => k in p) ? p : undefined);
|
|
125
|
-
if (!settings) throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");
|
|
126
|
-
return _impersonateStore.impersonateStore.updateSettings(settings);
|
|
127
|
-
},
|
|
128
|
-
removeFromHistory: params => _impersonateStore.impersonateStore.removeFromHistory(params.userId),
|
|
129
|
-
clearHistory: () => _impersonateStore.impersonateStore.clearHistory()
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Create a sync adapter for the impersonate tool, consumed by
|
|
134
|
-
* @buoy-gg/external-sync's `useExternalSync` (structurally matches its
|
|
135
|
-
* ToolSyncAdapter interface so this package doesn't need a dependency on it).
|
|
136
|
-
*
|
|
137
|
-
* The dashboard mirrors the impersonation state and forwards every mutation
|
|
138
|
-
* back as an action — header patching, data nuking and persistence all run
|
|
139
|
-
* on the device, so impersonating from the desktop behaves exactly like
|
|
140
|
-
* tapping the modal on the phone.
|
|
141
|
-
*/
|
|
142
|
-
function createImpersonateSyncAdapter({
|
|
143
|
-
onSearchUsers
|
|
144
|
-
}) {
|
|
145
|
-
return {
|
|
146
|
-
version: 1,
|
|
147
|
-
getSnapshot: () => toWireState(_impersonateStore.impersonateStore.getState()),
|
|
148
|
-
subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
|
|
149
|
-
actions: buildActions(onSearchUsers)
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Zero-config variant used by FloatingDevTools' auto external sync. User
|
|
155
|
-
* search proxies to the onSearchUsers the app passed to
|
|
156
|
-
* createImpersonateTool; if the tool was never configured, the search action
|
|
157
|
-
* reports a descriptive error to the dashboard.
|
|
158
|
-
*/
|
|
159
|
-
const impersonateSyncAdapter = exports.impersonateSyncAdapter = {
|
|
160
|
-
dispose: () => _impersonateStore.impersonateStore.disposeAccountSession(),
|
|
161
|
-
version: 1,
|
|
162
|
-
getSnapshot: () => toWireState(_impersonateStore.impersonateStore.getState()),
|
|
163
|
-
subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
|
|
164
|
-
actions: buildActions(query => {
|
|
165
|
-
if (!registeredSearchUsers) {
|
|
166
|
-
throw new Error("No onSearchUsers configured — pass it to createImpersonateTool()");
|
|
167
|
-
}
|
|
168
|
-
return registeredSearchUsers(query);
|
|
169
|
-
})
|
|
170
|
-
};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SNAPSHOT_URI_INLINE_LIMIT=exports.SNAPSHOT_METADATA_INLINE_LIMIT=void 0;exports.createImpersonateSyncAdapter=createImpersonateSyncAdapter;exports.impersonateSyncAdapter=void 0;exports.registerImpersonateSearchUsers=registerImpersonateSearchUsers;exports.toWireUri=toWireUri;var _sharedUi=require("@buoy-gg/shared-ui");var _impersonateStore=require("../impersonate/utils/impersonateStore");let registeredSearchUsers=null;function registerImpersonateSearchUsers(e){registeredSearchUsers=e}const SNAPSHOT_URI_INLINE_LIMIT=exports.SNAPSHOT_URI_INLINE_LIMIT=2*1024;const SNAPSHOT_METADATA_INLINE_LIMIT=exports.SNAPSHOT_METADATA_INLINE_LIMIT=16*1024;const METADATA_ON_DEVICE=Object.freeze({__buoyOmitted:"user-metadata",note:"User metadata stays on the device."});function toWireUri(e){if(!e)return e;if(e.startsWith("data:")){const r=e.indexOf(",");const t=r>=0?e.slice(0,Math.min(r+1,64)):"data:";return`${t}[${e.length} chars]`}if(e.length<=SNAPSHOT_URI_INLINE_LIMIT)return e;return`${e.slice(0,SNAPSHOT_URI_INLINE_LIMIT)}\u2026 [${e.length-SNAPSHOT_URI_INLINE_LIMIT} more]`}function toWireMetadata(e){if(!e)return e;const r=typeof e.role==="string"?e.role:void 0;if(!(0,_sharedUi.isOverWireBudget)(e,SNAPSHOT_METADATA_INLINE_LIMIT))return e;return r?{role:r,...METADATA_ON_DEVICE}:{...METADATA_ON_DEVICE}}function toWireUser(e){return{...e,avatarUrl:toWireUri(e.avatarUrl),metadata:toWireMetadata(e.metadata)}}function toWireState(e){return{...e,currentUser:e.currentUser?toWireUser(e.currentUser):null,history:e.history.map(r=>({...r,user:toWireUser(r.user)}))}}const seenUserIds=new Set;function rememberUsers(e){for(const r of e){if(r&&typeof r==="object"&&r.id)seenUserIds.add(String(r.id))}}function isKnownUser(e){if(!e||typeof e!=="object"||!e.id)return false;if(seenUserIds.has(String(e.id)))return true;const r=_impersonateStore.impersonateStore.getState();if(r.currentUser?.id===e.id)return true;return r.history.some(t=>t.user.id===e.id)}function buildActions(e){return{searchUsers:async r=>{const t=String(r?.query??"");const s=await e(t);if(Array.isArray(s))rememberUsers(s);return Array.isArray(s)?s.map(toWireUser):s},startImpersonation:async r=>{const t=r?.user;if(!isKnownUser(t)){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.")}await _impersonateStore.impersonateStore.startImpersonation(t);return{ok:true,userId:t.id}},stopImpersonation:()=>_impersonateStore.impersonateStore.stopImpersonation(),pauseImpersonation:()=>_impersonateStore.impersonateStore.pauseImpersonation(),resumeImpersonation:()=>_impersonateStore.impersonateStore.resumeImpersonation(),updateSettings:r=>{const t=r??{};const s=t.settings??(["headerKey","ignorePatterns","showBanner","dataNukeSettings"].some(o=>o in t)?t:void 0);if(!s)throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");return _impersonateStore.impersonateStore.updateSettings(s)},removeFromHistory:r=>_impersonateStore.impersonateStore.removeFromHistory(r.userId),clearHistory:()=>_impersonateStore.impersonateStore.clearHistory()}}function createImpersonateSyncAdapter({onSearchUsers:e}){return{version:1,getSnapshot:()=>toWireState(_impersonateStore.impersonateStore.getState()),subscribe:r=>_impersonateStore.impersonateStore.subscribe(r),actions:buildActions(e)}}const impersonateSyncAdapter=exports.impersonateSyncAdapter={dispose:()=>_impersonateStore.impersonateStore.disposeAccountSession(),version:1,getSnapshot:()=>toWireState(_impersonateStore.impersonateStore.getState()),subscribe:e=>_impersonateStore.impersonateStore.subscribe(e),actions:buildActions(e=>{if(!registeredSearchUsers){throw new Error("No onSearchUsers configured \u2014 pass it to createImpersonateTool()")}return registeredSearchUsers(e)})};
|