@buoy-gg/impersonate 7.0.16 → 7.0.18

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.
@@ -178,6 +178,7 @@ function ImpersonateModal({
178
178
  color: _sharedUi.macOSColors.text.secondary
179
179
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
180
180
  ref: searchInputRef,
181
+ testID: "buoy-impersonate-search-input",
181
182
  style: styles.headerSearchInput,
182
183
  placeholder: "Search by email, name, or ID...",
183
184
  placeholderTextColor: _sharedUi.macOSColors.text.muted,
@@ -213,6 +214,7 @@ function ImpersonateModal({
213
214
  })
214
215
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Actions, {
215
216
  children: activeTab === "search" && !isSearchActive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
217
+ testID: "buoy-impersonate-search-toggle",
216
218
  onPress: () => setIsSearchActive(true),
217
219
  style: styles.headerActionButton,
218
220
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Search, {
@@ -31,6 +31,7 @@ function UserCard({
31
31
  const showEmail = user.email && user.displayName;
32
32
  const role = typeof user.metadata?.role === "string" ? user.metadata.role : null;
33
33
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
34
+ testID: `buoy-impersonate-user-${user.id}`,
34
35
  style: [styles.container, isActive && styles.activeContainer, variant === "compact" && styles.compactContainer],
35
36
  onPress: onPress,
36
37
  disabled: isActive,
@@ -3,9 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.SNAPSHOT_URI_INLINE_LIMIT = exports.SNAPSHOT_METADATA_INLINE_LIMIT = void 0;
6
7
  exports.createImpersonateSyncAdapter = createImpersonateSyncAdapter;
7
8
  exports.impersonateSyncAdapter = void 0;
8
9
  exports.registerImpersonateSearchUsers = registerImpersonateSearchUsers;
10
+ exports.toWireUri = toWireUri;
9
11
  var _impersonateStore = require("../impersonate/utils/impersonateStore");
10
12
  // Registered by createImpersonateTool, so the zero-config adapter (see
11
13
  // FloatingDevTools' auto external sync) can proxy the dashboard's user
@@ -16,9 +18,98 @@ let registeredSearchUsers = null;
16
18
  function registerImpersonateSearchUsers(handler) {
17
19
  registeredSearchUsers = handler;
18
20
  }
21
+
22
+ /**
23
+ * `data:` avatar URLs (and any URL over this) are NOT copied onto the
24
+ * snapshot. UserCard renders initials, not the image, but apps still put
25
+ * base64 photos on `avatarUrl` / dump the API user into `metadata`. Ten
26
+ * history entries of those blow the 2MB emit budget and drop the panel.
27
+ */
28
+ const SNAPSHOT_URI_INLINE_LIMIT = exports.SNAPSHOT_URI_INLINE_LIMIT = 2 * 1024;
29
+ const SNAPSHOT_METADATA_INLINE_LIMIT = exports.SNAPSHOT_METADATA_INLINE_LIMIT = 16 * 1024;
30
+ const METADATA_ON_DEVICE = Object.freeze({
31
+ __buoyOmitted: "user-metadata",
32
+ note: "User metadata stays on the device."
33
+ });
34
+ function jsonLongerThan(value, limit) {
35
+ let bytes = 0;
36
+ const stack = [value];
37
+ const seen = new Set();
38
+ while (stack.length > 0) {
39
+ if (bytes > limit) return true;
40
+ const v = stack.pop();
41
+ if (v === null || v === undefined) bytes += 4;else if (typeof v === "string") bytes += v.length + 2;else if (typeof v === "number") bytes += 8;else if (typeof v === "boolean") bytes += 5;else if (typeof v === "object") {
42
+ if (seen.has(v)) continue;
43
+ seen.add(v);
44
+ if (Array.isArray(v)) {
45
+ bytes += 2 + v.length;
46
+ for (let i = 0; i < v.length; i++) stack.push(v[i]);
47
+ } else {
48
+ bytes += 2;
49
+ for (const k in v) {
50
+ bytes += k.length + 4;
51
+ stack.push(v[k]);
52
+ }
53
+ }
54
+ } else bytes += 4;
55
+ }
56
+ return bytes > limit;
57
+ }
58
+ function toWireUri(uri) {
59
+ if (!uri) return uri;
60
+ if (uri.startsWith("data:")) {
61
+ const comma = uri.indexOf(",");
62
+ const header = comma >= 0 ? uri.slice(0, Math.min(comma + 1, 64)) : "data:";
63
+ return `${header}[${uri.length} chars]`;
64
+ }
65
+ if (uri.length <= SNAPSHOT_URI_INLINE_LIMIT) return uri;
66
+ return `${uri.slice(0, SNAPSHOT_URI_INLINE_LIMIT)}… [${uri.length - SNAPSHOT_URI_INLINE_LIMIT} more]`;
67
+ }
68
+ function toWireMetadata(metadata) {
69
+ if (!metadata) return metadata;
70
+ const role = typeof metadata.role === "string" ? metadata.role : undefined;
71
+ try {
72
+ JSON.stringify(metadata);
73
+ } catch {
74
+ return role ? {
75
+ role,
76
+ ...METADATA_ON_DEVICE
77
+ } : {
78
+ ...METADATA_ON_DEVICE
79
+ };
80
+ }
81
+ if (!jsonLongerThan(metadata, SNAPSHOT_METADATA_INLINE_LIMIT)) return metadata;
82
+ return role ? {
83
+ role,
84
+ ...METADATA_ON_DEVICE
85
+ } : {
86
+ ...METADATA_ON_DEVICE
87
+ };
88
+ }
89
+ function toWireUser(user) {
90
+ return {
91
+ ...user,
92
+ avatarUrl: toWireUri(user.avatarUrl),
93
+ metadata: toWireMetadata(user.metadata)
94
+ };
95
+ }
96
+ function toWireState(state) {
97
+ return {
98
+ ...state,
99
+ currentUser: state.currentUser ? toWireUser(state.currentUser) : null,
100
+ history: state.history.map(entry => ({
101
+ ...entry,
102
+ user: toWireUser(entry.user)
103
+ }))
104
+ };
105
+ }
19
106
  function buildActions(onSearchUsers) {
20
107
  return {
21
- searchUsers: params => onSearchUsers(params.query),
108
+ searchUsers: async params => {
109
+ const query = String(params?.query ?? "");
110
+ const users = await onSearchUsers(query);
111
+ return Array.isArray(users) ? users.map(toWireUser) : users;
112
+ },
22
113
  startImpersonation: params => _impersonateStore.impersonateStore.startImpersonation(params.user),
23
114
  stopImpersonation: () => _impersonateStore.impersonateStore.stopImpersonation(),
24
115
  pauseImpersonation: () => _impersonateStore.impersonateStore.pauseImpersonation(),
@@ -43,7 +134,7 @@ function createImpersonateSyncAdapter({
43
134
  }) {
44
135
  return {
45
136
  version: 1,
46
- getSnapshot: () => _impersonateStore.impersonateStore.getState(),
137
+ getSnapshot: () => toWireState(_impersonateStore.impersonateStore.getState()),
47
138
  subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
48
139
  actions: buildActions(onSearchUsers)
49
140
  };
@@ -57,7 +148,7 @@ function createImpersonateSyncAdapter({
57
148
  */
58
149
  const impersonateSyncAdapter = exports.impersonateSyncAdapter = {
59
150
  version: 1,
60
- getSnapshot: () => _impersonateStore.impersonateStore.getState(),
151
+ getSnapshot: () => toWireState(_impersonateStore.impersonateStore.getState()),
61
152
  subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
62
153
  actions: buildActions(query => {
63
154
  if (!registeredSearchUsers) {
@@ -173,6 +173,7 @@ export function ImpersonateModal({
173
173
  color: macOSColors.text.secondary
174
174
  }), /*#__PURE__*/_jsx(TextInput, {
175
175
  ref: searchInputRef,
176
+ testID: "buoy-impersonate-search-input",
176
177
  style: styles.headerSearchInput,
177
178
  placeholder: "Search by email, name, or ID...",
178
179
  placeholderTextColor: macOSColors.text.muted,
@@ -208,6 +209,7 @@ export function ImpersonateModal({
208
209
  })
209
210
  }), /*#__PURE__*/_jsx(ModalHeader.Actions, {
210
211
  children: activeTab === "search" && !isSearchActive && /*#__PURE__*/_jsx(TouchableOpacity, {
212
+ testID: "buoy-impersonate-search-toggle",
211
213
  onPress: () => setIsSearchActive(true),
212
214
  style: styles.headerActionButton,
213
215
  children: /*#__PURE__*/_jsx(Search, {
@@ -26,6 +26,7 @@ export function UserCard({
26
26
  const showEmail = user.email && user.displayName;
27
27
  const role = typeof user.metadata?.role === "string" ? user.metadata.role : null;
28
28
  return /*#__PURE__*/_jsxs(TouchableOpacity, {
29
+ testID: `buoy-impersonate-user-${user.id}`,
29
30
  style: [styles.container, isActive && styles.activeContainer, variant === "compact" && styles.compactContainer],
30
31
  onPress: onPress,
31
32
  disabled: isActive,
@@ -10,9 +10,98 @@ let registeredSearchUsers = null;
10
10
  export function registerImpersonateSearchUsers(handler) {
11
11
  registeredSearchUsers = handler;
12
12
  }
13
+
14
+ /**
15
+ * `data:` avatar URLs (and any URL over this) are NOT copied onto the
16
+ * snapshot. UserCard renders initials, not the image, but apps still put
17
+ * base64 photos on `avatarUrl` / dump the API user into `metadata`. Ten
18
+ * history entries of those blow the 2MB emit budget and drop the panel.
19
+ */
20
+ export const SNAPSHOT_URI_INLINE_LIMIT = 2 * 1024;
21
+ export const SNAPSHOT_METADATA_INLINE_LIMIT = 16 * 1024;
22
+ const METADATA_ON_DEVICE = Object.freeze({
23
+ __buoyOmitted: "user-metadata",
24
+ note: "User metadata stays on the device."
25
+ });
26
+ function jsonLongerThan(value, limit) {
27
+ let bytes = 0;
28
+ const stack = [value];
29
+ const seen = new Set();
30
+ while (stack.length > 0) {
31
+ if (bytes > limit) return true;
32
+ const v = stack.pop();
33
+ if (v === null || v === undefined) bytes += 4;else if (typeof v === "string") bytes += v.length + 2;else if (typeof v === "number") bytes += 8;else if (typeof v === "boolean") bytes += 5;else if (typeof v === "object") {
34
+ if (seen.has(v)) continue;
35
+ seen.add(v);
36
+ if (Array.isArray(v)) {
37
+ bytes += 2 + v.length;
38
+ for (let i = 0; i < v.length; i++) stack.push(v[i]);
39
+ } else {
40
+ bytes += 2;
41
+ for (const k in v) {
42
+ bytes += k.length + 4;
43
+ stack.push(v[k]);
44
+ }
45
+ }
46
+ } else bytes += 4;
47
+ }
48
+ return bytes > limit;
49
+ }
50
+ export function toWireUri(uri) {
51
+ if (!uri) return uri;
52
+ if (uri.startsWith("data:")) {
53
+ const comma = uri.indexOf(",");
54
+ const header = comma >= 0 ? uri.slice(0, Math.min(comma + 1, 64)) : "data:";
55
+ return `${header}[${uri.length} chars]`;
56
+ }
57
+ if (uri.length <= SNAPSHOT_URI_INLINE_LIMIT) return uri;
58
+ return `${uri.slice(0, SNAPSHOT_URI_INLINE_LIMIT)}… [${uri.length - SNAPSHOT_URI_INLINE_LIMIT} more]`;
59
+ }
60
+ function toWireMetadata(metadata) {
61
+ if (!metadata) return metadata;
62
+ const role = typeof metadata.role === "string" ? metadata.role : undefined;
63
+ try {
64
+ JSON.stringify(metadata);
65
+ } catch {
66
+ return role ? {
67
+ role,
68
+ ...METADATA_ON_DEVICE
69
+ } : {
70
+ ...METADATA_ON_DEVICE
71
+ };
72
+ }
73
+ if (!jsonLongerThan(metadata, SNAPSHOT_METADATA_INLINE_LIMIT)) return metadata;
74
+ return role ? {
75
+ role,
76
+ ...METADATA_ON_DEVICE
77
+ } : {
78
+ ...METADATA_ON_DEVICE
79
+ };
80
+ }
81
+ function toWireUser(user) {
82
+ return {
83
+ ...user,
84
+ avatarUrl: toWireUri(user.avatarUrl),
85
+ metadata: toWireMetadata(user.metadata)
86
+ };
87
+ }
88
+ function toWireState(state) {
89
+ return {
90
+ ...state,
91
+ currentUser: state.currentUser ? toWireUser(state.currentUser) : null,
92
+ history: state.history.map(entry => ({
93
+ ...entry,
94
+ user: toWireUser(entry.user)
95
+ }))
96
+ };
97
+ }
13
98
  function buildActions(onSearchUsers) {
14
99
  return {
15
- searchUsers: params => onSearchUsers(params.query),
100
+ searchUsers: async params => {
101
+ const query = String(params?.query ?? "");
102
+ const users = await onSearchUsers(query);
103
+ return Array.isArray(users) ? users.map(toWireUser) : users;
104
+ },
16
105
  startImpersonation: params => impersonateStore.startImpersonation(params.user),
17
106
  stopImpersonation: () => impersonateStore.stopImpersonation(),
18
107
  pauseImpersonation: () => impersonateStore.pauseImpersonation(),
@@ -37,7 +126,7 @@ export function createImpersonateSyncAdapter({
37
126
  }) {
38
127
  return {
39
128
  version: 1,
40
- getSnapshot: () => impersonateStore.getState(),
129
+ getSnapshot: () => toWireState(impersonateStore.getState()),
41
130
  subscribe: onChange => impersonateStore.subscribe(onChange),
42
131
  actions: buildActions(onSearchUsers)
43
132
  };
@@ -51,7 +140,7 @@ export function createImpersonateSyncAdapter({
51
140
  */
52
141
  export const impersonateSyncAdapter = {
53
142
  version: 1,
54
- getSnapshot: () => impersonateStore.getState(),
143
+ getSnapshot: () => toWireState(impersonateStore.getState()),
55
144
  subscribe: onChange => impersonateStore.subscribe(onChange),
56
145
  actions: buildActions(query => {
57
146
  if (!registeredSearchUsers) {
@@ -1 +1 @@
1
- {"version":3,"file":"ImpersonateModal.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/components/ImpersonateModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAiBxE,OAAO,KAAK,EAAE,qBAAqB,EAA0B,MAAM,UAAU,CAAC;AAgC9E,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,eAAsB,EACtB,MAAc,GACf,EAAE,qBAAqB,4BAyPvB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,qBAGrE"}
1
+ {"version":3,"file":"ImpersonateModal.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/components/ImpersonateModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAiBxE,OAAO,KAAK,EAAE,qBAAqB,EAA0B,MAAM,UAAU,CAAC;AAgC9E,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,eAAsB,EACtB,MAAc,GACf,EAAE,qBAAqB,4BA2PvB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,qBAGrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserCard.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/components/UserCard.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,gBAAgB;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,QAAgB,EAChB,OAAO,EACP,MAAM,EACN,QAAQ,EACR,gBAAwB,EACxB,YAAY,EACZ,OAAmB,GACpB,EAAE,aAAa,qBA2Ff"}
1
+ {"version":3,"file":"UserCard.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/components/UserCard.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,gBAAgB;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,QAAgB,EAChB,OAAO,EACP,MAAM,EACN,QAAQ,EACR,gBAAwB,EACxB,YAAY,EACZ,OAAmB,GACpB,EAAE,aAAa,qBA4Ff"}
@@ -2,6 +2,15 @@ import type { User, ImpersonationState } from "../impersonate/types";
2
2
  type SearchUsersHandler = (query: string) => Promise<User[]>;
3
3
  /** @internal Called by createImpersonateTool with the app's onSearchUsers. */
4
4
  export declare function registerImpersonateSearchUsers(handler: SearchUsersHandler | null): void;
5
+ /**
6
+ * `data:` avatar URLs (and any URL over this) are NOT copied onto the
7
+ * snapshot. UserCard renders initials, not the image, but apps still put
8
+ * base64 photos on `avatarUrl` / dump the API user into `metadata`. Ten
9
+ * history entries of those blow the 2MB emit budget and drop the panel.
10
+ */
11
+ export declare const SNAPSHOT_URI_INLINE_LIMIT: number;
12
+ export declare const SNAPSHOT_METADATA_INLINE_LIMIT: number;
13
+ export declare function toWireUri(uri: string | undefined): string | undefined;
5
14
  interface CreateImpersonateSyncAdapterOptions {
6
15
  /**
7
16
  * Same user-search callback you pass to the ImpersonateModal — the
@@ -1 +1 @@
1
- {"version":3,"file":"impersonateSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/impersonateSyncAdapter.ts"],"names":[],"mappings":"AACA,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;AAyBD,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;;8BA7CV,OAAO;qCAEA,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;EAiCtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;uBAEhB,kBAAkB;0BACb,MAAM,IAAI;;8BA3DR,OAAO;qCAEA,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;CAqDtC,CAAC"}
1
+ {"version":3,"file":"impersonateSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/impersonateSyncAdapter.ts"],"names":[],"mappings":"AACA,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;AAoCxD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUrE;AAiED,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;;8BAlDJ,OAAO;qCAON,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;EAiCtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;uBAEhB,kBAAkB;0BACb,MAAM,IAAI;;8BAhEF,OAAO;qCAON,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;CAqDtC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/impersonate",
3
- "version": "7.0.16",
3
+ "version": "7.0.18",
4
4
  "description": "Test your React Native app as any user, role, or flag combo — without logging out or rebuilding. Part of Buoy devtools.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
- "@buoy-gg/shared-ui": "^7.0.16"
29
+ "@buoy-gg/shared-ui": "^7.0.18"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "*",