@buoy-gg/impersonate 7.0.39 → 7.0.41

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.
Files changed (38) hide show
  1. package/README.md +4 -0
  2. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.js +17 -0
  3. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.web.js +11 -0
  4. package/lib/commonjs/impersonate/hooks/useAutoClearAsyncStorage.js +3 -13
  5. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.web.js +20 -0
  6. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.web.js +27 -0
  7. package/lib/commonjs/impersonate/utils/impersonateListener.js +17 -2
  8. package/lib/commonjs/impersonate/utils/impersonateStore.js +18 -4
  9. package/lib/commonjs/preset.js +4 -4
  10. package/lib/commonjs/sync/impersonateSyncAdapter.js +10 -1
  11. package/lib/module/impersonate/hooks/asyncStoragePeer.js +13 -0
  12. package/lib/module/impersonate/hooks/asyncStoragePeer.web.js +6 -0
  13. package/lib/module/impersonate/hooks/useAutoClearAsyncStorage.js +1 -11
  14. package/lib/module/impersonate/hooks/useAutoClearReactQuery.web.js +16 -0
  15. package/lib/module/impersonate/hooks/useAutoClearRedux.web.js +22 -0
  16. package/lib/module/impersonate/utils/impersonateListener.js +17 -2
  17. package/lib/module/impersonate/utils/impersonateStore.js +19 -5
  18. package/lib/module/preset.js +4 -4
  19. package/lib/module/sync/impersonateSyncAdapter.js +10 -1
  20. package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts +7 -0
  21. package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts.map +1 -0
  22. package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts +2 -0
  23. package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts.map +1 -0
  24. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts +3 -12
  25. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts.map +1 -1
  26. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts +3 -0
  27. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts.map +1 -0
  28. package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts +4 -0
  29. package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts.map +1 -0
  30. package/lib/typescript/impersonate/types/types.d.ts +6 -0
  31. package/lib/typescript/impersonate/types/types.d.ts.map +1 -1
  32. package/lib/typescript/impersonate/utils/impersonateListener.d.ts +1 -0
  33. package/lib/typescript/impersonate/utils/impersonateListener.d.ts.map +1 -1
  34. package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +1 -1
  35. package/lib/typescript/preset.d.ts.map +1 -1
  36. package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +1 -1
  37. package/lib/web/index.mjs +11 -0
  38. package/package.json +32 -10
package/README.md CHANGED
@@ -89,3 +89,7 @@ Use a Free or Pro Buoy account. History limits and paid features vary by tool; s
89
89
  📚 [Full docs](https://buoy.gg/buoy/latest/docs/tools/impersonate) · [All Buoy tools](https://github.com/Buoy-gg/buoy)
90
90
 
91
91
  Proprietary software. © Buoy LLC. [Terms](https://buoy.gg/terms)
92
+
93
+ ## Web support (unreleased)
94
+
95
+ Register this package’s /web namespace in FloatingDevTools modules to use its shared panels and actions in a browser app. The browser build is available in this checkout and has not been published yet. See the [web setup guide](https://buoy.gg/buoy/latest/docs/web-preview) for registration, dependencies, and browser boundaries.
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAsyncStorage = getAsyncStorage;
7
+ function getAsyncStorage() {
8
+ try {
9
+ // Dynamic require to handle cases where async-storage isn't installed
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const AsyncStorage = require("@react-native-async-storage/async-storage").default;
12
+ return AsyncStorage;
13
+ } catch {
14
+ // @react-native-async-storage/async-storage not available
15
+ return null;
16
+ }
17
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAsyncStorage = getAsyncStorage;
7
+ var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function getAsyncStorage() {
10
+ return _asyncStorage.default;
11
+ }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useAsyncStorageAvailability = useAsyncStorageAvailability;
7
7
  exports.useAutoClearAsyncStorage = useAutoClearAsyncStorage;
8
+ var _asyncStoragePeer = require("./asyncStoragePeer");
8
9
  var _react = require("react");
9
10
  /**
10
11
  * useAutoClearAsyncStorage Hook
@@ -32,17 +33,6 @@ let isClearing = false;
32
33
  /**
33
34
  * Safely attempt to load @react-native-async-storage/async-storage
34
35
  */
35
- function getAsyncStorage() {
36
- try {
37
- // Dynamic require to handle cases where async-storage isn't installed
38
- // eslint-disable-next-line @typescript-eslint/no-var-requires
39
- const AsyncStorage = require("@react-native-async-storage/async-storage").default;
40
- return AsyncStorage;
41
- } catch {
42
- // @react-native-async-storage/async-storage not available
43
- return null;
44
- }
45
- }
46
36
 
47
37
  // ============================================
48
38
  // Main Hook
@@ -72,7 +62,7 @@ function useAutoClearAsyncStorage() {
72
62
 
73
63
  // Check for AsyncStorage on mount
74
64
  (0, _react.useEffect)(() => {
75
- const storage = getAsyncStorage();
65
+ const storage = (0, _asyncStoragePeer.getAsyncStorage)();
76
66
  if (storage) {
77
67
  setAsyncStorage(storage);
78
68
  setError(null);
@@ -130,7 +120,7 @@ function useAutoClearAsyncStorage() {
130
120
  * without creating the clear function
131
121
  */
132
122
  function useAsyncStorageAvailability() {
133
- const storage = getAsyncStorage();
123
+ const storage = (0, _asyncStoragePeer.getAsyncStorage)();
134
124
  if (!storage) {
135
125
  return {
136
126
  isInstalled: false,
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useAutoClearReactQuery = useAutoClearReactQuery;
7
+ var _react = require("react");
8
+ var _sharedUi = require("@buoy-gg/shared-ui");
9
+ function useAutoClearReactQuery() {
10
+ const available = Boolean((0, _sharedUi.getToolAdapters)().query);
11
+ const clearCache = (0, _react.useCallback)(async () => {
12
+ await (0, _sharedUi.dispatchToolAction)('query', 'clearQueryCache');
13
+ await (0, _sharedUi.dispatchToolAction)('query', 'clearMutationCache');
14
+ }, []);
15
+ return {
16
+ isAvailable: available,
17
+ error: available ? null : 'Connect React Query to Buoy or provide onClearReactQuery.',
18
+ clearCache: available ? clearCache : null
19
+ };
20
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.REDUX_RESET_ACTION_TYPE = void 0;
7
+ exports.useAutoClearRedux = useAutoClearRedux;
8
+ var _react = require("react");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
+ const REDUX_RESET_ACTION_TYPE = exports.REDUX_RESET_ACTION_TYPE = '@@RESET';
11
+ function useAutoClearRedux({
12
+ resetActionType = REDUX_RESET_ACTION_TYPE
13
+ } = {}) {
14
+ const available = Boolean((0, _sharedUi.getToolAdapters)().redux);
15
+ const resetStore = (0, _react.useCallback)(async () => {
16
+ await (0, _sharedUi.dispatchToolAction)('redux', 'dispatch', {
17
+ action: {
18
+ type: resetActionType
19
+ }
20
+ });
21
+ }, [resetActionType]);
22
+ return {
23
+ isAvailable: available,
24
+ error: available ? null : 'Connect Redux to Buoy or provide onClearRedux.',
25
+ resetStore: available ? resetStore : null
26
+ };
27
+ }
@@ -134,6 +134,9 @@ class ImpersonateListener {
134
134
  if (!this.config.userId) {
135
135
  return false;
136
136
  }
137
+ if (this.config.gate && !this.config.gate()) {
138
+ return false;
139
+ }
137
140
 
138
141
  // Check ignore patterns
139
142
  return !this.config.ignorePatterns.some(pattern => pattern.test(url));
@@ -188,7 +191,7 @@ class ImpersonateListener {
188
191
  const url = self.extractUrl(input);
189
192
  if (self.shouldInjectHeader(url)) {
190
193
  // Create new headers with impersonation header added
191
- const existingHeaders = init?.headers;
194
+ const existingHeaders = init?.headers ?? (typeof input === 'object' && 'headers' in input ? input.headers : undefined);
192
195
  const headers = new Headers(existingHeaders);
193
196
  headers.set(self.config.headerKey, self.config.userId);
194
197
 
@@ -233,8 +236,17 @@ class ImpersonateListener {
233
236
  this.patchedXHRSend = patchedSend;
234
237
  XMLHttpRequest.prototype.open = this.patchedXHROpen;
235
238
  XMLHttpRequest.prototype.send = this.patchedXHRSend;
239
+
240
+ // Tell @buoy-gg/network which header this adds, so its row shows it.
241
+ // Network usually wraps this wrapper and records before the header is set.
242
+ const g = globalThis;
243
+ const injectors = g.__buoyHeaderInjectors ??= [];
244
+ if (!injectors.includes(this.reportHeader)) injectors.push(this.reportHeader);
236
245
  this.isListeningFlag = true;
237
246
  }
247
+ reportHeader = url => this.shouldInjectHeader(url) ? {
248
+ [this.config.headerKey]: this.config.userId
249
+ } : null;
238
250
 
239
251
  /**
240
252
  * Stop intercepting - restore original methods
@@ -265,6 +277,9 @@ class ImpersonateListener {
265
277
  this.patchedFetch = null;
266
278
  this.patchedXHROpen = null;
267
279
  this.patchedXHRSend = null;
280
+ const injectors = globalThis.__buoyHeaderInjectors;
281
+ const at = injectors?.indexOf(this.reportHeader) ?? -1;
282
+ if (injectors && at >= 0) injectors.splice(at, 1);
268
283
  this.isListeningFlag = false;
269
284
  }
270
285
 
@@ -279,7 +294,7 @@ class ImpersonateListener {
279
294
  * Check if impersonation is currently active (has userId set)
280
295
  */
281
296
  get isImpersonating() {
282
- return this.config.userId !== null;
297
+ return this.config.userId !== null && (this.config.gate?.() ?? true);
283
298
  }
284
299
  }
285
300
 
@@ -112,8 +112,18 @@ class ImpersonateStore {
112
112
  // Try to load persisted state synchronously
113
113
  this.loadFromStorage();
114
114
  Promise.resolve().then(() => {
115
+ // Only a sign-out ends the session: access that was admitted and is now
116
+ // locked. The license reports "locked" for a moment while it boots or
117
+ // reloads, before validation starts, and ending the session then wiped a
118
+ // restored impersonation for good. The per-request gate already keeps
119
+ // the header off whenever access isn't admitted.
120
+ let wasAdmitted = false;
115
121
  const reconcile = () => {
116
- if (!(0, _sharedUi.hasAccountAccess)()) this.disposeAccountSession();
122
+ const status = (0, _sharedUi.getAccountAccess)().status;
123
+ if (status === "admitted") wasAdmitted = true;else if (status === "locked" && wasAdmitted) {
124
+ wasAdmitted = false;
125
+ this.disposeAccountSession();
126
+ }
117
127
  };
118
128
  (0, _sharedUi.subscribeAccountAccess)(reconcile);
119
129
  reconcile();
@@ -602,12 +612,16 @@ class ImpersonateStore {
602
612
  void this.persist();
603
613
  }
604
614
  syncWithListener() {
605
- // When paused, don't inject headers (pass null userId)
606
- const shouldInject = (0, _sharedUi.hasAccountAccess)() && this.state.isActive && !this.state.isPaused;
615
+ // When paused, don't inject headers (pass null userId). Account access is
616
+ // checked per request by the gate, not here: a session restored at launch
617
+ // syncs before the account check finishes, and reading it once here sent
618
+ // no header for the rest of the run, until a pause and resume re-synced.
619
+ const shouldInject = this.state.isActive && !this.state.isPaused;
607
620
  (0, _impersonateListener.setImpersonateConfig)({
608
621
  headerKey: this.state.headerKey,
609
622
  userId: shouldInject ? this.state.currentUser?.id ?? null : null,
610
- ignorePatterns: this.state.ignorePatterns.map(p => new RegExp(p))
623
+ ignorePatterns: this.state.ignorePatterns.map(p => new RegExp(p)),
624
+ gate: _sharedUi.hasAccountAccess
611
625
  });
612
626
 
613
627
  // Ensure listener is started
@@ -16,6 +16,7 @@ Object.defineProperty(exports, "ImpersonateIcon", {
16
16
  }
17
17
  });
18
18
  exports.createImpersonateTool = createImpersonateTool;
19
+ var _asyncStoragePeer = require("./impersonate/hooks/asyncStoragePeer");
19
20
  var _react = _interopRequireDefault(require("react"));
20
21
  var _ImpersonateModal = require("./impersonate/components/ImpersonateModal");
21
22
  var _ImpersonateBanner = require("./impersonate/components/ImpersonateBanner");
@@ -49,7 +50,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
49
50
 
50
51
  let bootstrapStarted = false;
51
52
  async function bootstrapImpersonate() {
52
- if (bootstrapStarted) return;
53
+ if (typeof window === 'undefined' || bootstrapStarted) return;
53
54
  bootstrapStarted = true;
54
55
 
55
56
  // eslint-disable-next-line no-console
@@ -67,11 +68,10 @@ async function bootstrapImpersonate() {
67
68
  // back to localStorage handled synchronously in its constructor.
68
69
  try {
69
70
  // eslint-disable-next-line @typescript-eslint/no-require-imports
70
- const mod = require("@react-native-async-storage/async-storage");
71
- const AsyncStorage = mod?.default ?? mod;
71
+ const AsyncStorage = (0, _asyncStoragePeer.getAsyncStorage)();
72
72
  if (!AsyncStorage || typeof AsyncStorage.getItem !== "function") {
73
73
  // eslint-disable-next-line no-console
74
- console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected", Object.keys(mod ?? {}));
74
+ console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected", Object.keys(AsyncStorage ?? {}));
75
75
  return;
76
76
  }
77
77
  const adapter = {
@@ -115,7 +115,16 @@ function buildActions(onSearchUsers) {
115
115
  stopImpersonation: () => _impersonateStore.impersonateStore.stopImpersonation(),
116
116
  pauseImpersonation: () => _impersonateStore.impersonateStore.pauseImpersonation(),
117
117
  resumeImpersonation: () => _impersonateStore.impersonateStore.resumeImpersonation(),
118
- updateSettings: params => _impersonateStore.impersonateStore.updateSettings(params.settings),
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
+ },
119
128
  removeFromHistory: params => _impersonateStore.impersonateStore.removeFromHistory(params.userId),
120
129
  clearHistory: () => _impersonateStore.impersonateStore.clearHistory()
121
130
  };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ export function getAsyncStorage() {
4
+ try {
5
+ // Dynamic require to handle cases where async-storage isn't installed
6
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
7
+ const AsyncStorage = require("@react-native-async-storage/async-storage").default;
8
+ return AsyncStorage;
9
+ } catch {
10
+ // @react-native-async-storage/async-storage not available
11
+ return null;
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ import AsyncStorage from '@react-native-async-storage/async-storage';
4
+ export function getAsyncStorage() {
5
+ return AsyncStorage;
6
+ }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { getAsyncStorage } from './asyncStoragePeer';
3
4
  /**
4
5
  * useAutoClearAsyncStorage Hook
5
6
  *
@@ -28,17 +29,6 @@ let isClearing = false;
28
29
  /**
29
30
  * Safely attempt to load @react-native-async-storage/async-storage
30
31
  */
31
- function getAsyncStorage() {
32
- try {
33
- // Dynamic require to handle cases where async-storage isn't installed
34
- // eslint-disable-next-line @typescript-eslint/no-var-requires
35
- const AsyncStorage = require("@react-native-async-storage/async-storage").default;
36
- return AsyncStorage;
37
- } catch {
38
- // @react-native-async-storage/async-storage not available
39
- return null;
40
- }
41
- }
42
32
 
43
33
  // ============================================
44
34
  // Main Hook
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ import { useCallback } from 'react';
4
+ import { dispatchToolAction, getToolAdapters } from '@buoy-gg/shared-ui';
5
+ export function useAutoClearReactQuery() {
6
+ const available = Boolean(getToolAdapters().query);
7
+ const clearCache = useCallback(async () => {
8
+ await dispatchToolAction('query', 'clearQueryCache');
9
+ await dispatchToolAction('query', 'clearMutationCache');
10
+ }, []);
11
+ return {
12
+ isAvailable: available,
13
+ error: available ? null : 'Connect React Query to Buoy or provide onClearReactQuery.',
14
+ clearCache: available ? clearCache : null
15
+ };
16
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ import { useCallback } from 'react';
4
+ import { dispatchToolAction, getToolAdapters } from '@buoy-gg/shared-ui';
5
+ export const REDUX_RESET_ACTION_TYPE = '@@RESET';
6
+ export function useAutoClearRedux({
7
+ resetActionType = REDUX_RESET_ACTION_TYPE
8
+ } = {}) {
9
+ const available = Boolean(getToolAdapters().redux);
10
+ const resetStore = useCallback(async () => {
11
+ await dispatchToolAction('redux', 'dispatch', {
12
+ action: {
13
+ type: resetActionType
14
+ }
15
+ });
16
+ }, [resetActionType]);
17
+ return {
18
+ isAvailable: available,
19
+ error: available ? null : 'Connect Redux to Buoy or provide onClearRedux.',
20
+ resetStore: available ? resetStore : null
21
+ };
22
+ }
@@ -125,6 +125,9 @@ class ImpersonateListener {
125
125
  if (!this.config.userId) {
126
126
  return false;
127
127
  }
128
+ if (this.config.gate && !this.config.gate()) {
129
+ return false;
130
+ }
128
131
 
129
132
  // Check ignore patterns
130
133
  return !this.config.ignorePatterns.some(pattern => pattern.test(url));
@@ -179,7 +182,7 @@ class ImpersonateListener {
179
182
  const url = self.extractUrl(input);
180
183
  if (self.shouldInjectHeader(url)) {
181
184
  // Create new headers with impersonation header added
182
- const existingHeaders = init?.headers;
185
+ const existingHeaders = init?.headers ?? (typeof input === 'object' && 'headers' in input ? input.headers : undefined);
183
186
  const headers = new Headers(existingHeaders);
184
187
  headers.set(self.config.headerKey, self.config.userId);
185
188
 
@@ -224,8 +227,17 @@ class ImpersonateListener {
224
227
  this.patchedXHRSend = patchedSend;
225
228
  XMLHttpRequest.prototype.open = this.patchedXHROpen;
226
229
  XMLHttpRequest.prototype.send = this.patchedXHRSend;
230
+
231
+ // Tell @buoy-gg/network which header this adds, so its row shows it.
232
+ // Network usually wraps this wrapper and records before the header is set.
233
+ const g = globalThis;
234
+ const injectors = g.__buoyHeaderInjectors ??= [];
235
+ if (!injectors.includes(this.reportHeader)) injectors.push(this.reportHeader);
227
236
  this.isListeningFlag = true;
228
237
  }
238
+ reportHeader = url => this.shouldInjectHeader(url) ? {
239
+ [this.config.headerKey]: this.config.userId
240
+ } : null;
229
241
 
230
242
  /**
231
243
  * Stop intercepting - restore original methods
@@ -256,6 +268,9 @@ class ImpersonateListener {
256
268
  this.patchedFetch = null;
257
269
  this.patchedXHROpen = null;
258
270
  this.patchedXHRSend = null;
271
+ const injectors = globalThis.__buoyHeaderInjectors;
272
+ const at = injectors?.indexOf(this.reportHeader) ?? -1;
273
+ if (injectors && at >= 0) injectors.splice(at, 1);
259
274
  this.isListeningFlag = false;
260
275
  }
261
276
 
@@ -270,7 +285,7 @@ class ImpersonateListener {
270
285
  * Check if impersonation is currently active (has userId set)
271
286
  */
272
287
  get isImpersonating() {
273
- return this.config.userId !== null;
288
+ return this.config.userId !== null && (this.config.gate?.() ?? true);
274
289
  }
275
290
  }
276
291
 
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import { assertAccountAccess, hasAccountAccess, subscribeAccountAccess } from "@buoy-gg/shared-ui";
3
+ import { assertAccountAccess, getAccountAccess, hasAccountAccess, subscribeAccountAccess } from "@buoy-gg/shared-ui";
4
4
  /**
5
5
  * Impersonate Store - State Management with Persistence
6
6
  *
@@ -109,8 +109,18 @@ class ImpersonateStore {
109
109
  // Try to load persisted state synchronously
110
110
  this.loadFromStorage();
111
111
  Promise.resolve().then(() => {
112
+ // Only a sign-out ends the session: access that was admitted and is now
113
+ // locked. The license reports "locked" for a moment while it boots or
114
+ // reloads, before validation starts, and ending the session then wiped a
115
+ // restored impersonation for good. The per-request gate already keeps
116
+ // the header off whenever access isn't admitted.
117
+ let wasAdmitted = false;
112
118
  const reconcile = () => {
113
- if (!hasAccountAccess()) this.disposeAccountSession();
119
+ const status = getAccountAccess().status;
120
+ if (status === "admitted") wasAdmitted = true;else if (status === "locked" && wasAdmitted) {
121
+ wasAdmitted = false;
122
+ this.disposeAccountSession();
123
+ }
114
124
  };
115
125
  subscribeAccountAccess(reconcile);
116
126
  reconcile();
@@ -599,12 +609,16 @@ class ImpersonateStore {
599
609
  void this.persist();
600
610
  }
601
611
  syncWithListener() {
602
- // When paused, don't inject headers (pass null userId)
603
- const shouldInject = hasAccountAccess() && this.state.isActive && !this.state.isPaused;
612
+ // When paused, don't inject headers (pass null userId). Account access is
613
+ // checked per request by the gate, not here: a session restored at launch
614
+ // syncs before the account check finishes, and reading it once here sent
615
+ // no header for the rest of the run, until a pause and resume re-synced.
616
+ const shouldInject = this.state.isActive && !this.state.isPaused;
604
617
  setImpersonateConfig({
605
618
  headerKey: this.state.headerKey,
606
619
  userId: shouldInject ? this.state.currentUser?.id ?? null : null,
607
- ignorePatterns: this.state.ignorePatterns.map(p => new RegExp(p))
620
+ ignorePatterns: this.state.ignorePatterns.map(p => new RegExp(p)),
621
+ gate: hasAccountAccess
608
622
  });
609
623
 
610
624
  // Ensure listener is started
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { getAsyncStorage } from './impersonate/hooks/asyncStoragePeer';
3
4
  /**
4
5
  * Impersonate Tool Preset
5
6
  *
@@ -30,7 +31,7 @@ import { registerImpersonateSearchUsers } from "./sync/impersonateSyncAdapter";
30
31
 
31
32
  let bootstrapStarted = false;
32
33
  async function bootstrapImpersonate() {
33
- if (bootstrapStarted) return;
34
+ if (typeof window === 'undefined' || bootstrapStarted) return;
34
35
  bootstrapStarted = true;
35
36
 
36
37
  // eslint-disable-next-line no-console
@@ -48,11 +49,10 @@ async function bootstrapImpersonate() {
48
49
  // back to localStorage handled synchronously in its constructor.
49
50
  try {
50
51
  // eslint-disable-next-line @typescript-eslint/no-require-imports
51
- const mod = require("@react-native-async-storage/async-storage");
52
- const AsyncStorage = mod?.default ?? mod;
52
+ const AsyncStorage = getAsyncStorage();
53
53
  if (!AsyncStorage || typeof AsyncStorage.getItem !== "function") {
54
54
  // eslint-disable-next-line no-console
55
- console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected", Object.keys(mod ?? {}));
55
+ console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected", Object.keys(AsyncStorage ?? {}));
56
56
  return;
57
57
  }
58
58
  const adapter = {
@@ -107,7 +107,16 @@ function buildActions(onSearchUsers) {
107
107
  stopImpersonation: () => impersonateStore.stopImpersonation(),
108
108
  pauseImpersonation: () => impersonateStore.pauseImpersonation(),
109
109
  resumeImpersonation: () => impersonateStore.resumeImpersonation(),
110
- updateSettings: params => impersonateStore.updateSettings(params.settings),
110
+ updateSettings: params => {
111
+ // The documented shape is { settings: {...} }, but the flat patch is the
112
+ // obvious guess and used to crash with "Cannot read property 'headerKey'
113
+ // of undefined". Accept both; refuse anything else by name.
114
+
115
+ const p = params ?? {};
116
+ const settings = p.settings ?? (["headerKey", "ignorePatterns", "showBanner", "dataNukeSettings"].some(k => k in p) ? p : undefined);
117
+ if (!settings) throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");
118
+ return impersonateStore.updateSettings(settings);
119
+ },
111
120
  removeFromHistory: params => impersonateStore.removeFromHistory(params.userId),
112
121
  clearHistory: () => impersonateStore.clearHistory()
113
122
  };
@@ -0,0 +1,7 @@
1
+ export declare function getAsyncStorage(): {
2
+ getItem(key: string): Promise<string | null>;
3
+ setItem(key: string, value: string): Promise<void>;
4
+ getAllKeys(): Promise<readonly string[]>;
5
+ multiRemove(keys: string[]): Promise<void>;
6
+ } | null;
7
+ //# sourceMappingURL=asyncStoragePeer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncStoragePeer.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/asyncStoragePeer.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,IAAI;IAAE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,UAAU,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,IAAI,CAUnO"}
@@ -0,0 +1,2 @@
1
+ export declare function getAsyncStorage(): import("@react-native-async-storage/async-storage").AsyncStorageStatic;
2
+ //# sourceMappingURL=asyncStoragePeer.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncStoragePeer.web.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/asyncStoragePeer.web.ts"],"names":[],"mappings":"AACA,wBAAgB,eAAe,2EAA2B"}
@@ -1,15 +1,3 @@
1
- /**
2
- * useAutoClearAsyncStorage Hook
3
- *
4
- * Auto-detects AsyncStorage and provides a clear function.
5
- * Follows the same pattern as useAutoClearReactQuery and useAutoClearRedux.
6
- *
7
- * This hook:
8
- * 1. Dynamically requires @react-native-async-storage/async-storage
9
- * 2. Returns a clearStorage function that removes all non-buoy keys
10
- *
11
- * IMPORTANT: This preserves all @buoy/* keys to avoid clearing our own state.
12
- */
13
1
  export interface UseAutoClearAsyncStorageResult {
14
2
  /** Whether AsyncStorage is available */
15
3
  isAvailable: boolean;
@@ -18,6 +6,9 @@ export interface UseAutoClearAsyncStorageResult {
18
6
  /** Function to clear all non-buoy keys from AsyncStorage */
19
7
  clearStorage: (() => Promise<void>) | null;
20
8
  }
9
+ /**
10
+ * Safely attempt to load @react-native-async-storage/async-storage
11
+ */
21
12
  /**
22
13
  * Hook to auto-detect AsyncStorage and provide clearing functionality.
23
14
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useAutoClearAsyncStorage.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/useAutoClearAsyncStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,MAAM,WAAW,8BAA8B;IAC7C,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,YAAY,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;CAC5C;AAyBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,IAAI,8BAA8B,CA+DzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAcA"}
1
+ {"version":3,"file":"useAutoClearAsyncStorage.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/useAutoClearAsyncStorage.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,8BAA8B;IAC7C,wCAAwC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,YAAY,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;CAC5C;AAMD;;GAEG;AAOH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,IAAI,8BAA8B,CA+DzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAcA"}
@@ -0,0 +1,3 @@
1
+ import type { UseAutoClearReactQueryResult } from './useAutoClearReactQuery';
2
+ export declare function useAutoClearReactQuery(): UseAutoClearReactQueryResult;
3
+ //# sourceMappingURL=useAutoClearReactQuery.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAutoClearReactQuery.web.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/useAutoClearReactQuery.web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAC7E,wBAAgB,sBAAsB,IAAI,4BAA4B,CAOrE"}
@@ -0,0 +1,4 @@
1
+ import type { UseAutoClearReduxOptions, UseAutoClearReduxResult } from './useAutoClearRedux';
2
+ export declare const REDUX_RESET_ACTION_TYPE = "@@RESET";
3
+ export declare function useAutoClearRedux({ resetActionType }?: UseAutoClearReduxOptions): UseAutoClearReduxResult;
4
+ //# sourceMappingURL=useAutoClearRedux.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAutoClearRedux.web.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/hooks/useAutoClearRedux.web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC7F,eAAO,MAAM,uBAAuB,YAAY,CAAC;AACjD,wBAAgB,iBAAiB,CAAC,EAAE,eAAyC,EAAE,GAAE,wBAA6B,GAAG,uBAAuB,CAIvI"}
@@ -69,6 +69,12 @@ export interface ImpersonateListenerConfig {
69
69
  userId: string | null;
70
70
  /** URL patterns to ignore (won't inject header) */
71
71
  ignorePatterns: RegExp[];
72
+ /**
73
+ * Checked on every request; false holds the header back. Lets a session
74
+ * restored before the account check finishes start sending the header the
75
+ * moment access is admitted, without anything re-syncing it.
76
+ */
77
+ gate?: () => boolean;
72
78
  }
73
79
  /**
74
80
  * Developer-configurable defaults for the impersonate tool
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/types/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/types/types.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,7 @@ declare class ImpersonateListener {
50
50
  * to inject the impersonation header on all requests.
51
51
  */
52
52
  startListening(): void;
53
+ private reportHeader;
53
54
  /**
54
55
  * Stop intercepting - restore original methods
55
56
  *
@@ -1 +1 @@
1
- {"version":3,"file":"impersonateListener.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateListener.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAqE1D,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,eAAe,CAAS;IAGhC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,eAAe,CAAuC;IAE9D;;;OAGG;IACH,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAAqD;IAC3E,OAAO,CAAC,cAAc,CAAqD;;IAe3E;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAY5D;;OAEG;IACH,SAAS,IAAI,yBAAyB;IAItC;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IAsGtB;;;;;;OAMG;IACH,aAAa,IAAI,IAAI;IAgCrB;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,OAAO,CAE7B;CACF;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAKzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,yBAAyB,CAAC,GACzC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAErD"}
1
+ {"version":3,"file":"impersonateListener.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateListener.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAqE1D,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,eAAe,CAAS;IAGhC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,eAAe,CAAuC;IAE9D;;;OAGG;IACH,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAAqD;IAC3E,OAAO,CAAC,cAAc,CAAqD;;IAe3E;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAY5D;;OAEG;IACH,SAAS,IAAI,yBAAyB;IAItC;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IA4GtB,OAAO,CAAC,YAAY,CACqE;IAEzF;;;;;;OAMG;IACH,aAAa,IAAI,IAAI;IAmCrB;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,OAAO,CAE7B;CACF;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAKzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,yBAAyB,CAAC,GACzC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAErD"}
@@ -1 +1 @@
1
- {"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAI/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAyEjE;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,CAAC;AAWnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB;;;;;2BAkCxC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;uBAGnC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE;;;;;EAmB3H"}
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAI/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAwEjE;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,CAAC;AAWnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB;;;;;2BAkCxC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;uBAGnC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE;;;;;EAmB3H"}
@@ -1 +1 @@
1
- {"version":3,"file":"impersonateSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/impersonateSyncAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAErE,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAO7D,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,kBAAkB,GAAG,IAAI,GACjC,IAAI,CAEN;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAW,CAAC;AAClD,eAAO,MAAM,8BAA8B,QAAY,CAAC;AAQxD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUrE;AA4FD,UAAU,mCAAmC;IAC3C;;;OAGG;IACH,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,aAAa,GACd,EAAE,mCAAmC;;uBAGjB,kBAAkB;0BACb,MAAM,IAAI;;8BA3DJ,OAAO;sCAQC,OAAO;;;;;;;kCAajB,OAAO;qCAQJ,OAAO;;;EAiCvC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;uBAGhB,kBAAkB;0BACb,MAAM,IAAI;;8BA1EF,OAAO;sCAQC,OAAO;;;;;;;kCAajB,OAAO;qCAQJ,OAAO;;;CAsDvC,CAAC"}
1
+ {"version":3,"file":"impersonateSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/impersonateSyncAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAErE,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAO7D,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,kBAAkB,GAAG,IAAI,GACjC,IAAI,CAEN;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAW,CAAC;AAClD,eAAO,MAAM,8BAA8B,QAAY,CAAC;AAQxD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUrE;AAgGD,UAAU,mCAAmC;IAC3C;;;OAGG;IACH,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,aAAa,GACd,EAAE,mCAAmC;;uBAGjB,kBAAkB;0BACb,MAAM,IAAI;;8BA/DJ,OAAO;sCAQC,OAAO;;;;;;;kCAajB,OAAO;qCAYJ,OAAO;;;EAiCvC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;uBAGhB,kBAAkB;0BACb,MAAM,IAAI;;8BA9EF,OAAO;sCAQC,OAAO;;;;;;;kCAajB,OAAO;qCAYJ,OAAO;;;CAsDvC,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ var yt=Object.defineProperty;var mo=Object.getOwnPropertyDescriptor;var ho=Object.getOwnPropertyNames;var yo=Object.prototype.hasOwnProperty;var fo=(t,e)=>{for(var o in e)yt(t,o,{get:e[o],enumerable:!0})},ht=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ho(e))!yo.call(t,r)&&r!==o&&yt(t,r,{get:()=>e[r],enumerable:!(n=mo(e,r))||n.enumerable});return t},I=(t,e,o)=>(ht(t,e,"default"),o&&ht(o,e,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import So from"@buoy-gg/shared-ui/web/asyncStorage";function ve(){return So}import{useState as Ze,useCallback as he,useRef as Nt,useEffect as Lt}from"react";var f={};fo(f,{AccessibilityInfo:()=>Uo,ActivityIndicator:()=>De,Alert:()=>Ao,Animated:()=>Bo,AppRegistry:()=>No,AppState:()=>Lo,Appearance:()=>Do,BackHandler:()=>Eo,Button:()=>ko,CheckBox:()=>Go,Clipboard:()=>Vo,DeviceEventEmitter:()=>gr,Dimensions:()=>zo,Easing:()=>Oo,FlatList:()=>ae,I18nManager:()=>Wo,Image:()=>Zo,ImageBackground:()=>er,InteractionManager:()=>Fo,Keyboard:()=>Mo,KeyboardAvoidingView:()=>tr,LayoutAnimation:()=>Ko,Linking:()=>_o,LogBox:()=>pr,Modal:()=>Co,NativeEventEmitter:()=>Xo,NativeModules:()=>Po,PanResponder:()=>qo,Picker:()=>or,PixelRatio:()=>Qo,Platform:()=>jo,Pressable:()=>Io,ProgressBar:()=>rr,RefreshControl:()=>nr,SafeAreaView:()=>sr,ScrollView:()=>Be,SectionList:()=>ar,Share:()=>$o,StatusBar:()=>ir,StyleSheet:()=>H,Switch:()=>To,Text:()=>u,TextInput:()=>Ue,Touchable:()=>cr,TouchableHighlight:()=>xo,TouchableNativeFeedback:()=>lr,TouchableOpacity:()=>C,TouchableWithoutFeedback:()=>wo,UIManager:()=>Jo,Vibration:()=>Yo,View:()=>s,VirtualizedList:()=>dr,YellowBox:()=>ur,findNodeHandle:()=>Ro,unstable_createElement:()=>Ho,useColorScheme:()=>mr,useLocaleContext:()=>hr,useWindowDimensions:()=>yr});I(f,Xn);import*as Xn from"react-native-web";import{unstable_createElement as Ho,NativeModules as Po,AccessibilityInfo as Uo,Animated as Bo,Appearance as Do,AppRegistry as No,AppState as Lo,BackHandler as Eo,Clipboard as Vo,Dimensions as zo,Easing as Oo,I18nManager as Wo,Keyboard as Mo,InteractionManager as Fo,LayoutAnimation as Ko,Linking as _o,NativeEventEmitter as Xo,PanResponder as qo,PixelRatio as Qo,Platform as jo,Share as $o,StyleSheet as H,UIManager as Jo,Vibration as Yo,CheckBox as Go,FlatList as ae,Image as Zo,ImageBackground as er,KeyboardAvoidingView as tr,Picker as or,ProgressBar as rr,RefreshControl as nr,SafeAreaView as sr,SectionList as ar,StatusBar as ir,Touchable as cr,TouchableNativeFeedback as lr,VirtualizedList as dr,YellowBox as ur,LogBox as pr,DeviceEventEmitter as gr,useColorScheme as mr,useLocaleContext as hr,useWindowDimensions as yr}from"react-native-web";import*as S from"react-native-web";import{createElement as bo,forwardRef as vo}from"react";function z(t){let e=vo((n,r)=>{let{accessibilityState:g,accessibilityValue:c,...m}=n;for(let a of["busy","checked","disabled","expanded","selected"])g?.[a]!==void 0&&m[`aria-${a}`]===void 0&&(m[`aria-${a}`]=g[a]);for(let[a,h]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))c?.[a]!==void 0&&m[`aria-${h}`]===void 0&&(m[`aria-${h}`]=c[a]);return bo(t,{...m,ref:r})}),o=t.State;return o&&Object.assign(e,{State:o}),e.displayName=t.displayName??t.name??"NativeWebView",e}var s=z(S.View),u=z(S.Text),Ue=z(S.TextInput),C=z(S.TouchableOpacity),xo=z(S.TouchableHighlight),wo=z(S.TouchableWithoutFeedback),Io=z(S.Pressable),Be=z(S.ScrollView),Co=z(S.Modal),To=z(S.Switch),De=z(S.ActivityIndicator),ko=z(S.Button),Ro=S.findNodeHandle,Ao={alert(t,e,o,n){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",t),r.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 g=document.createElement("h2");if(g.textContent=t,g.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(g),e){let h=document.createElement("p");h.textContent=e,h.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(h)}let c=document.createElement("div");c.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let m=o?.length?o:[{text:"OK"}],a=()=>{r.close?.(),r.remove()};for(let h of m){let y=document.createElement("button");y.type="button",y.textContent=h.text??"OK",y.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${h.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,y.onclick=()=>{a(),h.onPress?.()},c.appendChild(y)}r.addEventListener("cancel",h=>{h.preventDefault(),n?.cancelable!==!1&&(a(),n?.onDismiss?.())}),r.appendChild(c),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{JsModal as ln,TabSelector as dn,ModalHeader as ye,buoyColors as un,night as Vt,Search as pn,TickProvider as Et,windowDragProps as gn}from"@buoy-gg/shared-ui/web";import{useState as xe,useEffect as xt,useCallback as W,useSyncExternalStore as Tr}from"react";import{assertAccountAccess as St,getAccountAccess as xr,hasAccountAccess as wr,subscribeAccountAccess as Ir}from"@buoy-gg/shared-ui/web";var ft=[/\/symbolicate$/,/\/logs$/,/\/debugger-proxy/,/\/reload$/,/\/launch-js-devtools/,/localhost:8081/,/100\.64\.\d+\.\d+:8081/,/10\.0\.\d+\.\d+:8081/,/\.hot-update\./,/__metro/];function Ne(t,e){for(let o of Object.keys(e))o.startsWith("__buoy")&&(t[o]=e[o])}var Le=class{constructor(){this.isListeningFlag=!1;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:[...ft]}}setConfig(e){this.config={...this.config,...e},e.ignorePatterns&&(this.config.ignorePatterns=[...ft,...e.ignorePatterns])}getConfig(){return{...this.config}}shouldInjectHeader(e){return!this.config.userId||this.config.gate&&!this.config.gate()?!1:!this.config.ignorePatterns.some(o=>o.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,o=XMLHttpRequest.prototype.open,n=XMLHttpRequest.prototype.send;this.originalFetch=e.bind(globalThis),this.originalXHROpen=o,this.originalXHRSend=n;let r=this,g=async function(y,v){let T=r.extractUrl(y);if(r.shouldInjectHeader(T)){let D=v?.headers??(typeof y=="object"&&"headers"in y?y.headers:void 0),N=new Headers(D);return N.set(r.config.headerKey,r.config.userId),r.originalFetch(y,{...v,headers:N})}return r.originalFetch(y,v)};Ne(g,e),this.patchedFetch=g,globalThis.fetch=this.patchedFetch;let c=function(y,v,T=!0,D,N){let O=this;O._impersonateUrl=typeof v=="string"?v:v.href;let Z=typeof v=="string"?v:v.toString();return r.originalXHROpen.call(this,y,Z,T,D,N)},m=function(y){let v=this;return v._impersonateUrl&&r.shouldInjectHeader(v._impersonateUrl)&&this.setRequestHeader(r.config.headerKey,r.config.userId),r.originalXHRSend.call(this,y)};Ne(c,o),Ne(m,n),this.patchedXHROpen=c,this.patchedXHRSend=m,XMLHttpRequest.prototype.open=this.patchedXHROpen,XMLHttpRequest.prototype.send=this.patchedXHRSend;let a=globalThis,h=a.__buoyHeaderInjectors??(a.__buoyHeaderInjectors=[]);h.includes(this.reportHeader)||h.push(this.reportHeader),this.isListeningFlag=!0}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,o=e?.indexOf(this.reportHeader)??-1;e&&o>=0&&e.splice(o,1),this.isListeningFlag=!1}get isListening(){return this.isListeningFlag}get isImpersonating(){return this.config.userId!==null&&(this.config.gate?.()??!0)}},ie=null;function L(){return ie||(ie=new Le),ie}function fr(){L().startListening()}function Sr(){L().stopListening()}function Ee(t){L().setConfig(t)}function br(){return ie?.isImpersonating??!1}function vr(){return ie?.getConfig().userId??null}var ce="@buoy/impersonate/state",Cr=10,vt={reactQuery:!0,redux:!0,asyncStorage:!1,mmkv:!1},re={isActive:!1,isPaused:!1,currentUser:null,headerKey:"x-impersonate-user-id",ignorePatterns:[],dataNukeSettings:vt,showBanner:!0,history:[]},Ve=!1,bt={getItem:t=>{try{return typeof localStorage<"u"?localStorage.getItem(t):null}catch{return null}},setItem:(t,e)=>{try{typeof localStorage<"u"&&localStorage.setItem(t,e)}catch{}},removeItem:t=>{try{typeof localStorage<"u"&&localStorage.removeItem(t)}catch{}}},ze=class{constructor(){this.state={...re};this.listeners=new Set;this.nukeCallbacks={};this.isInitialized=!1;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=!1,o=()=>{let n=xr().status;n==="admitted"?e=!0:n==="locked"&&e&&(e=!1,this.disposeAccountSession())};Ir(o),o()}),typeof localStorage<"u"?this.storageReadyPromise=Promise.resolve():this.storageReadyPromise=new Promise(e=>{this.resolveStorageReady=e})}loadFromStorage(){try{let e=bt.getItem(ce),o=this.getEffectiveDefaults();if(e){let n=JSON.parse(e);this.state={...re,headerKey:n.headerKey??o.headerKey,ignorePatterns:n.ignorePatterns??re.ignorePatterns,dataNukeSettings:{...o.dataNukeSettings,...n.dataNukeSettings},showBanner:n.showBanner??o.showBanner,history:n.history??[],isActive:n.isActive??!1,isPaused:n.isPaused??!1,currentUser:n.currentUser??null},this.state.isActive&&this.state.currentUser&&this.syncWithListener()}else this.state={...re,headerKey:o.headerKey,dataNukeSettings:o.dataNukeSettings,showBanner:o.showBanner};this.isInitialized=!0}catch{this.isInitialized=!0}}setAsyncStorage(e){this.asyncStorageRef=e,this.resolveStorageReady&&(this.resolveStorageReady(),this.resolveStorageReady=null)}setDeveloperDefaults(e){this.developerDefaults=e;let o=this.getEffectiveDefaults();this.isInitialized||(this.state={...this.state,headerKey:o.headerKey,dataNukeSettings:o.dataNukeSettings,showBanner:o.showBanner})}getEffectiveDefaults(){return{headerKey:this.developerDefaults?.headerKey??re.headerKey,dataNukeSettings:{...vt,...this.developerDefaults?.dataNukeSettings},showBanner:this.developerDefaults?.showBanner??re.showBanner}}getDeveloperDefaults(){return this.developerDefaults}async initializeAsync(e){if(e){this.asyncStorageRef=e;try{let o=await e.getItem(ce);if(console.log(`[impersonate] initializeAsync read STORAGE_KEY=${ce} stored=${o?o.slice(0,200):"null"}`),o){let n=JSON.parse(o);this.state={...this.state,headerKey:n.headerKey??this.state.headerKey,ignorePatterns:n.ignorePatterns??this.state.ignorePatterns,dataNukeSettings:{...this.state.dataNukeSettings,...n.dataNukeSettings},showBanner:n.showBanner??this.state.showBanner,history:n.history??this.state.history,isActive:n.isActive??this.state.isActive,isPaused:n.isPaused??this.state.isPaused,currentUser:n.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 n=[{user:e,lastUsedAt:new Date().toISOString()},...this.state.history.filter(r=>r.user.id!==e.id)].slice(0,Cr);this.state={...this.state,isActive:!0,currentUser:e,history:n},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:!1,isPaused:!1,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:!0},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:!1},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(o=>o.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(!Ve){Ve=!0;try{let{dataNukeSettings:e}=this.state,o=[];e.reactQuery&&this.nukeCallbacks.reactQuery&&o.push(Promise.resolve(this.nukeCallbacks.reactQuery())),e.redux&&this.nukeCallbacks.redux&&o.push(Promise.resolve(this.nukeCallbacks.redux())),e.asyncStorage&&this.nukeCallbacks.asyncStorage&&o.push(Promise.resolve(this.nukeCallbacks.asyncStorage())),e.mmkv&&this.nukeCallbacks.mmkv&&o.push(Promise.resolve(this.nukeCallbacks.mmkv())),await Promise.allSettled(o)}finally{setTimeout(()=>{Ve=!1},100)}}}disposeAccountSession(){this.remoteHandler||!this.state.isActive||(this.state={...this.state,isActive:!1,isPaused:!1,currentUser:null},this.syncWithListener(),this.notify(),this.persist())}syncWithListener(){let e=this.state.isActive&&!this.state.isPaused;Ee({headerKey:this.state.headerKey,userId:e?this.state.currentUser?.id??null:null,ignorePatterns:this.state.ignorePatterns.map(o=>new RegExp(o)),gate:wr}),L().isListening||L().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},o=JSON.stringify(e);try{this.asyncStorageRef?(await this.asyncStorageRef.setItem(ce,o),console.log(`[impersonate] persist -> AsyncStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`)):(bt.setItem(ce,o),console.log(`[impersonate] persist -> localStorage isActive=${e.isActive} userId=${e.currentUser?.id??"null"}`))}catch(n){console.warn("[impersonate] persist failed",n)}}notify(){this.listeners.forEach(e=>{try{e(this.state)}catch{}})}},l=new ze;function Oe(t={}){let[e,o]=xe(""),[n,r]=xe([]),[g,c]=xe(!1),[m,a]=xe(null),h=Tr(l.subscribe,l.getSnapshot,l.getSnapshot);xt(()=>{l.registerNukeCallbacks({reactQuery:t.onClearReactQuery,redux:t.onClearRedux,asyncStorage:t.onClearAsyncStorage,mmkv:t.onClearMMKV})},[t.onClearReactQuery,t.onClearRedux,t.onClearAsyncStorage,t.onClearMMKV]),xt(()=>{let b=!0;return(async()=>{try{let te=await import("@buoy-gg/shared-ui/web/asyncStorage").then(J=>J.default),oe={getItem:J=>te.getItem(J),setItem:(J,He)=>te.setItem(J,He)};l.setAsyncStorage(oe),b&&await l.initializeAsync(oe)}catch{}})(),L().isListening||L().startListening(),()=>{b=!1}},[]);let y=W(async b=>{if(o(b),a(null),!b.trim()){r([]);return}if(!t.onSearchUsers){a("Search not configured"),r([]);return}c(!0);try{let w=await t.onSearchUsers(b);r(w)}catch(w){a(w instanceof Error?w.message:"Search failed"),r([])}finally{c(!1)}},[t.onSearchUsers]),v=W(()=>{o(""),r([]),a(null)},[]),T=W(async b=>{await l.startImpersonation(b)},[]),D=W(async()=>{await l.stopImpersonation()},[]),N=W(async b=>{await l.quickSwitch(b)},[]),O=W(async b=>{await l.updateSettings({headerKey:b})},[]),Z=W(async b=>{await l.updateSettings({ignorePatterns:b})},[]),Q=W(async b=>{await l.updateSettings({dataNukeSettings:b})},[]),ee=W(async b=>{await l.updateSettings({showBanner:b})},[]),F=W(async b=>{await l.removeFromHistory(b)},[]),se=W(async()=>{await l.clearHistory()},[]);return{isActive:h.isActive,currentUser:h.currentUser,headerKey:h.headerKey,ignorePatterns:h.ignorePatterns,dataNukeSettings:h.dataNukeSettings,showBanner:h.showBanner,history:h.history,searchQuery:e,searchResults:n,isSearching:g,searchError:m,searchUsers:y,clearSearch:v,startImpersonation:T,stopImpersonation:D,quickSwitch:N,updateHeaderKey:O,updateIgnorePatterns:Z,updateDataNukeSettings:Q,updateShowBanner:ee,removeFromHistory:F,clearHistory:se}}import{useCallback as kr}from"react";import{dispatchToolAction as wt,getToolAdapters as Rr}from"@buoy-gg/shared-ui/web";function It(){let t=!!Rr().query,e=kr(async()=>{await wt("query","clearQueryCache"),await wt("query","clearMutationCache")},[]);return{isAvailable:t,error:t?null:"Connect React Query to Buoy or provide onClearReactQuery.",clearCache:t?e:null}}import{useCallback as Ar}from"react";import{dispatchToolAction as Hr,getToolAdapters as Pr}from"@buoy-gg/shared-ui/web";var Ur="@@RESET";function Ct({resetActionType:t=Ur}={}){let e=!!Pr().redux,o=Ar(async()=>{await Hr("redux","dispatch",{action:{type:t}})},[t]);return{isAvailable:e,error:e?null:"Connect Redux to Buoy or provide onClearRedux.",resetStore:e?o:null}}import{useCallback as Br,useMemo as Dr,useState as Tt,useEffect as Nr}from"react";var We=!1;function kt(){let[t,e]=Tt(null),[o,n]=Tt(null);Nr(()=>{let c=ve();c?(e(c),n(null)):n("@react-native-async-storage/async-storage is not installed")},[]);let r=Br(async()=>{if(!We){We=!0;try{if(t){let m=(await t.getAllKeys()).filter(a=>!a.startsWith("@buoy/")&&!a.startsWith("@buoy-"));m.length>0&&await t.multiRemove([...m])}}finally{setTimeout(()=>{We=!1},100)}}},[t]);return Dr(()=>!t||o?{isAvailable:!1,error:o||"@react-native-async-storage/async-storage is not available",clearStorage:null}:{isAvailable:!0,error:null,clearStorage:r},[t,o,r])}import{useCallback as Xr}from"react";import{SectionHeader as Ke,EmptyState as qr,night as U,Search as Qr,AlertTriangle as Ht,Users as jr}from"@buoy-gg/shared-ui/web";import{buoyColors as Fe,night as V,Play as Mr,X as Fr,PowerToggleButton as Kr,monoFont as _r}from"@buoy-gg/shared-ui/web";import{useMemo as Rt}from"react";import{buoyColors as Lr,night as Er}from"@buoy-gg/shared-ui/web";import{jsx as Me,jsxs as Wr}from"react/jsx-runtime";var At=["#6366F1","#8B5CF6","#EC4899","#F43F5E","#F97316","#EAB308","#22C55E","#14B8A6","#06B6D4","#3B82F6"],Vr={small:{container:24,font:10,indicator:8},medium:{container:36,font:14,indicator:10},large:{container:44,font:16,indicator:12}};function zr(t){if(!t)return"?";if(t.includes("@"))return t.charAt(0).toUpperCase();let e=t.trim().split(/\s+/);return e.length===1?e[0].charAt(0).toUpperCase():(e[0].charAt(0)+e[e.length-1].charAt(0)).toUpperCase()}function Or(t){let e=0;for(let o=0;o<t.length;o++)e=t.charCodeAt(o)+((e<<5)-e);return At[Math.abs(e)%At.length]}function ne({userId:t,name:e,size:o="medium",showActiveIndicator:n=!1,backgroundColor:r}){let g=Vr[o],c=Rt(()=>r??Or(t),[t,r]),m=Rt(()=>zr(e),[e]);return Wr(s,{style:we.wrapper,children:[Me(s,{style:[we.container,{width:g.container,height:g.container,borderRadius:g.container/2,backgroundColor:c}],children:Me(u,{style:[we.initials,{fontSize:g.font}],children:m})}),n&&Me(s,{style:[we.indicator,{width:g.indicator,height:g.indicator,borderRadius:g.indicator/2,right:-1,bottom:-1}]})]})}var we=H.create({wrapper:{position:"relative"},container:{alignItems:"center",justifyContent:"center"},initials:{color:"#FFFFFF",fontWeight:"600",letterSpacing:.5},indicator:{position:"absolute",backgroundColor:Lr.success,borderWidth:2,borderColor:Er.color.surface}});import{jsx as E,jsxs as le}from"react/jsx-runtime";function Ie({user:t,isActive:e=!1,onPress:o,onStop:n,onRemove:r,showRemoveButton:g=!1,lastUsedTime:c,variant:m="default"}){let a=t.displayName||t.email||t.id,h=t.email&&t.displayName,y=typeof t.metadata?.role=="string"?t.metadata.role:null;return le(C,{testID:`buoy-impersonate-user-${t.id}`,style:[P.container,e&&P.activeContainer,m==="compact"&&P.compactContainer],onPress:o,disabled:e,activeOpacity:.7,children:[E(s,{style:P.avatarSection,children:E(ne,{userId:t.id,name:a,size:m==="compact"?"small":"medium",showActiveIndicator:e})}),le(s,{style:P.content,children:[le(s,{style:P.nameRow,children:[E(u,{style:[P.name,e&&P.activeName],numberOfLines:1,children:a}),y?E(s,{style:P.roleBadge,children:E(u,{style:P.roleBadgeText,children:y.toUpperCase()})}):null]}),h&&E(u,{style:P.email,numberOfLines:1,children:t.email}),E(s,{style:P.metadataRow,children:le(u,{style:P.userId,children:["ID: ",t.id]})})]}),le(s,{style:P.actions,children:[e?E(Kr,{isEnabled:!0,onToggle:n||(()=>{}),accessibilityLabel:"Stop impersonation"}):E(C,{style:P.actionButton,onPress:o,activeOpacity:.7,children:E(Mr,{size:14,color:V.color.onAccent})}),g&&r&&!e&&E(C,{style:P.removeButton,onPress:r,activeOpacity:.7,children:E(Fr,{size:12,color:V.color.textTertiary})})]}),c?E(u,{style:P.lastUsed,children:c}):null]})}var P=H.create({container:{flexDirection:"row",alignItems:"center",backgroundColor:V.color.surface,borderRadius:10,borderWidth:1,borderColor:V.color.border,padding:12,gap:12},activeContainer:{backgroundColor:Fe.success+"10",borderColor:Fe.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:V.color.text,flexShrink:1},activeName:{color:Fe.success},roleBadge:{backgroundColor:V.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},roleBadgeText:{fontSize:9,fontWeight:"700",color:V.color.textTertiary,letterSpacing:.5},email:{fontSize:13,color:V.color.textSecondary,marginBottom:4},metadataRow:{flexDirection:"row",alignItems:"center",gap:4},userId:{fontSize:11,color:V.color.textTertiary,fontFamily:_r},lastUsed:{position:"absolute",bottom:8,right:10,fontSize:10,color:V.color.textTertiary},actions:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:0},actionButton:{width:36,height:36,borderRadius:8,backgroundColor:V.color.accent,alignItems:"center",justifyContent:"center"},removeButton:{width:28,height:28,borderRadius:6,backgroundColor:V.color.surfaceElevated,borderWidth:1,borderColor:V.color.border,alignItems:"center",justifyContent:"center"}});import{jsx as A,jsxs as K}from"react/jsx-runtime";function _e({currentUser:t,searchQuery:e,searchResults:o,isSearching:n,searchError:r,onSelectUser:g,onStopImpersonation:c,searchAvailable:m=!0}){let a=Xr(({item:h})=>{let y=t?.id===h.id;return A(Ie,{user:h,isActive:y,onPress:()=>!y&&g(h),onStop:y?c:void 0})},[t,g,c]);return K(s,{style:R.container,children:[!m&&A(s,{style:R.section,children:K(s,{style:R.warningCard,children:[A(Ht,{size:18,color:U.color.warning}),K(s,{style:R.warningContent,children:[A(u,{style:R.warningTitle,children:"Search Not Available"}),A(u,{style:R.warningText,children:"Configure the onSearchUsers callback to enable user search."})]})]})}),n&&K(s,{style:R.loadingContainer,children:[A(De,{size:"small",color:U.color.accent}),A(u,{style:R.loadingText,children:"Searching users..."})]}),r?A(s,{style:R.section,children:K(s,{style:R.errorCard,children:[A(Ht,{size:16,color:U.color.danger}),A(u,{style:R.errorText,children:r})]})}):null,o.length>0&&K(s,{style:R.resultsSection,children:[K(Ke,{children:[A(Ke.Title,{children:"Results"}),A(Ke.Badge,{count:o.length})]}),A(ae,{data:o,keyExtractor:h=>h.id,renderItem:a,ItemSeparatorComponent:()=>A(s,{style:R.separator}),contentContainerStyle:R.listContent,showsVerticalScrollIndicator:!1})]}),!!e&&!n&&o.length===0&&!r&&K(s,{style:R.emptyStateContainer,children:[A(s,{style:R.emptyStateIcon,children:A(jr,{size:28,color:U.color.textTertiary})}),A(u,{style:R.emptyStateTitle,children:"No users found"}),K(u,{style:R.emptyStateDescription,children:['No results for "',e,'"']}),A(u,{style:R.emptyStateHint,children:"Try a different search term"})]}),!e&&o.length===0&&!n&&m&&A(qr,{title:"Search for users",description:"Tap the search icon in the header to find users by email, name, or ID",icon:Qr,variant:"minimal"})]})}var R=H.create({container:{flex:1},section:{padding:16,paddingBottom:8},loadingContainer:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10,paddingVertical:20},loadingText:{fontSize:13,color:U.color.textSecondary},resultsSection:{flex:1,paddingHorizontal:16},listContent:{paddingBottom:16},separator:{height:8},warningCard:{flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:U.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:U.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:14,fontWeight:"600",color:U.color.warning,marginBottom:4},warningText:{fontSize:13,color:U.color.textSecondary,lineHeight:18},errorCard:{flexDirection:"row",alignItems:"center",gap:10,backgroundColor:U.color.dangerSoft,borderRadius:10,borderWidth:1,borderColor:U.color.danger+"25",padding:12},errorText:{flex:1,fontSize:13,color:U.color.danger},emptyStateContainer:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:32,paddingVertical:48},emptyStateIcon:{width:56,height:56,borderRadius:28,backgroundColor:U.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyStateTitle:{fontSize:16,fontWeight:"600",color:U.color.text,marginBottom:6},emptyStateDescription:{fontSize:14,color:U.color.textSecondary,textAlign:"center",marginBottom:8},emptyStateHint:{fontSize:12,color:U.color.textTertiary}});import{useCallback as $r}from"react";import{night as j,Trash2 as Jr,useRelativeTime as Yr,ToolEmptyState as Gr}from"@buoy-gg/shared-ui/web";import{jsx as M,jsxs as Pt}from"react/jsx-runtime";function Zr({item:t,isActive:e,onSelect:o,onStop:n,onRemove:r,showRemoveButton:g}){let c=Yr(new Date(t.lastUsedAt));return M(Ie,{user:t.user,isActive:e,onPress:()=>!e&&o(t.user),onStop:e?n:void 0,onRemove:r,showRemoveButton:g,lastUsedTime:c})}function Xe({history:t,currentUserId:e,onSelectUser:o,onStopImpersonation:n,onRemoveFromHistory:r,onClearHistory:g}){let c=$r(({item:m})=>{let a=e===m.user.id;return M(Zr,{item:m,isActive:a,onSelect:o,onStop:n,onRemove:r?()=>r(m.user.id):void 0,showRemoveButton:!!r})},[e,o,n,r]);return t.length===0?M(Gr,{testID:"buoy-impersonate-history-empty",otto:"disguise",title:"No History",message:"Users you impersonate will appear here for quick access"}):Pt(s,{style:_.container,children:[Pt(s,{style:_.headerRow,children:[M(u,{style:_.headerTitle,children:"Recent"}),M(s,{style:_.headerBadge,children:M(u,{style:_.headerBadgeText,children:t.length})}),M(s,{style:_.headerSpacer}),g&&M(C,{style:_.clearButton,onPress:g,activeOpacity:.7,children:M(Jr,{size:12,color:j.color.textTertiary})})]}),M(ae,{data:t,keyExtractor:m=>m.user.id,renderItem:c,ItemSeparatorComponent:()=>M(s,{style:_.separator}),contentContainerStyle:_.listContent,showsVerticalScrollIndicator:!1})]})}var _=H.create({container:{flex:1,paddingHorizontal:16},headerRow:{flexDirection:"row",alignItems:"center",paddingVertical:10,gap:8},headerTitle:{fontSize:12,fontWeight:"600",color:j.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},headerBadge:{backgroundColor:j.color.surfaceElevated,paddingHorizontal:6,paddingVertical:2,borderRadius:4},headerBadgeText:{fontSize:10,fontWeight:"600",color:j.color.textTertiary},headerSpacer:{flex:1},clearButton:{width:24,height:24,alignItems:"center",justifyContent:"center",backgroundColor:j.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:j.color.surfaceElevated,alignItems:"center",justifyContent:"center",marginBottom:16},emptyTitle:{fontSize:16,fontWeight:"600",color:j.color.text,marginBottom:6},emptyDescription:{fontSize:14,color:j.color.textSecondary,textAlign:"center"}});import{useState as Ce,useEffect as qe,useMemo as Qe}from"react";import{CollapsibleSection as de,buoyColors as me,night as p,Settings as en,AlertTriangle as Ut,Info as tn,Zap as on,RefreshCw as rn,Check as Je,X as Dt,Copy as Bt,Eye as nn,copyToClipboard as sn,ToggleRow as an,monoFont as je}from"@buoy-gg/shared-ui/web";import{DataViewer as cn}from"@buoy-gg/shared-ui/web/dataViewer";import{Fragment as Ye,jsx as d,jsxs as x}from"react/jsx-runtime";var ue="x-impersonate-user-id",$e=!0,pe={reactQuery:!0,redux:!0,asyncStorage:!1,mmkv:!1};function ge({label:t,description:e,value:o,onChange:n,recommended:r,dangerous:g,detected:c}){let m=x(Ye,{children:[c!==void 0&&x(s,{style:[i.detectedBadge,c?i.detectedBadgeActive:i.detectedBadgeInactive],children:[c?d(Je,{size:10,color:me.success}):d(Dt,{size:10,color:p.color.textTertiary}),d(u,{style:[i.detectedText,c?i.detectedTextActive:i.detectedTextInactive],children:c?"Detected":"Not Detected"})]}),r&&c!==!1&&x(s,{style:i.recommendedBadge,children:[d(on,{size:10,color:p.color.accent}),d(u,{style:i.recommendedText,children:"Recommended"})]})]});return d(an,{variant:"plain",label:t,description:e,value:o,onValueChange:n,tone:g?"warning":"accent",emphasizeLabel:g,accessory:m})}function Ge({headerKey:t,settings:e,showBanner:o,onSave:n,onShowBannerChange:r,detectionStatus:g}){let[c,m]=Ce(t),[a,h]=Ce(e),[y,v]=Ce(o),[T,D]=Ce(!1);qe(()=>{m(t)},[t]),qe(()=>{h(e)},[e]),qe(()=>{v(o)},[o]);let N=Qe(()=>c!==t||a.reactQuery!==e.reactQuery||a.redux!==e.redux||a.asyncStorage!==e.asyncStorage||a.mmkv!==e.mmkv,[c,a,t,e]),O=Qe(()=>c===ue&&y===$e&&a.reactQuery===pe.reactQuery&&a.redux===pe.redux&&a.asyncStorage===pe.asyncStorage&&a.mmkv===pe.mmkv,[c,y,a]),Z=()=>{n(c.trim()||ue,a,y)},Q=()=>{m(t),h(e),v(o)},ee=()=>{m(ue),h(pe),v($e),r($e)},F=(w,te)=>{h(oe=>({...oe,[w]:te}))},se=Qe(()=>({defaults:{headerKey:c,showBanner:y,dataNukeSettings:{reactQuery:a.reactQuery,redux:a.redux,asyncStorage:a.asyncStorage,mmkv:a.mmkv}}}),[c,y,a]),b=async()=>{let w=`defaults: {
3
+ headerKey: '${c}',
4
+ showBanner: ${y},
5
+ dataNukeSettings: {
6
+ reactQuery: ${a.reactQuery},
7
+ redux: ${a.redux},
8
+ asyncStorage: ${a.asyncStorage},
9
+ mmkv: ${a.mmkv},
10
+ },
11
+ },`;try{await sn(w),D(!0),setTimeout(()=>D(!1),2e3)}catch{}};return x(Be,{style:i.container,contentContainerStyle:i.contentContainer,children:[N&&d(s,{style:i.actionBar,children:x(s,{style:i.actionBarContent,children:[d(u,{style:i.unsavedText,children:"Unsaved changes"}),x(s,{style:i.actionButtons,children:[x(C,{style:i.discardButton,onPress:Q,children:[d(Dt,{size:14,color:p.color.textSecondary}),d(u,{style:i.discardButtonText,children:"Discard"})]}),x(C,{style:i.saveButton,onPress:Z,children:[d(Je,{size:14,color:p.color.onAccent}),d(u,{style:i.saveButtonText,children:"Save"})]})]})]})}),d(de,{title:"Header Configuration",icon:en,defaultOpen:!0,variant:"bordered",children:x(s,{style:i.sectionContent,children:[d(u,{style:i.inputLabel,children:"Header Key"}),d(Ue,{style:i.input,value:c,onChangeText:m,placeholder:"x-impersonate-user-id",placeholderTextColor:p.color.placeholder,autoCapitalize:"none",autoCorrect:!1}),x(s,{style:i.inputFooter,children:[d(u,{style:i.helperText,children:"The HTTP header key used for impersonation. Value will be the user ID."}),c!==ue&&d(C,{onPress:()=>m(ue),style:i.resetLink,children:d(u,{style:i.resetLinkText,children:"Reset to default"})})]})]})}),d(de,{title:"Display",icon:nn,defaultOpen:!0,variant:"bordered",children:d(s,{style:i.sectionContent,children:d(s,{style:i.togglesCard,children:d(ge,{label:"Floating Banner",description:"Show a floating banner when impersonation is active",value:y,onChange:w=>{v(w),r(w)},recommended:!0})})})}),d(de,{title:"Data Clearing",icon:Ut,defaultOpen:!0,variant:"bordered",children:x(s,{style:i.sectionContent,children:[d(u,{style:i.sectionDescription,children:"Choose what data to clear when impersonation starts or stops. This ensures you see fresh data for the impersonated user."}),x(s,{style:i.togglesCard,children:[d(ge,{label:"React Query",description:"Clear query cache and cancel pending queries",value:a.reactQuery,onChange:w=>F("reactQuery",w),recommended:!0,detected:g?.reactQuery}),d(s,{style:i.divider}),d(ge,{label:"Redux",description:"Reset Redux store to initial state",value:a.redux,onChange:w=>F("redux",w),recommended:!0,detected:g?.redux})]}),x(s,{style:i.advancedSection,children:[d(u,{style:i.advancedLabel,children:"Storage Options"}),x(s,{style:[i.togglesCard,i.dangerousCard],children:[d(ge,{label:"AsyncStorage",description:"Clear app data (preserves @buoy/* keys)",value:a.asyncStorage,onChange:w=>F("asyncStorage",w),dangerous:!0,detected:g?.asyncStorage}),d(s,{style:i.divider}),d(ge,{label:"MMKV",description:"Clear MMKV storage (preserves @buoy/* keys)",value:a.mmkv,onChange:w=>F("mmkv",w),dangerous:!0,detected:g?.mmkv})]})]}),(a.asyncStorage||a.mmkv)&&x(s,{style:i.warningCard,children:[d(Ut,{size:16,color:p.color.warning}),x(s,{style:i.warningContent,children:[d(u,{style:i.warningTitle,children:"Storage Clearing Enabled"}),d(u,{style:i.warningText,children:"This will remove app data like settings and cached content. Auth tokens managed by @buoy/* are preserved."})]})]})]})}),!O&&x(C,{style:i.restoreButton,onPress:ee,children:[d(rn,{size:14,color:p.color.textSecondary}),d(u,{style:i.restoreButtonText,children:"Restore Defaults"})]}),d(de,{title:"How It Works",icon:tn,defaultOpen:!1,variant:"bordered",children:x(s,{style:i.sectionContent,children:[d(u,{style:i.infoText,children:"When impersonation is enabled, the configured header is automatically added to all outgoing fetch and XMLHttpRequest calls."}),d(u,{style:[i.infoText,i.infoTextSpaced],children:"Your backend should check for this header and return data for the specified user ID instead of the authenticated user."}),x(s,{style:i.codeBlock,children:[d(u,{style:i.codeComment,children:"// Example request header"}),x(u,{style:i.codeText,children:[c||"x-impersonate-user-id",": ",d(u,{style:i.codeValue,children:"user_123"})]})]})]})}),d(de,{title:"Export Configuration",icon:Bt,defaultOpen:!1,variant:"bordered",children:x(s,{style:i.sectionContent,children:[d(u,{style:i.infoText,children:"Copy current settings to use in createImpersonateTool()."}),d(s,{style:i.dataViewerContainer,children:d(cn,{title:"",data:se,showTypeFilter:!0,rawMode:!0,initialExpanded:!0})}),d(C,{style:i.copyButton,onPress:b,children:T?x(Ye,{children:[d(Je,{size:14,color:me.success}),d(u,{style:[i.copyButtonText,i.copySuccessText],children:"Copied!"})]}):x(Ye,{children:[d(Bt,{size:14,color:p.color.accent}),d(u,{style:i.copyButtonText,children:"Copy Config"})]})})]})})]})}var i=H.create({container:{flex:1},contentContainer:{padding:16,gap:12,paddingBottom:32},actionBar:{backgroundColor:p.color.accentSoft,borderRadius:10,borderWidth:1,borderColor:p.color.accentBorder,padding:12},actionBarContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},unsavedText:{fontSize:13,fontWeight:"500",color:p.color.accent},actionButtons:{flexDirection:"row",gap:8},saveButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:p.color.accent,paddingHorizontal:14,paddingVertical:8,borderRadius:6},saveButtonText:{fontSize:13,fontWeight:"600",color:p.color.onAccent},discardButton:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:p.color.surfaceElevated,paddingHorizontal:14,paddingVertical:8,borderRadius:6,borderWidth:1,borderColor:p.color.border},discardButtonText:{fontSize:13,fontWeight:"500",color:p.color.textSecondary},restoreButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,paddingVertical:12,borderRadius:8,borderWidth:1,borderColor:p.color.border,borderStyle:"dashed"},restoreButtonText:{fontSize:13,color:p.color.textSecondary},sectionContent:{paddingTop:8},sectionDescription:{fontSize:13,color:p.color.textSecondary,lineHeight:18,marginBottom:14},togglesCard:{backgroundColor:p.color.surface,borderRadius:10,borderWidth:1,borderColor:p.color.border,padding:4},dangerousCard:{borderColor:p.color.warning+"30"},advancedSection:{marginTop:16},advancedLabel:{fontSize:11,fontWeight:"600",color:p.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,marginBottom:8,marginLeft:2},inputLabel:{fontSize:12,fontWeight:"600",color:p.color.textSecondary,marginBottom:8},input:{height:42,backgroundColor:p.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:p.color.border,paddingHorizontal:14,fontSize:14,color:p.color.text,fontFamily:je},inputFooter:{flexDirection:"row",justifyContent:"space-between",alignItems:"flex-start",marginTop:8,gap:12},helperText:{flex:1,fontSize:12,color:p.color.textTertiary,lineHeight:16},resetLink:{paddingVertical:2},resetLinkText:{fontSize:12,color:p.color.accent,fontWeight:"500"},recommendedBadge:{flexDirection:"row",alignItems:"center",gap:4,backgroundColor:p.color.accentSoft,paddingHorizontal:8,paddingVertical:3,borderRadius:4},recommendedText:{fontSize:10,fontWeight:"600",color:p.color.accent},detectedBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:8,paddingVertical:3,borderRadius:4},detectedBadgeActive:{backgroundColor:me.success+"15"},detectedBadgeInactive:{backgroundColor:p.color.textTertiary+"15"},detectedText:{fontSize:10,fontWeight:"600"},detectedTextActive:{color:me.success},detectedTextInactive:{color:p.color.textTertiary},divider:{height:1,backgroundColor:p.color.separator,marginHorizontal:12},warningCard:{marginTop:14,flexDirection:"row",alignItems:"flex-start",gap:12,backgroundColor:p.color.warningSoft,borderRadius:10,borderWidth:1,borderColor:p.color.warning+"25",padding:14},warningContent:{flex:1},warningTitle:{fontSize:13,fontWeight:"600",color:p.color.warning,marginBottom:4},warningText:{fontSize:12,color:p.color.textSecondary,lineHeight:17},infoText:{fontSize:13,color:p.color.textSecondary,lineHeight:19},infoTextSpaced:{marginTop:10},codeBlock:{marginTop:14,backgroundColor:p.color.bg,borderRadius:8,padding:14},codeComment:{fontSize:12,color:p.color.textTertiary,fontFamily:je,marginBottom:6},codeText:{fontSize:13,color:p.color.text,fontFamily:je},codeValue:{color:p.color.accent},dataViewerContainer:{marginTop:12,borderRadius:8,overflow:"hidden",borderWidth:1,borderColor:p.color.border},copyButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,marginTop:14,backgroundColor:p.color.accentSoft,paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderColor:p.color.accentBorder},copyButtonText:{fontSize:13,fontWeight:"600",color:p.color.accent},copySuccessText:{color:me.success}});import{jsx as B,jsxs as et}from"react/jsx-runtime";var mn=ln,hn=[{key:"search",label:"Search"},{key:"history",label:"History"},{key:"settings",label:"Settings"}],yn=[{key:"search",label:"Search"},{key:"history",label:"History"}];function ke({visible:t,onClose:e,onBack:o,onMinimize:n,onSearchUsers:r,onClearReactQuery:g,onClearRedux:c,onClearAsyncStorage:m,onClearMMKV:a,showSettingsTab:h=!0,inline:y=!1}){let v=h?hn:yn,[T,D]=Ze("search"),[N,O]=Ze(!1),Z=Nt(!1),[Q,ee]=Ze(""),F=Nt(null),{clearCache:se,isAvailable:b}=It(),{resetStore:w,isAvailable:te}=Ct(),{clearStorage:oe,isAvailable:J}=kt(),He=g??se??void 0,Qt=c??w??void 0,jt=m??oe??void 0,$t={reactQuery:!!g||b,redux:!!c||te,asyncStorage:!!m||J,mmkv:!!a},{isActive:Jt,currentUser:at,headerKey:Yt,dataNukeSettings:Gt,showBanner:Zt,searchQuery:eo,searchResults:to,isSearching:oo,searchError:ro,searchUsers:it,startImpersonation:ct,stopImpersonation:lt,updateHeaderKey:dt,updateDataNukeSettings:ut,updateShowBanner:Pe,history:no,removeFromHistory:so,clearHistory:ao}=Oe({onSearchUsers:r,onClearReactQuery:He,onClearRedux:Qt,onClearAsyncStorage:jt,onClearMMKV:a});Lt(()=>{N&&F.current&&setTimeout(()=>{F.current?.focus()},100)},[N]),Lt(()=>{!h&&T==="settings"&&D("search")},[h,T]);let io=he(Y=>{ee(Y)},[]),co=he(()=>{Q.trim()&&it(Q.trim()),O(!1)},[Q,it]),pt=he(async Y=>{await ct(Y)},[ct]),lo=he(async(Y,po,go)=>{await dt(Y),await ut(po),await Pe(go)},[dt,ut,Pe]),uo=he(Y=>{D(Y),O(!1)},[]),gt=()=>et(ye,{children:[o&&B(ye.Navigation,{onBack:o}),B(ye.Content,{title:"",children:N?B(ye.Search,{value:Q,onChangeText:io,onCancel:()=>{ee(""),O(!1)},onDismiss:()=>O(!1),dismissOnBlur:!0,placeholder:"Search by email, name, or ID...",iconSize:14,testID:"buoy-impersonate-search-input",inputProps:{onSubmitEditing:co}}):B(dn,{tabs:v,activeTab:T,onTabChange:uo})}),B(ye.Actions,{children:T==="search"&&!N&&B(C,{testID:"buoy-impersonate-search-toggle",onPress:()=>O(!0),style:Te.headerActionButton,children:B(pn,{size:14,color:Vt.color.textSecondary})})})]});if(!t)return null;let mt=et(s,{style:Te.container,children:[T==="search"&&B(_e,{currentUser:at,isActive:Jt,searchQuery:eo,searchResults:to,isSearching:oo,searchError:ro,onSelectUser:pt,onStopImpersonation:lt,searchAvailable:!!r}),T==="history"&&B(Xe,{history:no,currentUserId:at?.id??null,onSelectUser:pt,onStopImpersonation:lt,onRemoveFromHistory:so,onClearHistory:ao}),T==="settings"&&B(Ge,{headerKey:Yt,settings:Gt,showBanner:Zt,onSave:lo,onShowBannerChange:Pe,detectionStatus:$t})]});return y?B(Et,{children:et(s,{style:Te.inlineRoot,children:[B(s,{style:Te.inlineHeader,...gn,children:gt()}),mt]})}):B(Et,{children:B(mn,{visible:t,onClose:e,onMinimize:n,header:{showToggleButton:!0,customContent:gt()},enablePersistence:!0,initialMode:"bottomSheet",disableScrollWrapper:!0,children:mt})})}function fn(t){return B(ke,{...t,inline:!0,visible:!0,onClose:()=>{}})}var Te=H.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:un.border,backgroundColor:"transparent"},container:{flex:1},headerActionButton:{width:28,height:28,borderRadius:6,backgroundColor:Vt.color.buttonSurface,justifyContent:"center",alignItems:"center"}});import{useSyncExternalStore as zt}from"react";import{buoyColors as Re,X as Sn,PowerToggleButton as bn}from"@buoy-gg/shared-ui/web";import{jsx as $,jsxs as tt}from"react/jsx-runtime";function fe({onPress:t,onStopPress:e,position:o="top",offset:n=50}){let r=zt(l.subscribe,l.getSnapshot,l.getSnapshot);if(!r.isActive||!r.currentUser||!r.showBanner)return null;let g=async()=>{console.log("[impersonate] banner pause/resume pressed"),r.isPaused?await l.resumeImpersonation():await l.pauseImpersonation()},c=r.currentUser.displayName||r.currentUser.email||r.currentUser.id,m=o==="top"?{top:n}:{bottom:n},a=async()=>{console.log("[impersonate] banner STOP pressed"),await l.stopImpersonation()};return $(s,{style:[X.container,m],children:tt(s,{style:X.banner,children:[tt(C,{style:X.userSection,onPress:t,activeOpacity:.7,children:[$(ne,{userId:r.currentUser.id,name:c,size:"small",showActiveIndicator:!1}),$(u,{style:[X.userName,r.isPaused&&X.userNamePaused],numberOfLines:1,children:c})]}),$(bn,{isEnabled:!r.isPaused,onToggle:g,size:"small",accessibilityLabel:"Toggle impersonation"}),$(C,{style:X.closeButton,onPress:a,activeOpacity:.7,children:$(Sn,{size:12,color:"rgba(255, 255, 255, 0.5)"})})]})})}function vn({onPress:t}){let e=zt(l.subscribe,l.getSnapshot,l.getSnapshot);return!e.isActive||!e.currentUser?null:tt(C,{style:X.minimalBanner,onPress:t,activeOpacity:.8,children:[$(s,{style:X.minimalDot}),$(u,{style:X.minimalText,children:"IMP"})]})}var X=H.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:Re.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:Re.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:Re.success},minimalText:{fontSize:10,fontWeight:"700",color:Re.success,letterSpacing:.5}});import{isOverWireBudget as xn}from"@buoy-gg/shared-ui/web";var rt=null;function Wt(t){rt=t}var ot=2*1024,wn=16*1024,Ot=Object.freeze({__buoyOmitted:"user-metadata",note:"User metadata stays on the device."});function In(t){if(!t)return t;if(t.startsWith("data:")){let e=t.indexOf(",");return`${e>=0?t.slice(0,Math.min(e+1,64)):"data:"}[${t.length} chars]`}return t.length<=ot?t:`${t.slice(0,ot)}\u2026 [${t.length-ot} more]`}function Cn(t){if(!t)return t;let e=typeof t.role=="string"?t.role:void 0;return xn(t,wn)?e?{role:e,...Ot}:{...Ot}:t}function nt(t){return{...t,avatarUrl:In(t.avatarUrl),metadata:Cn(t.metadata)}}function Mt(t){return{...t,currentUser:t.currentUser?nt(t.currentUser):null,history:t.history.map(e=>({...e,user:nt(e.user)}))}}var Ft=new Set;function Tn(t){for(let e of t)e&&typeof e=="object"&&e.id&&Ft.add(String(e.id))}function kn(t){if(!t||typeof t!="object"||!t.id)return!1;if(Ft.has(String(t.id)))return!0;let e=l.getState();return e.currentUser?.id===t.id?!0:e.history.some(o=>o.user.id===t.id)}function Kt(t){return{searchUsers:async e=>{let o=String(e?.query??""),n=await t(o);return Array.isArray(n)&&Tn(n),Array.isArray(n)?n.map(nt):n},startImpersonation:async e=>{let o=e?.user;if(!kn(o))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.");return await l.startImpersonation(o),{ok:!0,userId:o.id}},stopImpersonation:()=>l.stopImpersonation(),pauseImpersonation:()=>l.pauseImpersonation(),resumeImpersonation:()=>l.resumeImpersonation(),updateSettings:e=>{let o=e??{},n=o.settings??(["headerKey","ignorePatterns","showBanner","dataNukeSettings"].some(r=>r in o)?o:void 0);if(!n)throw new Error("updateSettings needs { settings: { headerKey?, ignorePatterns?, showBanner?, dataNukeSettings? } }.");return l.updateSettings(n)},removeFromHistory:e=>l.removeFromHistory(e.userId),clearHistory:()=>l.clearHistory()}}function Rn({onSearchUsers:t}){return{version:1,getSnapshot:()=>Mt(l.getState()),subscribe:e=>l.subscribe(e),actions:Kt(t)}}var An={dispose:()=>l.disposeAccountSession(),version:1,getSnapshot:()=>Mt(l.getState()),subscribe:t=>l.subscribe(t),actions:Kt(t=>{if(!rt)throw new Error("No onSearchUsers configured \u2014 pass it to createImpersonateTool()");return rt(t)})};import{ImpersonateIcon as qt,IMPERSONATE_ICON_COLOR as Pn}from"@buoy-gg/shared-ui/web";import{jsx as Xt}from"react/jsx-runtime";var _t=!1;async function Hn(){if(!(typeof window>"u"||_t)){_t=!0,console.log("[impersonate] bootstrap: start"),L().isListening||L().startListening();try{let t=ve();if(!t||typeof t.getItem!="function"){console.warn("[impersonate] bootstrap: AsyncStorage shape unexpected",Object.keys(t??{}));return}let e={getItem:o=>t.getItem(o),setItem:(o,n)=>t.setItem(o,n)};l.setAsyncStorage(e),console.log("[impersonate] bootstrap: AsyncStorage adapter installed"),await l.initializeAsync(e),console.log("[impersonate] bootstrap: initializeAsync done")}catch(t){console.warn("[impersonate] bootstrap: failed",t)}}}function Un(t){let{id:e="impersonate",name:o="IMPERSONATE",description:n="User impersonation for admin testing",defaults:r,showSettingsTab:g=!0,onSearchUsers:c,onClearReactQuery:m,onClearRedux:a,onClearAsyncStorage:h,onClearMMKV:y}=t;return r&&l.setDeveloperDefaults(r),Wt(c??null),Hn(),{id:e,name:o,description:n,slot:"both",icon:({size:T,slot:D})=>Xt(qt,{size:D==="dial"?T*1.5:T,color:Pn}),component:T=>Xt(ke,{...T,onSearchUsers:c,onClearReactQuery:m,onClearRedux:a,onClearAsyncStorage:h,onClearMMKV:y,showSettingsTab:g}),props:{enableSharedModalDimensions:!1},Banner:fe}}import{jsx as Dn}from"react/jsx-runtime";function Bn(){return Dn(fe,{position:"top",offset:50})}import{buoyColors as Se,night as be,X as Nn}from"@buoy-gg/shared-ui/web";import{jsx as G,jsxs as Ae}from"react/jsx-runtime";function Ln({user:t,onStopImpersonation:e}){let o=t.displayName||t.email||t.id;return Ae(s,{style:q.container,children:[Ae(s,{style:q.userSection,children:[G(ne,{userId:t.id,name:o,size:"small",showActiveIndicator:!1}),G(s,{style:q.userInfo,children:G(u,{style:q.userName,numberOfLines:1,children:o})})]}),Ae(s,{style:q.statusPill,children:[G(s,{style:q.pulseDot}),G(u,{style:q.statusText,children:"Active"})]}),Ae(C,{style:q.stopButton,onPress:e,activeOpacity:.7,children:[G(Nn,{size:12,color:be.color.danger}),G(u,{style:q.stopButtonText,children:"Stop"})]})]})}var q=H.create({container:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:10,paddingHorizontal:16,backgroundColor:Se.success+"10",borderBottomWidth:1,borderBottomColor:Se.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:be.color.text},statusPill:{flexDirection:"row",alignItems:"center",gap:6,backgroundColor:Se.success+"20",paddingHorizontal:10,paddingVertical:5,borderRadius:12},pulseDot:{width:6,height:6,borderRadius:3,backgroundColor:Se.success},statusText:{fontSize:11,fontWeight:"600",color:Se.success,textTransform:"uppercase",letterSpacing:.5},stopButton:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:12,paddingVertical:6,backgroundColor:be.color.dangerSoft,borderRadius:6,borderWidth:1,borderColor:be.color.danger+"30"},stopButtonText:{fontSize:12,fontWeight:"600",color:be.color.danger}});import{useCallback as st,useSyncExternalStore as En}from"react";function Vn(){let t=En(l.subscribe,l.getSnapshot,l.getSnapshot),e=st(async r=>{await l.quickSwitch(r)},[]),o=st(async r=>{await l.removeFromHistory(r)},[]),n=st(async()=>{await l.clearHistory()},[]);return{history:t.history,currentUserId:t.currentUser?.id??null,quickSwitch:e,removeFromHistory:o,clearHistory:n}}export{Ge as DataNukeSettingsComponent,fe as ImpersonateBanner,vn as ImpersonateBannerMinimal,Xe as ImpersonateHistoryList,qt as ImpersonateIcon,ke as ImpersonateModal,Bn as ImpersonateOverlay,Ln as ImpersonateStatusBar,fn as ImpersonateToolView,_e as UserSearchView,Rn as createImpersonateSyncAdapter,Un as createImpersonateTool,vr as getImpersonatedUserId,L as impersonateListener,l as impersonateStore,An as impersonateSyncAdapter,br as isImpersonating,Ee as setImpersonateConfig,fr as startImpersonateListener,Sr as stopImpersonateListener,Oe as useImpersonate,Vn as useImpersonateHistory};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/impersonate",
3
- "version": "7.0.39",
3
+ "version": "7.0.41",
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",
@@ -10,27 +10,37 @@
10
10
  "exports": {
11
11
  ".": {
12
12
  "react-native": "./lib/module/index.js",
13
+ "browser": {
14
+ "types": "./lib/typescript/index.d.ts",
15
+ "default": "./lib/web/index.mjs"
16
+ },
13
17
  "import": {
14
- "default": "./lib/module/index.js",
15
- "types": "./lib/typescript/index.d.ts"
18
+ "types": "./lib/typescript/index.d.ts",
19
+ "default": "./lib/module/index.js"
16
20
  },
17
21
  "require": {
18
- "default": "./lib/commonjs/index.js",
19
- "types": "./lib/typescript/index.d.ts"
22
+ "types": "./lib/typescript/index.d.ts",
23
+ "default": "./lib/commonjs/index.js"
20
24
  }
21
25
  },
22
- "./package.json": "./package.json"
26
+ "./package.json": "./package.json",
27
+ "./web": {
28
+ "types": "./lib/typescript/index.d.ts",
29
+ "default": "./lib/web/index.mjs"
30
+ }
23
31
  },
24
32
  "files": [
25
33
  "lib"
26
34
  ],
27
35
  "sideEffects": false,
28
36
  "dependencies": {
29
- "@buoy-gg/shared-ui": "^7.0.39"
37
+ "@buoy-gg/shared-ui": "^7.0.41"
30
38
  },
31
39
  "peerDependencies": {
32
40
  "react": "*",
33
- "react-native": "*"
41
+ "react-native": "*",
42
+ "react-native-web": "^0.21.0",
43
+ "react-dom": ">=18"
34
44
  },
35
45
  "devDependencies": {
36
46
  "@types/react": "^19.1.0",
@@ -85,10 +95,22 @@
85
95
  "auth-testing",
86
96
  "qa"
87
97
  ],
98
+ "peerDependenciesMeta": {
99
+ "react-native": {
100
+ "optional": true
101
+ },
102
+ "react-native-web": {
103
+ "optional": true
104
+ },
105
+ "react-dom": {
106
+ "optional": true
107
+ }
108
+ },
88
109
  "scripts": {
89
- "build": "bob build",
110
+ "build": "bob build && pnpm run build:web",
90
111
  "typecheck": "tsc --noEmit",
91
112
  "clean": "rimraf lib",
92
- "test": "pnpm run typecheck"
113
+ "test": "pnpm run typecheck",
114
+ "build:web": "node ../../scripts/build-web.mjs impersonate"
93
115
  }
94
116
  }