@buoy-gg/impersonate 7.0.36 → 7.0.38
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 +31 -9
- package/lib/commonjs/impersonate/components/UserCard.js +4 -4
- package/lib/commonjs/impersonate/components/UserSearchView.js +3 -3
- package/lib/commonjs/impersonate/utils/impersonateStore.js +24 -1
- package/lib/commonjs/preset.js +3 -2
- package/lib/commonjs/sync/impersonateSyncAdapter.js +1 -0
- package/lib/module/impersonate/components/UserCard.js +4 -4
- package/lib/module/impersonate/components/UserSearchView.js +3 -3
- package/lib/module/impersonate/utils/impersonateStore.js +24 -1
- package/lib/module/preset.js +3 -2
- package/lib/module/sync/impersonateSyncAdapter.js +1 -0
- package/lib/typescript/impersonate/utils/impersonateStore.d.ts +2 -0
- package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +1 -1
- package/lib/typescript/preset.d.ts +2 -1
- package/lib/typescript/preset.d.ts.map +1 -1
- package/lib/typescript/sync/impersonateSyncAdapter.d.ts +1 -0
- package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@buoy-gg/impersonate) [](https://www.npmjs.com/package/@buoy-gg/impersonate)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Connect your app’s user-switching flow to Buoy so testers can switch test accounts, roles, or flags without rebuilding.
|
|
6
6
|
|
|
7
|
-
Part of [Buoy](https://github.com/Buoy-gg/buoy)
|
|
7
|
+
Part of [Buoy](https://github.com/Buoy-gg/buoy). Install the package, complete account setup, and follow the integration steps below.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -12,6 +12,24 @@ Part of [Buoy](https://github.com/Buoy-gg/buoy) — devtools that live inside yo
|
|
|
12
12
|
npm install @buoy-gg/core @buoy-gg/impersonate
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Before you start
|
|
16
|
+
|
|
17
|
+
Use a development build with `@buoy-gg/core` and a Free or Pro Buoy account key. From your app’s directory, sign in:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx --package=@buoy-gg/core buoy login
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For Expo, initialize Buoy before rendering the menu:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { Buoy } from "@buoy-gg/core";
|
|
27
|
+
|
|
28
|
+
Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The login command writes the Expo key to `.env.local`. For React Native CLI, pass the key from your app’s environment configuration; React Native does not load `.env.local` automatically. Mount `FloatingDevTools` inside the same providers as your screens and restart the development server after installation. The [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) shows the complete root component setup.
|
|
32
|
+
|
|
15
33
|
## Quick start
|
|
16
34
|
|
|
17
35
|
Unlike most Buoy tools, this one needs a little config — it has to know how to search *your* users:
|
|
@@ -42,13 +60,17 @@ export default function App() {
|
|
|
42
60
|
}
|
|
43
61
|
```
|
|
44
62
|
|
|
45
|
-
While impersonating,
|
|
63
|
+
While impersonating, requests passing through the patched global `fetch` and `XMLHttpRequest` carries `x-impersonate-user-id: <id>` (header name configurable via `defaults.headerKey`). Your backend checks the header — after verifying the caller is an admin — and returns data for that user instead.
|
|
64
|
+
|
|
65
|
+
## Check the integration
|
|
66
|
+
|
|
67
|
+
Switch between two test accounts and confirm both the visible identity and subsequent authenticated requests. Your backend must authorize the switch. Redux clearing requires a reducer that handles `@@RESET` or your own reset callback; Buoy cannot infer your app’s reset behavior.
|
|
46
68
|
|
|
47
69
|
## What you get
|
|
48
70
|
|
|
49
|
-
- **Header injection
|
|
50
|
-
- **
|
|
51
|
-
- **Floating banner** —
|
|
71
|
+
- **Header injection** — adds the configured header through patched global fetch and XHR paths while impersonation is active
|
|
72
|
+
- **Data clearing** — supports query-cache clearing and Redux reset integration. Your reducer must handle `@@RESET`, or provide a reset callback. Storage clearing uses optional callbacks
|
|
73
|
+
- **Floating banner** — identifies the active impersonation when the banner is enabled
|
|
52
74
|
- **Pause vs stop** — the banner's power button pauses header injection for instant A/B against your real account; X stops the session and triggers data clearing
|
|
53
75
|
- **History** — quick-switch between your last 10 impersonated users, persisted across app restarts
|
|
54
76
|
- **Developer defaults** — ship team-wide defaults for header name, banner, and clearing behavior; the Settings tab exports your current config as paste-ready code
|
|
@@ -56,11 +78,11 @@ While impersonating, every outgoing `fetch` and `XMLHttpRequest` carries `x-impe
|
|
|
56
78
|
|
|
57
79
|
## Desktop & AI
|
|
58
80
|
|
|
59
|
-
|
|
81
|
+
To connect a React Native app to [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) or MCP, install `@buoy-gg/external-sync` and follow the [Desktop connection guide](https://buoy.gg/buoy/latest/docs/desktop). Sign in to Desktop separately. [MCP setup](https://buoy.gg/buoy/latest/docs/mcp) also requires a process account and Pro access. Available remote actions depend on the tool and app integration.
|
|
60
82
|
|
|
61
|
-
##
|
|
83
|
+
## Account and plan requirements
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
Use a Free or Pro Buoy account. History limits and paid features vary by tool; see [pricing](https://buoy.gg/pricing). Production access requires Pro where supported. Development-only hooks and actions remain unavailable in release builds.
|
|
64
86
|
|
|
65
87
|
---
|
|
66
88
|
|
|
@@ -52,13 +52,13 @@ function UserCard({
|
|
|
52
52
|
style: [styles.name, isActive && styles.activeName],
|
|
53
53
|
numberOfLines: 1,
|
|
54
54
|
children: displayName
|
|
55
|
-
}), role
|
|
55
|
+
}), role ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
56
56
|
style: styles.roleBadge,
|
|
57
57
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
58
58
|
style: styles.roleBadgeText,
|
|
59
59
|
children: role.toUpperCase()
|
|
60
60
|
})
|
|
61
|
-
})]
|
|
61
|
+
}) : null]
|
|
62
62
|
}), showEmail && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
63
63
|
style: styles.email,
|
|
64
64
|
numberOfLines: 1,
|
|
@@ -93,10 +93,10 @@ function UserCard({
|
|
|
93
93
|
color: _sharedUi.night.color.textTertiary
|
|
94
94
|
})
|
|
95
95
|
})]
|
|
96
|
-
}), lastUsedTime
|
|
96
|
+
}), lastUsedTime ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
97
97
|
style: styles.lastUsed,
|
|
98
98
|
children: lastUsedTime
|
|
99
|
-
})]
|
|
99
|
+
}) : null]
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
const styles = _reactNative.StyleSheet.create({
|
|
@@ -68,7 +68,7 @@ function UserSearchView({
|
|
|
68
68
|
style: styles.loadingText,
|
|
69
69
|
children: "Searching users..."
|
|
70
70
|
})]
|
|
71
|
-
}), searchError
|
|
71
|
+
}), searchError ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
72
72
|
style: styles.section,
|
|
73
73
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
74
74
|
style: styles.errorCard,
|
|
@@ -80,7 +80,7 @@ function UserSearchView({
|
|
|
80
80
|
children: searchError
|
|
81
81
|
})]
|
|
82
82
|
})
|
|
83
|
-
}), searchResults.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
83
|
+
}) : null, searchResults.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
84
84
|
style: styles.resultsSection,
|
|
85
85
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
|
|
86
86
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
@@ -98,7 +98,7 @@ function UserSearchView({
|
|
|
98
98
|
contentContainerStyle: styles.listContent,
|
|
99
99
|
showsVerticalScrollIndicator: false
|
|
100
100
|
})]
|
|
101
|
-
}), searchQuery && !isSearching && searchResults.length === 0 && !searchError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
101
|
+
}), !!searchQuery && !isSearching && searchResults.length === 0 && !searchError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
102
102
|
style: styles.emptyStateContainer,
|
|
103
103
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
104
104
|
style: styles.emptyStateIcon,
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.impersonateStore = void 0;
|
|
7
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
7
8
|
var _impersonateListener = require("./impersonateListener");
|
|
8
9
|
/**
|
|
9
10
|
* Impersonate Store - State Management with Persistence
|
|
@@ -110,6 +111,13 @@ class ImpersonateStore {
|
|
|
110
111
|
constructor() {
|
|
111
112
|
// Try to load persisted state synchronously
|
|
112
113
|
this.loadFromStorage();
|
|
114
|
+
Promise.resolve().then(() => {
|
|
115
|
+
const reconcile = () => {
|
|
116
|
+
if (!(0, _sharedUi.hasAccountAccess)()) this.disposeAccountSession();
|
|
117
|
+
};
|
|
118
|
+
(0, _sharedUi.subscribeAccountAccess)(reconcile);
|
|
119
|
+
reconcile();
|
|
120
|
+
});
|
|
113
121
|
|
|
114
122
|
// Check if localStorage is available (web) - if so, storage is ready
|
|
115
123
|
if (typeof localStorage !== "undefined") {
|
|
@@ -350,6 +358,7 @@ class ImpersonateStore {
|
|
|
350
358
|
* the visual symptom of "I clicked a user and nothing changed."
|
|
351
359
|
*/
|
|
352
360
|
async startImpersonation(user) {
|
|
361
|
+
(0, _sharedUi.assertAccountAccess)();
|
|
353
362
|
if (this.remoteHandler) {
|
|
354
363
|
this.remoteHandler("startImpersonation", {
|
|
355
364
|
user
|
|
@@ -436,6 +445,7 @@ class ImpersonateStore {
|
|
|
436
445
|
* Resume impersonation (start injecting headers again)
|
|
437
446
|
*/
|
|
438
447
|
async resumeImpersonation() {
|
|
448
|
+
(0, _sharedUi.assertAccountAccess)();
|
|
439
449
|
if (this.remoteHandler) {
|
|
440
450
|
this.remoteHandler("resumeImpersonation");
|
|
441
451
|
return;
|
|
@@ -578,9 +588,22 @@ class ImpersonateStore {
|
|
|
578
588
|
/**
|
|
579
589
|
* Sync current state with the impersonateListener
|
|
580
590
|
*/
|
|
591
|
+
/** Remove only the active header override. Sign-out must not nuke host caches. */
|
|
592
|
+
disposeAccountSession() {
|
|
593
|
+
if (this.remoteHandler || !this.state.isActive) return;
|
|
594
|
+
this.state = {
|
|
595
|
+
...this.state,
|
|
596
|
+
isActive: false,
|
|
597
|
+
isPaused: false,
|
|
598
|
+
currentUser: null
|
|
599
|
+
};
|
|
600
|
+
this.syncWithListener();
|
|
601
|
+
this.notify();
|
|
602
|
+
void this.persist();
|
|
603
|
+
}
|
|
581
604
|
syncWithListener() {
|
|
582
605
|
// When paused, don't inject headers (pass null userId)
|
|
583
|
-
const shouldInject = this.state.isActive && !this.state.isPaused;
|
|
606
|
+
const shouldInject = (0, _sharedUi.hasAccountAccess)() && this.state.isActive && !this.state.isPaused;
|
|
584
607
|
(0, _impersonateListener.setImpersonateConfig)({
|
|
585
608
|
headerKey: this.state.headerKey,
|
|
586
609
|
userId: shouldInject ? this.state.currentUser?.id ?? null : null,
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -190,9 +190,10 @@ function createImpersonateTool(config) {
|
|
|
190
190
|
description,
|
|
191
191
|
slot: "both",
|
|
192
192
|
icon: ({
|
|
193
|
-
size
|
|
193
|
+
size,
|
|
194
|
+
slot
|
|
194
195
|
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ImpersonateIcon, {
|
|
195
|
-
size: size,
|
|
196
|
+
size: slot === "dial" ? size * 1.5 : size,
|
|
196
197
|
color: _sharedUi.IMPERSONATE_ICON_COLOR
|
|
197
198
|
}),
|
|
198
199
|
component: props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImpersonateModal.ImpersonateModal, {
|
|
@@ -148,6 +148,7 @@ function createImpersonateSyncAdapter({
|
|
|
148
148
|
* reports a descriptive error to the dashboard.
|
|
149
149
|
*/
|
|
150
150
|
const impersonateSyncAdapter = exports.impersonateSyncAdapter = {
|
|
151
|
+
dispose: () => _impersonateStore.impersonateStore.disposeAccountSession(),
|
|
151
152
|
version: 1,
|
|
152
153
|
getSnapshot: () => toWireState(_impersonateStore.impersonateStore.getState()),
|
|
153
154
|
subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
|
|
@@ -47,13 +47,13 @@ export function UserCard({
|
|
|
47
47
|
style: [styles.name, isActive && styles.activeName],
|
|
48
48
|
numberOfLines: 1,
|
|
49
49
|
children: displayName
|
|
50
|
-
}), role
|
|
50
|
+
}), role ? /*#__PURE__*/_jsx(View, {
|
|
51
51
|
style: styles.roleBadge,
|
|
52
52
|
children: /*#__PURE__*/_jsx(Text, {
|
|
53
53
|
style: styles.roleBadgeText,
|
|
54
54
|
children: role.toUpperCase()
|
|
55
55
|
})
|
|
56
|
-
})]
|
|
56
|
+
}) : null]
|
|
57
57
|
}), showEmail && /*#__PURE__*/_jsx(Text, {
|
|
58
58
|
style: styles.email,
|
|
59
59
|
numberOfLines: 1,
|
|
@@ -88,10 +88,10 @@ export function UserCard({
|
|
|
88
88
|
color: night.color.textTertiary
|
|
89
89
|
})
|
|
90
90
|
})]
|
|
91
|
-
}), lastUsedTime
|
|
91
|
+
}), lastUsedTime ? /*#__PURE__*/_jsx(Text, {
|
|
92
92
|
style: styles.lastUsed,
|
|
93
93
|
children: lastUsedTime
|
|
94
|
-
})]
|
|
94
|
+
}) : null]
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
const styles = StyleSheet.create({
|
|
@@ -63,7 +63,7 @@ export function UserSearchView({
|
|
|
63
63
|
style: styles.loadingText,
|
|
64
64
|
children: "Searching users..."
|
|
65
65
|
})]
|
|
66
|
-
}), searchError
|
|
66
|
+
}), searchError ? /*#__PURE__*/_jsx(View, {
|
|
67
67
|
style: styles.section,
|
|
68
68
|
children: /*#__PURE__*/_jsxs(View, {
|
|
69
69
|
style: styles.errorCard,
|
|
@@ -75,7 +75,7 @@ export function UserSearchView({
|
|
|
75
75
|
children: searchError
|
|
76
76
|
})]
|
|
77
77
|
})
|
|
78
|
-
}), searchResults.length > 0 && /*#__PURE__*/_jsxs(View, {
|
|
78
|
+
}) : null, searchResults.length > 0 && /*#__PURE__*/_jsxs(View, {
|
|
79
79
|
style: styles.resultsSection,
|
|
80
80
|
children: [/*#__PURE__*/_jsxs(SectionHeader, {
|
|
81
81
|
children: [/*#__PURE__*/_jsx(SectionHeader.Title, {
|
|
@@ -93,7 +93,7 @@ export function UserSearchView({
|
|
|
93
93
|
contentContainerStyle: styles.listContent,
|
|
94
94
|
showsVerticalScrollIndicator: false
|
|
95
95
|
})]
|
|
96
|
-
}), searchQuery && !isSearching && searchResults.length === 0 && !searchError && /*#__PURE__*/_jsxs(View, {
|
|
96
|
+
}), !!searchQuery && !isSearching && searchResults.length === 0 && !searchError && /*#__PURE__*/_jsxs(View, {
|
|
97
97
|
style: styles.emptyStateContainer,
|
|
98
98
|
children: [/*#__PURE__*/_jsx(View, {
|
|
99
99
|
style: styles.emptyStateIcon,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { assertAccountAccess, hasAccountAccess, subscribeAccountAccess } from "@buoy-gg/shared-ui";
|
|
3
4
|
/**
|
|
4
5
|
* Impersonate Store - State Management with Persistence
|
|
5
6
|
*
|
|
@@ -107,6 +108,13 @@ class ImpersonateStore {
|
|
|
107
108
|
constructor() {
|
|
108
109
|
// Try to load persisted state synchronously
|
|
109
110
|
this.loadFromStorage();
|
|
111
|
+
Promise.resolve().then(() => {
|
|
112
|
+
const reconcile = () => {
|
|
113
|
+
if (!hasAccountAccess()) this.disposeAccountSession();
|
|
114
|
+
};
|
|
115
|
+
subscribeAccountAccess(reconcile);
|
|
116
|
+
reconcile();
|
|
117
|
+
});
|
|
110
118
|
|
|
111
119
|
// Check if localStorage is available (web) - if so, storage is ready
|
|
112
120
|
if (typeof localStorage !== "undefined") {
|
|
@@ -347,6 +355,7 @@ class ImpersonateStore {
|
|
|
347
355
|
* the visual symptom of "I clicked a user and nothing changed."
|
|
348
356
|
*/
|
|
349
357
|
async startImpersonation(user) {
|
|
358
|
+
assertAccountAccess();
|
|
350
359
|
if (this.remoteHandler) {
|
|
351
360
|
this.remoteHandler("startImpersonation", {
|
|
352
361
|
user
|
|
@@ -433,6 +442,7 @@ class ImpersonateStore {
|
|
|
433
442
|
* Resume impersonation (start injecting headers again)
|
|
434
443
|
*/
|
|
435
444
|
async resumeImpersonation() {
|
|
445
|
+
assertAccountAccess();
|
|
436
446
|
if (this.remoteHandler) {
|
|
437
447
|
this.remoteHandler("resumeImpersonation");
|
|
438
448
|
return;
|
|
@@ -575,9 +585,22 @@ class ImpersonateStore {
|
|
|
575
585
|
/**
|
|
576
586
|
* Sync current state with the impersonateListener
|
|
577
587
|
*/
|
|
588
|
+
/** Remove only the active header override. Sign-out must not nuke host caches. */
|
|
589
|
+
disposeAccountSession() {
|
|
590
|
+
if (this.remoteHandler || !this.state.isActive) return;
|
|
591
|
+
this.state = {
|
|
592
|
+
...this.state,
|
|
593
|
+
isActive: false,
|
|
594
|
+
isPaused: false,
|
|
595
|
+
currentUser: null
|
|
596
|
+
};
|
|
597
|
+
this.syncWithListener();
|
|
598
|
+
this.notify();
|
|
599
|
+
void this.persist();
|
|
600
|
+
}
|
|
578
601
|
syncWithListener() {
|
|
579
602
|
// When paused, don't inject headers (pass null userId)
|
|
580
|
-
const shouldInject = this.state.isActive && !this.state.isPaused;
|
|
603
|
+
const shouldInject = hasAccountAccess() && this.state.isActive && !this.state.isPaused;
|
|
581
604
|
setImpersonateConfig({
|
|
582
605
|
headerKey: this.state.headerKey,
|
|
583
606
|
userId: shouldInject ? this.state.currentUser?.id ?? null : null,
|
package/lib/module/preset.js
CHANGED
|
@@ -174,9 +174,10 @@ export function createImpersonateTool(config) {
|
|
|
174
174
|
description,
|
|
175
175
|
slot: "both",
|
|
176
176
|
icon: ({
|
|
177
|
-
size
|
|
177
|
+
size,
|
|
178
|
+
slot
|
|
178
179
|
}) => /*#__PURE__*/_jsx(ImpersonateIcon, {
|
|
179
|
-
size: size,
|
|
180
|
+
size: slot === "dial" ? size * 1.5 : size,
|
|
180
181
|
color: IMPERSONATE_ICON_COLOR
|
|
181
182
|
}),
|
|
182
183
|
component: props => /*#__PURE__*/_jsx(ImpersonateModal, {
|
|
@@ -140,6 +140,7 @@ export function createImpersonateSyncAdapter({
|
|
|
140
140
|
* reports a descriptive error to the dashboard.
|
|
141
141
|
*/
|
|
142
142
|
export const impersonateSyncAdapter = {
|
|
143
|
+
dispose: () => impersonateStore.disposeAccountSession(),
|
|
143
144
|
version: 1,
|
|
144
145
|
getSnapshot: () => toWireState(impersonateStore.getState()),
|
|
145
146
|
subscribe: onChange => impersonateStore.subscribe(onChange),
|
|
@@ -147,6 +147,8 @@ declare class ImpersonateStore {
|
|
|
147
147
|
/**
|
|
148
148
|
* Sync current state with the impersonateListener
|
|
149
149
|
*/
|
|
150
|
+
/** Remove only the active header override. Sign-out must not nuke host caches. */
|
|
151
|
+
disposeAccountSession(): void;
|
|
150
152
|
private syncWithListener;
|
|
151
153
|
/**
|
|
152
154
|
* Persist state to storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,8 +66,9 @@ export declare function createImpersonateTool(config: ImpersonateToolConfig): {
|
|
|
66
66
|
name: string;
|
|
67
67
|
description: string;
|
|
68
68
|
slot: "both";
|
|
69
|
-
icon: ({ size }: {
|
|
69
|
+
icon: ({ size, slot }: {
|
|
70
70
|
size: number;
|
|
71
|
+
slot?: string;
|
|
71
72
|
}) => React.JSX.Element;
|
|
72
73
|
component: (props: {
|
|
73
74
|
visible: boolean;
|
|
@@ -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;;;;;
|
|
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"}
|
|
@@ -53,6 +53,7 @@ export declare function createImpersonateSyncAdapter({ onSearchUsers, }: CreateI
|
|
|
53
53
|
* reports a descriptive error to the dashboard.
|
|
54
54
|
*/
|
|
55
55
|
export declare const impersonateSyncAdapter: {
|
|
56
|
+
dispose: () => void;
|
|
56
57
|
version: number;
|
|
57
58
|
getSnapshot: () => ImpersonationState;
|
|
58
59
|
subscribe: (onChange: () => void) => () => void;
|
|
@@ -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
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/impersonate",
|
|
3
|
-
"version": "7.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "7.0.38",
|
|
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",
|
|
7
7
|
"types": "lib/typescript/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
29
|
+
"@buoy-gg/shared-ui": "^7.0.38"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": "*",
|