react-native-in-app-debugger 1.0.56 → 1.0.57
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/Api/index.jsx +138 -65
- package/X.jsx +20 -7
- package/index.jsx +32 -27
- package/package.json +1 -1
package/Api/index.jsx
CHANGED
|
@@ -1,34 +1,58 @@
|
|
|
1
|
-
import React, { useState } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
SectionList,
|
|
4
|
+
TextInput,
|
|
5
|
+
View,
|
|
6
|
+
Alert,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
} from "react-native";
|
|
10
|
+
import Text from "../Text";
|
|
11
|
+
import Highlight from "../Highlight";
|
|
12
|
+
import Bookmark from "../Bookmark";
|
|
13
|
+
import X from "../X";
|
|
14
|
+
import getRandomBrightColor from "../utils/getRandomBrightColor";
|
|
15
|
+
import { MAX_URL_LENGTH } from "./Row";
|
|
9
16
|
let Clipboard;
|
|
10
17
|
try {
|
|
11
|
-
Clipboard = require(
|
|
18
|
+
Clipboard = require("@react-native-clipboard/clipboard")?.default;
|
|
12
19
|
} catch (error) {
|
|
13
20
|
// console.error("Error importing Clipboard:", error);
|
|
14
21
|
}
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
let LocalStorage;
|
|
24
|
+
try {
|
|
25
|
+
LocalStorage =
|
|
26
|
+
require("@react-native-async-storage/async-storage/src").default;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
// console.error("Error importing LocalStorage:", error);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
import Row from "./Row";
|
|
17
32
|
|
|
18
33
|
const BlacklistIcon = () => (
|
|
19
|
-
<View style={{ borderRadius: 100, backgroundColor:
|
|
34
|
+
<View style={{ borderRadius: 100, backgroundColor: "black" }}>
|
|
20
35
|
<X size={12} />
|
|
21
36
|
</View>
|
|
22
37
|
);
|
|
23
38
|
|
|
24
39
|
const isError = (a) => a.response?.status < 200 || a.response?.status >= 400;
|
|
25
40
|
export default (props) => {
|
|
26
|
-
const [filter, setFilter] = useState(
|
|
41
|
+
const [filter, setFilter] = useState("");
|
|
27
42
|
const [errorOnly, setErrorOnly] = useState(false);
|
|
28
43
|
const [showBookmarkOnly, setShowBookmarkOnly] = useState(false);
|
|
29
44
|
const [expands, setExpands] = useState({});
|
|
30
45
|
const apis = props.apis.filter((a) => !errorOnly || isError(a));
|
|
31
46
|
|
|
47
|
+
if (LocalStorage) {
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
LocalStorage.getItem("in-app-debugger-api-filter").then(setFilter);
|
|
50
|
+
}, []);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
LocalStorage.setItem("in-app-debugger-api-filter", filter);
|
|
53
|
+
}, [filter]);
|
|
54
|
+
}
|
|
55
|
+
|
|
32
56
|
const hasError = apis.some(isError);
|
|
33
57
|
|
|
34
58
|
return (
|
|
@@ -38,26 +62,29 @@ export default (props) => {
|
|
|
38
62
|
<TouchableOpacity
|
|
39
63
|
style={styles.actionButton}
|
|
40
64
|
onPress={() =>
|
|
41
|
-
Alert.alert(
|
|
42
|
-
{ text:
|
|
43
|
-
{ text:
|
|
65
|
+
Alert.alert("Are you sure", "You want to clear all logs", [
|
|
66
|
+
{ text: "Delete", onPress: props.clear, style: "cancel" },
|
|
67
|
+
{ text: "Cancel" },
|
|
44
68
|
])
|
|
45
69
|
}
|
|
46
70
|
>
|
|
47
|
-
<Text style={{ color:
|
|
71
|
+
<Text style={{ color: "black", fontSize: 10 }}>Clear logs</Text>
|
|
48
72
|
</TouchableOpacity>
|
|
49
73
|
)}
|
|
50
74
|
{hasError && !filter && (
|
|
51
|
-
<TouchableOpacity
|
|
75
|
+
<TouchableOpacity
|
|
76
|
+
style={{ padding: 5 }}
|
|
77
|
+
onPress={() => setErrorOnly((v) => !v)}
|
|
78
|
+
>
|
|
52
79
|
<Text
|
|
53
80
|
style={{
|
|
54
|
-
color:
|
|
55
|
-
textDecorationLine: errorOnly ?
|
|
81
|
+
color: "red",
|
|
82
|
+
textDecorationLine: errorOnly ? "line-through" : undefined,
|
|
56
83
|
fontSize: 10,
|
|
57
84
|
}}
|
|
58
85
|
>
|
|
59
86
|
{apis.filter(isError).length} error
|
|
60
|
-
{apis.filter(isError).length > 1 ?
|
|
87
|
+
{apis.filter(isError).length > 1 ? "s" : ""}
|
|
61
88
|
</Text>
|
|
62
89
|
</TouchableOpacity>
|
|
63
90
|
)}
|
|
@@ -65,57 +92,91 @@ export default (props) => {
|
|
|
65
92
|
<TouchableOpacity
|
|
66
93
|
style={styles.actionButton}
|
|
67
94
|
onPress={() =>
|
|
68
|
-
Alert.alert(
|
|
69
|
-
{
|
|
70
|
-
|
|
95
|
+
Alert.alert("Are you sure", "You want to clear all blacklists", [
|
|
96
|
+
{
|
|
97
|
+
text: "Clear",
|
|
98
|
+
onPress: () => props.setBlacklists(),
|
|
99
|
+
style: "cancel",
|
|
100
|
+
},
|
|
101
|
+
{ text: "Cancel" },
|
|
71
102
|
])
|
|
72
103
|
}
|
|
73
104
|
>
|
|
74
|
-
<Text style={{ color:
|
|
105
|
+
<Text style={{ color: "black", fontSize: 10 }}>
|
|
106
|
+
Clear {props.blacklists.length}
|
|
107
|
+
</Text>
|
|
75
108
|
<BlacklistIcon />
|
|
76
109
|
</TouchableOpacity>
|
|
77
110
|
)}
|
|
78
111
|
{!!Object.keys(props.bookmarks).length && (
|
|
79
112
|
<>
|
|
80
|
-
<TouchableOpacity
|
|
113
|
+
<TouchableOpacity
|
|
114
|
+
style={styles.actionButton}
|
|
115
|
+
onPress={() => setShowBookmarkOnly((v) => !v)}
|
|
116
|
+
>
|
|
81
117
|
<Bookmark size={7} />
|
|
82
|
-
<Text style={{ color:
|
|
118
|
+
<Text style={{ color: "black", fontSize: 10 }}>
|
|
119
|
+
{showBookmarkOnly ? "& others" : "Only"}
|
|
120
|
+
</Text>
|
|
83
121
|
</TouchableOpacity>
|
|
84
|
-
<TouchableOpacity
|
|
85
|
-
|
|
122
|
+
<TouchableOpacity
|
|
123
|
+
style={styles.actionButton}
|
|
124
|
+
onPress={() => props.setBookmarks({})}
|
|
125
|
+
>
|
|
126
|
+
<Text style={{ color: "black", fontSize: 10 }}>
|
|
127
|
+
Clear {Object.keys(props.bookmarks).length}
|
|
128
|
+
</Text>
|
|
86
129
|
<Bookmark size={7} />
|
|
87
130
|
</TouchableOpacity>
|
|
88
131
|
</>
|
|
89
132
|
)}
|
|
90
133
|
<TextInput
|
|
91
134
|
value={filter}
|
|
92
|
-
placeholder=
|
|
93
|
-
clearButtonMode=
|
|
94
|
-
placeholderTextColor=
|
|
135
|
+
placeholder="Filter..."
|
|
136
|
+
clearButtonMode="always"
|
|
137
|
+
placeholderTextColor="grey"
|
|
95
138
|
style={styles.textInput}
|
|
96
139
|
onChangeText={(t) => setFilter(t.toLowerCase())}
|
|
97
140
|
/>
|
|
98
141
|
</View>
|
|
99
|
-
{!filter &&
|
|
100
|
-
|
|
101
|
-
|
|
142
|
+
{!filter &&
|
|
143
|
+
!!props.maxNumOfApiToStore &&
|
|
144
|
+
apis.length >= props.maxNumOfApiToStore && (
|
|
145
|
+
<Text style={{ color: "#ffffff88", padding: 10 }}>
|
|
146
|
+
Capped to only latest {props.maxNumOfApiToStore} APIs
|
|
147
|
+
</Text>
|
|
148
|
+
)}
|
|
102
149
|
<SectionList
|
|
103
150
|
keyExtractor={(i) => i.id}
|
|
104
151
|
stickySectionHeadersEnabled
|
|
105
152
|
showsVerticalScrollIndicator
|
|
106
153
|
sections={apis
|
|
107
|
-
.filter(
|
|
154
|
+
.filter(
|
|
155
|
+
(a) => !filter || JSON.stringify(a).toLowerCase().includes(filter)
|
|
156
|
+
)
|
|
108
157
|
.filter((a) => !showBookmarkOnly || props.bookmarks[a.id])
|
|
109
158
|
.map((data) => ({ data: [data], id: data.id }))}
|
|
110
|
-
renderItem={(i) =>
|
|
159
|
+
renderItem={(i) =>
|
|
160
|
+
expands[i.item.id] ? (
|
|
161
|
+
<Row {...i} filter={filter} />
|
|
162
|
+
) : (
|
|
163
|
+
<View style={{ height: 20 }} />
|
|
164
|
+
)
|
|
165
|
+
}
|
|
111
166
|
renderSectionHeader={({ section: { data } }) => {
|
|
112
167
|
const item = data[0];
|
|
113
168
|
const hasResponse = !!item.response;
|
|
114
169
|
|
|
115
|
-
const duration = item.response?.timestamp
|
|
170
|
+
const duration = item.response?.timestamp
|
|
171
|
+
? ~~(item.response?.timestamp - item.request.timestamp) / 1000
|
|
172
|
+
: 0;
|
|
116
173
|
const isExpand = expands[item.id];
|
|
117
174
|
const bookmarkColor = props.bookmarks[item.id];
|
|
118
|
-
const color = hasResponse
|
|
175
|
+
const color = hasResponse
|
|
176
|
+
? item.response.error
|
|
177
|
+
? "red"
|
|
178
|
+
: "white"
|
|
179
|
+
: "yellow";
|
|
119
180
|
|
|
120
181
|
return (
|
|
121
182
|
<View style={styles.rowHeader}>
|
|
@@ -123,7 +184,8 @@ export default (props) => {
|
|
|
123
184
|
color={bookmarkColor}
|
|
124
185
|
onPress={() => {
|
|
125
186
|
props.setBookmarks((v) => {
|
|
126
|
-
if (!bookmarkColor)
|
|
187
|
+
if (!bookmarkColor)
|
|
188
|
+
return { ...v, [item.id]: getRandomBrightColor() };
|
|
127
189
|
const newV = { ...v };
|
|
128
190
|
delete newV[item.id];
|
|
129
191
|
return newV;
|
|
@@ -133,14 +195,17 @@ export default (props) => {
|
|
|
133
195
|
<Text selectable style={{ flex: 1, color, marginVertical: 10 }}>
|
|
134
196
|
<Text style={{ opacity: 0.7 }}>
|
|
135
197
|
{item.request.method +
|
|
136
|
-
` (${item.response?.status ??
|
|
137
|
-
|
|
198
|
+
` (${item.response?.status ?? "no response"})` +
|
|
199
|
+
" - " +
|
|
138
200
|
item.request.time +
|
|
139
|
-
(hasResponse ?
|
|
140
|
-
|
|
201
|
+
(hasResponse ? " - " + duration + " second(s)" : "") +
|
|
202
|
+
"\n"}
|
|
141
203
|
</Text>
|
|
142
|
-
<Highlight
|
|
143
|
-
|
|
204
|
+
<Highlight
|
|
205
|
+
text={item.request.url.slice(0, MAX_URL_LENGTH)}
|
|
206
|
+
filter={filter}
|
|
207
|
+
/>
|
|
208
|
+
{item.request.url.length > MAX_URL_LENGTH && "......."}
|
|
144
209
|
</Text>
|
|
145
210
|
<View style={{ gap: 4 }}>
|
|
146
211
|
<TouchableOpacity
|
|
@@ -154,33 +219,41 @@ export default (props) => {
|
|
|
154
219
|
}
|
|
155
220
|
style={styles.actionButton}
|
|
156
221
|
>
|
|
157
|
-
<Text style={{ color:
|
|
222
|
+
<Text style={{ color: "black", fontSize: 10 }}>
|
|
223
|
+
{isExpand ? "Hide" : "Show"}
|
|
224
|
+
</Text>
|
|
158
225
|
</TouchableOpacity>
|
|
159
226
|
{!!Clipboard && (
|
|
160
227
|
<TouchableOpacity
|
|
161
228
|
onPress={() => {
|
|
162
229
|
const content = { ...item };
|
|
163
230
|
delete content.id;
|
|
164
|
-
Clipboard.setString(
|
|
231
|
+
Clipboard.setString(
|
|
232
|
+
JSON.stringify(content, undefined, 4)
|
|
233
|
+
);
|
|
165
234
|
}}
|
|
166
235
|
style={styles.actionButton}
|
|
167
236
|
>
|
|
168
|
-
<Text style={{ color:
|
|
237
|
+
<Text style={{ color: "black", fontSize: 10 }}>Copy</Text>
|
|
169
238
|
</TouchableOpacity>
|
|
170
239
|
)}
|
|
171
240
|
<TouchableOpacity
|
|
172
241
|
onPress={() => {
|
|
173
242
|
Alert.alert(
|
|
174
|
-
|
|
243
|
+
"Are you sure",
|
|
175
244
|
`You want to blacklist: \n\n(${item.request.method}) ${item.request.url} \n\nwhere all history logs for this API will be removed and all future request for this API will not be recorded?`,
|
|
176
245
|
[
|
|
177
246
|
{
|
|
178
|
-
text:
|
|
179
|
-
onPress: () =>
|
|
180
|
-
|
|
247
|
+
text: "Blacklist",
|
|
248
|
+
onPress: () =>
|
|
249
|
+
props.setBlacklists({
|
|
250
|
+
method: item.request.method,
|
|
251
|
+
url: item.request.url,
|
|
252
|
+
}),
|
|
253
|
+
style: "cancel",
|
|
181
254
|
},
|
|
182
|
-
{ text:
|
|
183
|
-
]
|
|
255
|
+
{ text: "Cancel" },
|
|
256
|
+
]
|
|
184
257
|
);
|
|
185
258
|
}}
|
|
186
259
|
style={styles.actionButton}
|
|
@@ -198,28 +271,28 @@ export default (props) => {
|
|
|
198
271
|
|
|
199
272
|
const styles = StyleSheet.create({
|
|
200
273
|
container: {
|
|
201
|
-
flexDirection:
|
|
202
|
-
flexWrap:
|
|
274
|
+
flexDirection: "row",
|
|
275
|
+
flexWrap: "wrap",
|
|
203
276
|
paddingLeft: 5,
|
|
204
|
-
alignItems:
|
|
277
|
+
alignItems: "center",
|
|
205
278
|
gap: 5,
|
|
206
279
|
},
|
|
207
280
|
actionButton: {
|
|
208
|
-
backgroundColor:
|
|
281
|
+
backgroundColor: "white",
|
|
209
282
|
borderRadius: 5,
|
|
210
283
|
padding: 4,
|
|
211
|
-
flexDirection:
|
|
212
|
-
alignItems:
|
|
213
|
-
justifyContent:
|
|
284
|
+
flexDirection: "row",
|
|
285
|
+
alignItems: "center",
|
|
286
|
+
justifyContent: "center",
|
|
214
287
|
gap: 3,
|
|
215
288
|
},
|
|
216
289
|
rowHeader: {
|
|
217
|
-
flexDirection:
|
|
290
|
+
flexDirection: "row",
|
|
218
291
|
gap: 5,
|
|
219
|
-
backgroundColor:
|
|
292
|
+
backgroundColor: "black",
|
|
220
293
|
padding: 5,
|
|
221
294
|
paddingTop: 10,
|
|
222
|
-
shadowColor:
|
|
295
|
+
shadowColor: "black",
|
|
223
296
|
shadowOffset: {
|
|
224
297
|
width: 0,
|
|
225
298
|
height: 2,
|
|
@@ -230,5 +303,5 @@ const styles = StyleSheet.create({
|
|
|
230
303
|
elevation: 10,
|
|
231
304
|
zIndex: 99,
|
|
232
305
|
},
|
|
233
|
-
textInput: {
|
|
306
|
+
textInput: { padding: 5, color: "white", flex: 1, minWidth: 100 },
|
|
234
307
|
});
|
package/X.jsx
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { StyleSheet, TouchableOpacity, View } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyleSheet, TouchableOpacity, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
const height = 3;
|
|
5
|
-
export default ({ size = 20, color =
|
|
5
|
+
export default ({ size = 20, color = "white", style = {}, ...rest }) => {
|
|
6
6
|
const panelStyle = { top: size / 2, width: size, backgroundColor: color };
|
|
7
7
|
const Component = rest.onPress ? TouchableOpacity : View;
|
|
8
8
|
return (
|
|
9
9
|
<Component
|
|
10
10
|
{...rest}
|
|
11
11
|
style={{
|
|
12
|
+
...style,
|
|
12
13
|
width: size,
|
|
13
14
|
height: size,
|
|
14
|
-
transform: [{ scale:
|
|
15
|
+
transform: [{ scale: 2 }],
|
|
15
16
|
}}
|
|
16
17
|
>
|
|
17
18
|
<View style={{ width: size, height: size, transform: [{ scale: 0.5 }] }}>
|
|
18
|
-
<View
|
|
19
|
-
|
|
19
|
+
<View
|
|
20
|
+
style={[
|
|
21
|
+
styles.panel,
|
|
22
|
+
panelStyle,
|
|
23
|
+
{ transform: [...styles.panel.transform, { rotate: "45deg" }] },
|
|
24
|
+
]}
|
|
25
|
+
/>
|
|
26
|
+
<View
|
|
27
|
+
style={[
|
|
28
|
+
styles.panel,
|
|
29
|
+
panelStyle,
|
|
30
|
+
{ transform: [...styles.panel.transform, { rotate: "-45deg" }] },
|
|
31
|
+
]}
|
|
32
|
+
/>
|
|
20
33
|
</View>
|
|
21
34
|
</Component>
|
|
22
35
|
);
|
|
@@ -26,6 +39,6 @@ const styles = StyleSheet.create({
|
|
|
26
39
|
panel: {
|
|
27
40
|
height,
|
|
28
41
|
transform: [{ translateY: -height / 2 }],
|
|
29
|
-
position:
|
|
42
|
+
position: "absolute",
|
|
30
43
|
},
|
|
31
44
|
});
|
package/index.jsx
CHANGED
|
@@ -177,37 +177,42 @@ export default ({
|
|
|
177
177
|
</View>
|
|
178
178
|
<View style={{ flexDirection: "row", padding: 5, gap: 6 }}>
|
|
179
179
|
<View style={{ flex: 1, flexDirection: "row" }}>
|
|
180
|
-
{[
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
180
|
+
{[
|
|
181
|
+
"api",
|
|
182
|
+
!!variables && "variables",
|
|
183
|
+
"libs",
|
|
184
|
+
...tabs.map((t) => t.title),
|
|
185
|
+
]
|
|
186
|
+
.filter(Boolean)
|
|
187
|
+
.map((t, i) => {
|
|
188
|
+
const isSelected = t === tab;
|
|
189
|
+
return (
|
|
190
|
+
<TouchableOpacity
|
|
191
|
+
onPress={() => setTab(t)}
|
|
192
|
+
activeOpacity={isSelected ? 1 : 0.7}
|
|
193
|
+
key={t}
|
|
194
|
+
style={{
|
|
195
|
+
flex: 1,
|
|
196
|
+
borderBottomWidth: +isSelected,
|
|
197
|
+
borderColor: "white",
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
200
|
+
<Text
|
|
188
201
|
style={{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
202
|
+
color: "white",
|
|
203
|
+
opacity: isSelected ? 1 : 0.5,
|
|
204
|
+
textAlign: "center",
|
|
205
|
+
textTransform: "uppercase",
|
|
192
206
|
}}
|
|
193
207
|
>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}}
|
|
201
|
-
>
|
|
202
|
-
{t}
|
|
203
|
-
{!i && !!apis.length && <Text> ({apis.length})</Text>}
|
|
204
|
-
</Text>
|
|
205
|
-
</TouchableOpacity>
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
)}
|
|
208
|
+
{t}
|
|
209
|
+
{!i && !!apis.length && <Text> ({apis.length})</Text>}
|
|
210
|
+
</Text>
|
|
211
|
+
</TouchableOpacity>
|
|
212
|
+
);
|
|
213
|
+
})}
|
|
209
214
|
</View>
|
|
210
|
-
<X onPress={() => setIsOpen(false)} />
|
|
215
|
+
<X style={{ marginRight: 5 }} onPress={() => setIsOpen(false)} />
|
|
211
216
|
</View>
|
|
212
217
|
{tab === "variables" && !!variables && (
|
|
213
218
|
<Variables variables={variables} />
|
package/package.json
CHANGED