@aimeloic/monkey-tester 2.0.0 → 2.0.1
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/html.backup.js +317 -0
- package/htmlTemplate.js +1038 -182
- package/index.js +216 -40
- package/package.json +1 -1
package/htmlTemplate.js
CHANGED
|
@@ -1,316 +1,1172 @@
|
|
|
1
1
|
export function getHtmlTemplate(endpoints) {
|
|
2
|
-
const safeJsonString = Buffer
|
|
2
|
+
const safeJsonString = Buffer
|
|
3
|
+
.from(JSON.stringify(endpoints))
|
|
4
|
+
.toString('base64');
|
|
3
5
|
|
|
4
6
|
return `
|
|
5
7
|
<!DOCTYPE html>
|
|
6
8
|
<html lang="en">
|
|
7
9
|
<head>
|
|
8
|
-
<meta charset="UTF-8"
|
|
9
|
-
<meta
|
|
10
|
+
<meta charset="UTF-8" />
|
|
11
|
+
<meta
|
|
12
|
+
name="viewport"
|
|
13
|
+
content="width=device-width, initial-scale=1.0"
|
|
14
|
+
/>
|
|
15
|
+
|
|
10
16
|
<title>Endtester — API Environment</title>
|
|
11
|
-
|
|
17
|
+
|
|
18
|
+
<link
|
|
19
|
+
href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=DM+Mono:wght@400;500&family=DM+Sans:wght@300;400;500&display=swap"
|
|
20
|
+
rel="stylesheet"
|
|
21
|
+
/>
|
|
22
|
+
|
|
12
23
|
<style>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
:root{
|
|
25
|
+
--bg:#0e0c09;
|
|
26
|
+
--surface:#181510;
|
|
27
|
+
--surface2:#221d14;
|
|
28
|
+
--border:#3a3020;
|
|
29
|
+
--accent:#e8a838;
|
|
30
|
+
--text:#f0e8d8;
|
|
31
|
+
--text-dim:#9a8c78;
|
|
32
|
+
--red:#d45c3c;
|
|
33
|
+
--green:#6ba05a;
|
|
34
|
+
--blue:#5a86c0;
|
|
35
|
+
--radius:8px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
*{
|
|
39
|
+
box-sizing:border-box;
|
|
40
|
+
margin:0;
|
|
41
|
+
padding:0;
|
|
42
|
+
min-width:0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
html,
|
|
46
|
+
body{
|
|
47
|
+
width:100%;
|
|
48
|
+
overflow-x:hidden;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
body{
|
|
52
|
+
background:var(--bg);
|
|
53
|
+
color:var(--text);
|
|
54
|
+
font-family:'DM Sans',sans-serif;
|
|
55
|
+
font-size:14px;
|
|
56
|
+
min-height:100vh;
|
|
57
|
+
overflow-x:hidden;
|
|
58
|
+
|
|
59
|
+
background-image:
|
|
60
|
+
radial-gradient(
|
|
61
|
+
ellipse 80% 60% at 50% -20%,
|
|
62
|
+
#3a2a0a22 0%,
|
|
63
|
+
transparent 70%
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
header{
|
|
68
|
+
width:100%;
|
|
69
|
+
border-bottom:1px solid var(--border);
|
|
70
|
+
|
|
71
|
+
padding:20px 24px;
|
|
72
|
+
|
|
73
|
+
display:flex;
|
|
74
|
+
align-items:center;
|
|
75
|
+
gap:20px;
|
|
76
|
+
|
|
77
|
+
background:#0e0c09ee;
|
|
78
|
+
|
|
79
|
+
backdrop-filter:blur(8px);
|
|
80
|
+
|
|
81
|
+
position:sticky;
|
|
82
|
+
top:0;
|
|
83
|
+
z-index:100;
|
|
84
|
+
|
|
85
|
+
overflow:hidden;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.logo{
|
|
89
|
+
font-family:'Playfair Display',serif;
|
|
90
|
+
font-size:22px;
|
|
91
|
+
color:var(--accent);
|
|
92
|
+
letter-spacing:.02em;
|
|
93
|
+
flex-shrink:0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.logo span{
|
|
97
|
+
color:var(--text-dim);
|
|
98
|
+
font-size:13px;
|
|
99
|
+
font-family:'DM Mono',monospace;
|
|
100
|
+
display:block;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.header-right{
|
|
104
|
+
margin-left:auto;
|
|
105
|
+
|
|
106
|
+
display:flex;
|
|
107
|
+
align-items:center;
|
|
108
|
+
gap:12px;
|
|
109
|
+
|
|
110
|
+
flex-wrap:wrap;
|
|
111
|
+
justify-content:flex-end;
|
|
112
|
+
|
|
113
|
+
max-width:100%;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.jwt-wrap,
|
|
117
|
+
.base-url-wrap{
|
|
118
|
+
display:flex;
|
|
119
|
+
align-items:center;
|
|
120
|
+
gap:8px;
|
|
121
|
+
|
|
122
|
+
min-width:0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.jwt-wrap label,
|
|
126
|
+
.base-url-wrap label{
|
|
127
|
+
color:var(--text-dim);
|
|
128
|
+
font-size:12px;
|
|
129
|
+
font-family:'DM Mono',monospace;
|
|
130
|
+
white-space:nowrap;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#jwt-input,
|
|
134
|
+
#base-url{
|
|
135
|
+
background:var(--surface2);
|
|
136
|
+
|
|
137
|
+
border:1px solid var(--border);
|
|
138
|
+
|
|
139
|
+
color:var(--text);
|
|
140
|
+
|
|
141
|
+
font-family:'DM Mono',monospace;
|
|
142
|
+
|
|
143
|
+
font-size:11px;
|
|
144
|
+
|
|
145
|
+
padding:6px 10px;
|
|
146
|
+
|
|
147
|
+
border-radius:var(--radius);
|
|
148
|
+
|
|
149
|
+
width:220px;
|
|
150
|
+
max-width:100%;
|
|
151
|
+
|
|
152
|
+
outline:none;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.layout{
|
|
156
|
+
width:100%;
|
|
157
|
+
max-width:100vw;
|
|
158
|
+
|
|
159
|
+
display:grid;
|
|
160
|
+
|
|
161
|
+
grid-template-columns:
|
|
162
|
+
minmax(220px,260px)
|
|
163
|
+
minmax(0,1fr)
|
|
164
|
+
minmax(300px,400px);
|
|
165
|
+
|
|
166
|
+
height:calc(100vh - 78px);
|
|
167
|
+
|
|
168
|
+
overflow:hidden;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
aside{
|
|
172
|
+
border-right:1px solid var(--border);
|
|
173
|
+
|
|
174
|
+
overflow-y:auto;
|
|
175
|
+
overflow-x:hidden;
|
|
176
|
+
|
|
177
|
+
padding:16px 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.section-label{
|
|
181
|
+
font-size:10px;
|
|
182
|
+
|
|
183
|
+
font-family:'DM Mono',monospace;
|
|
184
|
+
|
|
185
|
+
color:var(--text-dim);
|
|
186
|
+
|
|
187
|
+
letter-spacing:.12em;
|
|
188
|
+
|
|
189
|
+
text-transform:uppercase;
|
|
190
|
+
|
|
191
|
+
padding:12px 18px 6px;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.nav-item{
|
|
195
|
+
display:flex;
|
|
196
|
+
align-items:center;
|
|
197
|
+
gap:10px;
|
|
198
|
+
|
|
199
|
+
padding:8px 18px;
|
|
200
|
+
|
|
201
|
+
cursor:pointer;
|
|
202
|
+
|
|
203
|
+
border-left:2px solid transparent;
|
|
204
|
+
|
|
205
|
+
color:var(--text-dim);
|
|
206
|
+
|
|
207
|
+
overflow:hidden;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.nav-item:hover{
|
|
211
|
+
background:var(--surface);
|
|
212
|
+
color:var(--text);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.nav-item.active{
|
|
216
|
+
border-left-color:var(--accent);
|
|
217
|
+
|
|
218
|
+
background:var(--surface);
|
|
219
|
+
|
|
220
|
+
color:var(--accent);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.method-badge{
|
|
224
|
+
font-family:'DM Mono',monospace;
|
|
225
|
+
|
|
226
|
+
font-size:9px;
|
|
227
|
+
|
|
228
|
+
font-weight:500;
|
|
229
|
+
|
|
230
|
+
padding:2px 5px;
|
|
231
|
+
|
|
232
|
+
border-radius:3px;
|
|
233
|
+
|
|
234
|
+
min-width:45px;
|
|
235
|
+
|
|
236
|
+
text-align:center;
|
|
237
|
+
|
|
238
|
+
flex-shrink:0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.GET{
|
|
242
|
+
background:#1a3a22;
|
|
243
|
+
color:#6ba05a;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.POST{
|
|
247
|
+
background:#1a2e3a;
|
|
248
|
+
color:#5a86c0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.PUT,
|
|
252
|
+
.PATCH{
|
|
253
|
+
background:#3a2e10;
|
|
254
|
+
color:#e8a838;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.DELETE{
|
|
258
|
+
background:#3a1a14;
|
|
259
|
+
color:#d45c3c;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.nav-label{
|
|
263
|
+
font-size:11px;
|
|
264
|
+
|
|
265
|
+
flex:1;
|
|
266
|
+
|
|
267
|
+
overflow:hidden;
|
|
268
|
+
|
|
269
|
+
text-overflow:ellipsis;
|
|
270
|
+
|
|
271
|
+
white-space:nowrap;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
main{
|
|
275
|
+
overflow-y:auto;
|
|
276
|
+
overflow-x:hidden;
|
|
277
|
+
|
|
278
|
+
padding:24px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.endpoint-title{
|
|
282
|
+
font-family:'Playfair Display',serif;
|
|
283
|
+
|
|
284
|
+
font-size:20px;
|
|
285
|
+
|
|
286
|
+
color:var(--accent);
|
|
287
|
+
|
|
288
|
+
margin-bottom:6px;
|
|
289
|
+
|
|
290
|
+
overflow-wrap:anywhere;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.endpoint-path{
|
|
294
|
+
font-family:'DM Mono',monospace;
|
|
295
|
+
|
|
296
|
+
font-size:12px;
|
|
297
|
+
|
|
298
|
+
color:var(--text-dim);
|
|
299
|
+
|
|
300
|
+
margin-bottom:20px;
|
|
301
|
+
|
|
302
|
+
display:flex;
|
|
303
|
+
align-items:center;
|
|
304
|
+
gap:8px;
|
|
305
|
+
|
|
306
|
+
flex-wrap:wrap;
|
|
307
|
+
|
|
308
|
+
overflow-wrap:anywhere;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.endpoint-desc{
|
|
312
|
+
color:var(--text-dim);
|
|
313
|
+
|
|
314
|
+
font-size:13px;
|
|
315
|
+
|
|
316
|
+
line-height:1.6;
|
|
317
|
+
|
|
318
|
+
margin-bottom:24px;
|
|
319
|
+
|
|
320
|
+
border-left:2px solid var(--border);
|
|
321
|
+
|
|
322
|
+
padding-left:12px;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.form-section{
|
|
326
|
+
background:var(--surface);
|
|
327
|
+
|
|
328
|
+
border:1px solid var(--border);
|
|
329
|
+
|
|
330
|
+
border-radius:var(--radius);
|
|
331
|
+
|
|
332
|
+
padding:18px;
|
|
333
|
+
|
|
334
|
+
margin-bottom:16px;
|
|
335
|
+
|
|
336
|
+
overflow:hidden;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.form-section-title{
|
|
340
|
+
font-size:11px;
|
|
341
|
+
|
|
342
|
+
font-family:'DM Mono',monospace;
|
|
343
|
+
|
|
344
|
+
color:var(--text-dim);
|
|
345
|
+
|
|
346
|
+
letter-spacing:.1em;
|
|
347
|
+
|
|
348
|
+
text-transform:uppercase;
|
|
349
|
+
|
|
350
|
+
margin-bottom:14px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.field-row{
|
|
354
|
+
display:grid;
|
|
355
|
+
|
|
356
|
+
grid-template-columns:
|
|
357
|
+
minmax(90px,140px)
|
|
358
|
+
minmax(0,1fr);
|
|
359
|
+
|
|
360
|
+
align-items:center;
|
|
361
|
+
|
|
362
|
+
gap:10px;
|
|
363
|
+
|
|
364
|
+
margin-bottom:10px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.field-label{
|
|
368
|
+
font-family:'DM Mono',monospace;
|
|
369
|
+
|
|
370
|
+
font-size:11px;
|
|
371
|
+
|
|
372
|
+
color:var(--text-dim);
|
|
373
|
+
|
|
374
|
+
text-align:right;
|
|
375
|
+
|
|
376
|
+
overflow-wrap:anywhere;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
input,
|
|
380
|
+
select,
|
|
381
|
+
textarea{
|
|
382
|
+
max-width:100%;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
input[type=text],
|
|
386
|
+
input[type=number],
|
|
387
|
+
input[type=password],
|
|
388
|
+
input[type=email],
|
|
389
|
+
input[type=date],
|
|
390
|
+
input[type=tel],
|
|
391
|
+
input[type=url],
|
|
392
|
+
select{
|
|
393
|
+
background:var(--surface2);
|
|
394
|
+
|
|
395
|
+
border:1px solid var(--border);
|
|
396
|
+
|
|
397
|
+
color:var(--text);
|
|
398
|
+
|
|
399
|
+
font-family:'DM Mono',monospace;
|
|
400
|
+
|
|
401
|
+
font-size:12px;
|
|
402
|
+
|
|
403
|
+
padding:7px 10px;
|
|
404
|
+
|
|
405
|
+
border-radius:var(--radius);
|
|
406
|
+
|
|
407
|
+
width:100%;
|
|
408
|
+
|
|
409
|
+
outline:none;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.btn-row{
|
|
413
|
+
margin-top:20px;
|
|
414
|
+
|
|
415
|
+
display:flex;
|
|
416
|
+
gap:10px;
|
|
417
|
+
|
|
418
|
+
flex-wrap:wrap;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.btn{
|
|
422
|
+
background:var(--accent);
|
|
423
|
+
|
|
424
|
+
color:#0e0c09;
|
|
425
|
+
|
|
426
|
+
border:none;
|
|
427
|
+
|
|
428
|
+
padding:10px 22px;
|
|
429
|
+
|
|
430
|
+
border-radius:var(--radius);
|
|
431
|
+
|
|
432
|
+
font-size:13px;
|
|
433
|
+
|
|
434
|
+
font-weight:500;
|
|
435
|
+
|
|
436
|
+
cursor:pointer;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.btn-secondary{
|
|
440
|
+
background:var(--surface2);
|
|
441
|
+
|
|
442
|
+
color:var(--text-dim);
|
|
443
|
+
|
|
444
|
+
border:1px solid var(--border);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.response-panel{
|
|
448
|
+
border-left:1px solid var(--border);
|
|
449
|
+
|
|
450
|
+
display:flex;
|
|
451
|
+
|
|
452
|
+
flex-direction:column;
|
|
453
|
+
|
|
454
|
+
overflow:hidden;
|
|
455
|
+
|
|
456
|
+
min-width:0;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.response-header{
|
|
460
|
+
padding:14px 18px;
|
|
461
|
+
|
|
462
|
+
border-bottom:1px solid var(--border);
|
|
463
|
+
|
|
464
|
+
display:flex;
|
|
465
|
+
align-items:center;
|
|
466
|
+
|
|
467
|
+
gap:10px;
|
|
468
|
+
|
|
469
|
+
background:var(--surface);
|
|
470
|
+
|
|
471
|
+
overflow:hidden;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.response-header-title{
|
|
475
|
+
font-size:11px;
|
|
476
|
+
|
|
477
|
+
font-family:'DM Mono',monospace;
|
|
478
|
+
|
|
479
|
+
color:var(--text-dim);
|
|
480
|
+
|
|
481
|
+
text-transform:uppercase;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.status-badge{
|
|
485
|
+
font-family:'DM Mono',monospace;
|
|
486
|
+
|
|
487
|
+
font-size:12px;
|
|
488
|
+
|
|
489
|
+
margin-left:auto;
|
|
490
|
+
|
|
491
|
+
padding:2px 8px;
|
|
492
|
+
|
|
493
|
+
border-radius:4px;
|
|
494
|
+
|
|
495
|
+
flex-shrink:0;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.status-ok{
|
|
499
|
+
background:#1a3a22;
|
|
500
|
+
color:#6ba05a;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.status-err{
|
|
504
|
+
background:#3a1a14;
|
|
505
|
+
color:#d45c3c;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.status-idle{
|
|
509
|
+
background:var(--surface2);
|
|
510
|
+
color:var(--text-dim);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.response-body{
|
|
514
|
+
flex:1;
|
|
515
|
+
|
|
516
|
+
overflow:auto;
|
|
517
|
+
|
|
518
|
+
padding:16px;
|
|
519
|
+
|
|
520
|
+
font-family:'DM Mono',monospace;
|
|
521
|
+
|
|
522
|
+
font-size:12px;
|
|
523
|
+
|
|
524
|
+
white-space:pre-wrap;
|
|
525
|
+
|
|
526
|
+
overflow-wrap:anywhere;
|
|
527
|
+
|
|
528
|
+
word-break:break-word;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.response-body.empty{
|
|
532
|
+
color:var(--text-dim);
|
|
533
|
+
|
|
534
|
+
display:flex;
|
|
535
|
+
|
|
536
|
+
align-items:center;
|
|
537
|
+
|
|
538
|
+
justify-content:center;
|
|
539
|
+
|
|
540
|
+
text-align:center;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.json-key{color:#e8a838;}
|
|
544
|
+
.json-str{color:#9ab878;}
|
|
545
|
+
.json-num{color:#5a86c0;}
|
|
546
|
+
|
|
547
|
+
#toast{
|
|
548
|
+
position:fixed;
|
|
549
|
+
|
|
550
|
+
bottom:24px;
|
|
551
|
+
right:24px;
|
|
552
|
+
|
|
553
|
+
background:var(--surface2);
|
|
554
|
+
|
|
555
|
+
border:1px solid var(--border);
|
|
556
|
+
|
|
557
|
+
padding:10px 18px;
|
|
558
|
+
|
|
559
|
+
border-radius:var(--radius);
|
|
560
|
+
|
|
561
|
+
opacity:0;
|
|
562
|
+
|
|
563
|
+
transition:all .25s;
|
|
564
|
+
|
|
565
|
+
max-width:90vw;
|
|
566
|
+
|
|
567
|
+
overflow-wrap:anywhere;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
#toast.show{
|
|
571
|
+
opacity:1;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
@media (max-width:1200px){
|
|
575
|
+
|
|
576
|
+
.layout{
|
|
577
|
+
grid-template-columns:
|
|
578
|
+
220px
|
|
579
|
+
1fr;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.response-panel{
|
|
583
|
+
display:none;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
@media (max-width:768px){
|
|
588
|
+
|
|
589
|
+
header{
|
|
590
|
+
flex-direction:column;
|
|
591
|
+
align-items:flex-start;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.header-right{
|
|
595
|
+
width:100%;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.layout{
|
|
599
|
+
grid-template-columns:1fr;
|
|
26
600
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
background-image: radial-gradient(ellipse 80% 60% at 50% -20%, #3a2a0a22 0%, transparent 70%);
|
|
601
|
+
|
|
602
|
+
aside{
|
|
603
|
+
display:none;
|
|
31
604
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
605
|
+
|
|
606
|
+
.field-row{
|
|
607
|
+
grid-template-columns:1fr;
|
|
35
608
|
}
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
.jwt-wrap, .base-url-wrap { display: flex; align-items: center; gap: 8px; }
|
|
40
|
-
.jwt-wrap label, .base-url-wrap label { color: var(--text-dim); font-size: 12px; font-family: 'DM Mono', monospace; }
|
|
41
|
-
#jwt-input, #base-url {
|
|
42
|
-
background: var(--surface2); border: 1px solid var(--border); color: var(--text);
|
|
43
|
-
font-family: 'DM Mono', monospace; font-size: 11px; padding: 6px 10px; border-radius: var(--radius); width: 220px; outline: none;
|
|
609
|
+
|
|
610
|
+
.field-label{
|
|
611
|
+
text-align:left;
|
|
44
612
|
}
|
|
45
|
-
|
|
46
|
-
aside { border-right: 1px solid var(--border); overflow-y: auto; padding: 16px 0; }
|
|
47
|
-
.section-label { font-size: 10px; font-family: 'DM Mono', monospace; color: var(--text-dim); letter-spacing: 0.12em; text-transform: uppercase; padding: 12px 18px 6px; }
|
|
48
|
-
.nav-item { display: flex; align-items: center; gap: 10px; padding: 8px 18px; cursor: pointer; border-left: 2px solid transparent; color: var(--text-dim); }
|
|
49
|
-
.nav-item:hover { background: var(--surface); color: var(--text); }
|
|
50
|
-
.nav-item.active { border-left-color: var(--accent); background: var(--surface); color: var(--accent); }
|
|
51
|
-
.method-badge { font-family: 'DM Mono', monospace; font-size: 9px; font-weight: 500; padding: 2px 5px; border-radius: 3px; min-width: 45px; text-align: center; }
|
|
52
|
-
.GET { background: #1a3a22; color: #6ba05a; }
|
|
53
|
-
.POST { background: #1a2e3a; color: #5a86c0; }
|
|
54
|
-
.PUT, .PATCH { background: #3a2e10; color: #e8a838; }
|
|
55
|
-
.DELETE { background: #3a1a14; color: #d45c3c; }
|
|
56
|
-
.nav-label { font-size: 11px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
57
|
-
main { overflow-y: auto; padding: 24px; }
|
|
58
|
-
.endpoint-title { font-family: 'Playfair Display', serif; font-size: 20px; color: var(--accent); margin-bottom: 6px; }
|
|
59
|
-
.endpoint-path { font-family: 'DM Mono', monospace; font-size: 12px; color: var(--text-dim); margin-bottom: 20px; display: flex; align-items: center; gap: 8px; }
|
|
60
|
-
.endpoint-desc { color: var(--text-dim); font-size: 13px; line-height: 1.6; margin-bottom: 24px; border-left: 2px solid var(--border); padding-left: 12px; }
|
|
61
|
-
.form-section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; margin-bottom: 16px; }
|
|
62
|
-
.form-section-title { font-size: 11px; font-family: 'DM Mono', monospace; color: var(--text-dim); letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 14px; }
|
|
63
|
-
.field-row { display: grid; grid-template-columns: 140px 1fr; align-items: center; gap: 10px; margin-bottom: 10px; }
|
|
64
|
-
.field-label { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text-dim); text-align: right; }
|
|
65
|
-
input[type=text], input[type=number], select { background: var(--surface2); border: 1px solid var(--border); color: var(--text); font-family: 'DM Mono', monospace; font-size: 12px; padding: 7px 10px; border-radius: var(--radius); width: 100%; outline: none; }
|
|
66
|
-
.btn { background: var(--accent); color: #0e0c09; border: none; padding: 10px 22px; border-radius: var(--radius); font-size: 13px; font-weight: 500; cursor: pointer; }
|
|
67
|
-
.btn-row { margin-top: 20px; display: flex; gap: 10px; }
|
|
68
|
-
.btn-secondary { background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); }
|
|
69
|
-
.response-panel { border-left: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; }
|
|
70
|
-
.response-header { padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; background: var(--surface); }
|
|
71
|
-
.response-header-title { font-size: 11px; font-family: 'DM Mono', monospace; color: var(--text-dim); text-transform: uppercase; }
|
|
72
|
-
.status-badge { font-family: 'DM Mono', monospace; font-size: 12px; margin-left: auto; padding: 2px 8px; border-radius: 4px; }
|
|
73
|
-
.status-ok { background: #1a3a22; color: #6ba05a; }
|
|
74
|
-
.status-err { background: #3a1a14; color: #d45c3c; }
|
|
75
|
-
.status-idle { background: var(--surface2); color: var(--text-dim); }
|
|
76
|
-
.response-body { flex: 1; overflow-y: auto; padding: 16px; font-family: 'DM Mono', monospace; font-size: 12px; white-space: pre-wrap; word-break: break-all; }
|
|
77
|
-
.response-body.empty { color: var(--text-dim); display: flex; align-items: center; justify-content: center; }
|
|
78
|
-
.json-key { color: #e8a838; } .json-str { color: #9ab878; } .json-num { color: #5a86c0; }
|
|
79
|
-
#toast { position: fixed; bottom: 24px; right: 24px; background: var(--surface2); border: 1px solid var(--border); padding: 10px 18px; border-radius: var(--radius); opacity: 0; transition: all .25s; }
|
|
80
|
-
#toast.show { opacity: 1; }
|
|
613
|
+
}
|
|
81
614
|
</style>
|
|
82
615
|
</head>
|
|
616
|
+
|
|
83
617
|
<body>
|
|
84
618
|
|
|
85
|
-
<div
|
|
619
|
+
<div
|
|
620
|
+
id="endtester-data-vault"
|
|
621
|
+
data-payload="${safeJsonString}"
|
|
622
|
+
style="display:none;"
|
|
623
|
+
></div>
|
|
86
624
|
|
|
87
625
|
<header>
|
|
88
|
-
<div class="logo">
|
|
626
|
+
<div class="logo">
|
|
627
|
+
Endtester
|
|
628
|
+
<span>Application Runtime Sandbox</span>
|
|
629
|
+
</div>
|
|
630
|
+
|
|
89
631
|
<div class="header-right">
|
|
632
|
+
|
|
90
633
|
<div class="base-url-wrap">
|
|
91
634
|
<label>TARGET HOST</label>
|
|
92
|
-
|
|
635
|
+
|
|
636
|
+
<input
|
|
637
|
+
id="base-url"
|
|
638
|
+
type="text"
|
|
639
|
+
value=""
|
|
640
|
+
/>
|
|
93
641
|
</div>
|
|
642
|
+
|
|
94
643
|
<div class="jwt-wrap">
|
|
95
644
|
<label>BEARER AUTH</label>
|
|
96
|
-
|
|
645
|
+
|
|
646
|
+
<input
|
|
647
|
+
id="jwt-input"
|
|
648
|
+
type="text"
|
|
649
|
+
placeholder="Token value..."
|
|
650
|
+
/>
|
|
97
651
|
</div>
|
|
652
|
+
|
|
98
653
|
</div>
|
|
99
654
|
</header>
|
|
100
655
|
|
|
101
656
|
<div class="layout">
|
|
657
|
+
|
|
102
658
|
<aside id="sidebar-nav">
|
|
103
|
-
<div class="section-label">
|
|
659
|
+
<div class="section-label">
|
|
660
|
+
Discovered Endpoints
|
|
661
|
+
</div>
|
|
104
662
|
</aside>
|
|
663
|
+
|
|
105
664
|
<main id="main-panel"></main>
|
|
665
|
+
|
|
106
666
|
<div class="response-panel">
|
|
667
|
+
|
|
107
668
|
<div class="response-header">
|
|
108
|
-
<span class="response-header-title">
|
|
109
|
-
|
|
669
|
+
<span class="response-header-title">
|
|
670
|
+
Response Output
|
|
671
|
+
</span>
|
|
672
|
+
|
|
673
|
+
<span
|
|
674
|
+
id="status-badge"
|
|
675
|
+
class="status-badge status-idle"
|
|
676
|
+
>
|
|
677
|
+
—
|
|
678
|
+
</span>
|
|
679
|
+
</div>
|
|
680
|
+
|
|
681
|
+
<div
|
|
682
|
+
class="response-body empty"
|
|
683
|
+
id="response-body"
|
|
684
|
+
>
|
|
685
|
+
Execute a request row to generate feedback data
|
|
110
686
|
</div>
|
|
111
|
-
|
|
687
|
+
|
|
112
688
|
</div>
|
|
689
|
+
|
|
113
690
|
</div>
|
|
114
691
|
|
|
115
692
|
<div id="toast"></div>
|
|
116
693
|
|
|
117
694
|
<script>
|
|
118
|
-
const rawPayload =
|
|
119
|
-
|
|
695
|
+
const rawPayload =
|
|
696
|
+
document
|
|
697
|
+
.getElementById('endtester-data-vault')
|
|
698
|
+
.getAttribute('data-payload');
|
|
699
|
+
|
|
700
|
+
const ENDPOINTS =
|
|
701
|
+
JSON.parse(atob(rawPayload));
|
|
120
702
|
|
|
121
703
|
let currentEp = '';
|
|
122
704
|
|
|
123
|
-
document
|
|
705
|
+
document
|
|
706
|
+
.getElementById('base-url')
|
|
707
|
+
.value = window.location.origin;
|
|
124
708
|
|
|
125
|
-
function buildSidebar()
|
|
126
|
-
|
|
127
|
-
const
|
|
709
|
+
function buildSidebar(){
|
|
710
|
+
|
|
711
|
+
const sidebar =
|
|
712
|
+
document.getElementById('sidebar-nav');
|
|
713
|
+
|
|
714
|
+
const keys =
|
|
715
|
+
Object.keys(ENDPOINTS);
|
|
716
|
+
|
|
717
|
+
if(keys.length === 0){
|
|
718
|
+
|
|
719
|
+
sidebar.innerHTML +=
|
|
720
|
+
'<div style="padding:15px;color:var(--text-dim)">No endpoints discovered.</div>';
|
|
128
721
|
|
|
129
|
-
if (keys.length === 0) {
|
|
130
|
-
sidebar.innerHTML += '<div style="padding:15px; color:var(--text-dim)">No active application endpoints discovered.</div>';
|
|
131
722
|
return;
|
|
132
723
|
}
|
|
133
724
|
|
|
134
|
-
keys.forEach((key,
|
|
725
|
+
keys.forEach((key,index)=>{
|
|
726
|
+
|
|
135
727
|
const ep = ENDPOINTS[key];
|
|
136
|
-
|
|
137
|
-
div
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
div.
|
|
141
|
-
|
|
728
|
+
|
|
729
|
+
const div =
|
|
730
|
+
document.createElement('div');
|
|
731
|
+
|
|
732
|
+
div.className =
|
|
733
|
+
index === 0
|
|
734
|
+
? 'nav-item active'
|
|
735
|
+
: 'nav-item';
|
|
736
|
+
|
|
737
|
+
div.setAttribute('data-ep',key);
|
|
738
|
+
|
|
739
|
+
div.innerHTML =
|
|
740
|
+
'<span class="method-badge ' + ep.method + '">' +
|
|
741
|
+
ep.method +
|
|
742
|
+
'</span>' +
|
|
743
|
+
'<span class="nav-label">' +
|
|
744
|
+
ep.path +
|
|
745
|
+
'</span>';
|
|
746
|
+
|
|
747
|
+
div.addEventListener('click',()=>{
|
|
748
|
+
|
|
749
|
+
document
|
|
750
|
+
.querySelectorAll('.nav-item')
|
|
751
|
+
.forEach(n=>n.classList.remove('active'));
|
|
752
|
+
|
|
142
753
|
div.classList.add('active');
|
|
754
|
+
|
|
143
755
|
clearResponse();
|
|
756
|
+
|
|
144
757
|
renderPanel(key);
|
|
145
758
|
});
|
|
759
|
+
|
|
146
760
|
sidebar.appendChild(div);
|
|
147
761
|
});
|
|
148
762
|
|
|
149
|
-
if
|
|
763
|
+
if(keys.length > 0){
|
|
764
|
+
renderPanel(keys[0]);
|
|
765
|
+
}
|
|
150
766
|
}
|
|
151
767
|
|
|
152
|
-
function makeInputString(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
768
|
+
function makeInputString(
|
|
769
|
+
type,
|
|
770
|
+
id,
|
|
771
|
+
placeholder,
|
|
772
|
+
defaultValue
|
|
773
|
+
){
|
|
774
|
+
|
|
775
|
+
const pAttr =
|
|
776
|
+
placeholder
|
|
777
|
+
? ' placeholder="' + placeholder + '"'
|
|
778
|
+
: '';
|
|
779
|
+
|
|
780
|
+
const vAttr =
|
|
781
|
+
defaultValue !== undefined
|
|
782
|
+
? ' value="' + defaultValue + '"'
|
|
783
|
+
: '';
|
|
784
|
+
|
|
785
|
+
return \`
|
|
786
|
+
<input
|
|
787
|
+
type="\${type}"
|
|
788
|
+
id="\${id}"
|
|
789
|
+
\${pAttr}
|
|
790
|
+
\${vAttr}
|
|
791
|
+
/>
|
|
792
|
+
\`;
|
|
156
793
|
}
|
|
157
794
|
|
|
158
|
-
function renderPanel(epKey)
|
|
795
|
+
function renderPanel(epKey){
|
|
796
|
+
|
|
159
797
|
currentEp = epKey;
|
|
798
|
+
|
|
160
799
|
const ep = ENDPOINTS[epKey];
|
|
161
|
-
|
|
162
|
-
|
|
800
|
+
|
|
801
|
+
const main =
|
|
802
|
+
document.getElementById('main-panel');
|
|
803
|
+
|
|
804
|
+
if(!ep) return;
|
|
163
805
|
|
|
164
806
|
let html = \`
|
|
165
|
-
<div class="endpoint-title"
|
|
807
|
+
<div class="endpoint-title">
|
|
808
|
+
\${ep.title}
|
|
809
|
+
</div>
|
|
810
|
+
|
|
166
811
|
<div class="endpoint-path">
|
|
167
|
-
<span class="method-badge \${ep.method}"
|
|
168
|
-
|
|
812
|
+
<span class="method-badge \${ep.method}">
|
|
813
|
+
\${ep.method}
|
|
814
|
+
</span>
|
|
815
|
+
|
|
816
|
+
<span>
|
|
817
|
+
\${ep.path}
|
|
818
|
+
</span>
|
|
819
|
+
</div>
|
|
820
|
+
|
|
821
|
+
<div class="endpoint-desc">
|
|
822
|
+
\${ep.desc}
|
|
169
823
|
</div>
|
|
170
|
-
<div class="endpoint-desc">\${ep.desc}</div>
|
|
171
824
|
\`;
|
|
172
825
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
html +=
|
|
176
|
-
|
|
177
|
-
|
|
826
|
+
if(ep.params && ep.params.length){
|
|
827
|
+
|
|
828
|
+
html += \`
|
|
829
|
+
<div class="form-section">
|
|
830
|
+
|
|
831
|
+
<div class="form-section-title">
|
|
832
|
+
Path Parameters
|
|
833
|
+
</div>
|
|
834
|
+
\`;
|
|
835
|
+
|
|
836
|
+
ep.params.forEach((p)=>{
|
|
837
|
+
|
|
178
838
|
html += \`
|
|
179
839
|
<div class="field-row">
|
|
180
|
-
|
|
181
|
-
|
|
840
|
+
|
|
841
|
+
<label class="field-label">
|
|
842
|
+
\${p.label}
|
|
843
|
+
</label>
|
|
844
|
+
|
|
845
|
+
\${makeInputString(
|
|
846
|
+
'text',
|
|
847
|
+
'param-' + p.name,
|
|
848
|
+
p.placeholder,
|
|
849
|
+
''
|
|
850
|
+
)}
|
|
851
|
+
|
|
182
852
|
</div>
|
|
183
853
|
\`;
|
|
184
854
|
});
|
|
185
|
-
|
|
855
|
+
|
|
856
|
+
html += '</div>';
|
|
186
857
|
}
|
|
187
858
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
html +=
|
|
191
|
-
|
|
192
|
-
|
|
859
|
+
if(ep.fields && ep.fields.length){
|
|
860
|
+
|
|
861
|
+
html += \`
|
|
862
|
+
<div class="form-section">
|
|
863
|
+
|
|
864
|
+
<div class="form-section-title">
|
|
865
|
+
Request Body
|
|
866
|
+
</div>
|
|
867
|
+
\`;
|
|
868
|
+
|
|
869
|
+
ep.fields.forEach((f)=>{
|
|
870
|
+
|
|
193
871
|
html += \`
|
|
194
872
|
<div class="field-row">
|
|
195
|
-
|
|
196
|
-
|
|
873
|
+
|
|
874
|
+
<label class="field-label">
|
|
875
|
+
\${f.label}
|
|
876
|
+
</label>
|
|
877
|
+
|
|
878
|
+
\${makeInputString(
|
|
879
|
+
f.type || 'text',
|
|
880
|
+
'field-' + f.name,
|
|
881
|
+
f.placeholder || '',
|
|
882
|
+
''
|
|
883
|
+
)}
|
|
884
|
+
|
|
197
885
|
</div>
|
|
198
886
|
\`;
|
|
199
887
|
});
|
|
200
|
-
|
|
888
|
+
|
|
889
|
+
html += '</div>';
|
|
201
890
|
}
|
|
202
891
|
|
|
203
892
|
html += \`
|
|
204
893
|
<div class="btn-row">
|
|
205
|
-
|
|
206
|
-
<button
|
|
894
|
+
|
|
895
|
+
<button
|
|
896
|
+
class="btn"
|
|
897
|
+
onclick="sendRequest()"
|
|
898
|
+
>
|
|
899
|
+
Execute Route
|
|
900
|
+
</button>
|
|
901
|
+
|
|
902
|
+
<button
|
|
903
|
+
class="btn btn-secondary"
|
|
904
|
+
onclick="clearResponse()"
|
|
905
|
+
>
|
|
906
|
+
Clear Context
|
|
907
|
+
</button>
|
|
908
|
+
|
|
207
909
|
</div>
|
|
208
910
|
\`;
|
|
209
911
|
|
|
210
912
|
main.innerHTML = html;
|
|
211
913
|
}
|
|
212
914
|
|
|
213
|
-
async function sendRequest()
|
|
214
|
-
|
|
915
|
+
async function sendRequest(){
|
|
916
|
+
|
|
917
|
+
const ep =
|
|
918
|
+
ENDPOINTS[currentEp];
|
|
919
|
+
|
|
215
920
|
let path = ep.path;
|
|
216
921
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
for
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
922
|
+
if(ep.params){
|
|
923
|
+
|
|
924
|
+
for(const p of ep.params){
|
|
925
|
+
|
|
926
|
+
const val =
|
|
927
|
+
document
|
|
928
|
+
.getElementById('param-' + p.name)
|
|
929
|
+
?.value
|
|
930
|
+
.trim();
|
|
931
|
+
|
|
932
|
+
if(!val){
|
|
933
|
+
|
|
934
|
+
showToast(
|
|
935
|
+
'Parameter required: ' + p.label
|
|
936
|
+
);
|
|
937
|
+
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
path =
|
|
942
|
+
path.replace(
|
|
943
|
+
':' + p.name,
|
|
944
|
+
encodeURIComponent(val)
|
|
945
|
+
);
|
|
223
946
|
}
|
|
224
947
|
}
|
|
225
948
|
|
|
226
|
-
const baseUrl =
|
|
949
|
+
const baseUrl =
|
|
950
|
+
document
|
|
951
|
+
.getElementById('base-url')
|
|
952
|
+
.value
|
|
953
|
+
.replace(/[/]+$/,'');
|
|
954
|
+
|
|
227
955
|
const url = baseUrl + path;
|
|
228
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
229
956
|
|
|
230
|
-
const
|
|
231
|
-
|
|
957
|
+
const headers = {
|
|
958
|
+
'Content-Type':'application/json'
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
const jwt =
|
|
962
|
+
document
|
|
963
|
+
.getElementById('jwt-input')
|
|
964
|
+
.value
|
|
965
|
+
.trim();
|
|
966
|
+
|
|
967
|
+
if(jwt){
|
|
968
|
+
headers['Authorization'] =
|
|
969
|
+
'Bearer ' + jwt;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
let body;
|
|
973
|
+
|
|
974
|
+
if(
|
|
975
|
+
ep.fields &&
|
|
976
|
+
ep.fields.length &&
|
|
977
|
+
['POST','PUT','PATCH']
|
|
978
|
+
.includes(ep.method)
|
|
979
|
+
){
|
|
232
980
|
|
|
233
|
-
// FIXED: Dynamically bundles inputs into a background payload object structure seamlessly
|
|
234
|
-
let body = undefined;
|
|
235
|
-
if (ep.fields && ep.fields.length && ['POST', 'PUT', 'PATCH'].includes(ep.method)) {
|
|
236
981
|
const payloadObject = {};
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
982
|
+
|
|
983
|
+
ep.fields.forEach((f)=>{
|
|
984
|
+
|
|
985
|
+
const input =
|
|
986
|
+
document.getElementById(
|
|
987
|
+
'field-' + f.name
|
|
988
|
+
);
|
|
989
|
+
|
|
990
|
+
if(!input) return;
|
|
991
|
+
|
|
992
|
+
let value = input.value;
|
|
993
|
+
|
|
994
|
+
if(f.type === 'number'){
|
|
995
|
+
value =
|
|
996
|
+
value === ''
|
|
997
|
+
? null
|
|
998
|
+
: Number(value);
|
|
247
999
|
}
|
|
248
|
-
|
|
1000
|
+
|
|
1001
|
+
payloadObject[f.name] = value;
|
|
1002
|
+
});
|
|
1003
|
+
|
|
249
1004
|
body = JSON.stringify(payloadObject);
|
|
250
1005
|
}
|
|
251
1006
|
|
|
252
|
-
setResponse(null,
|
|
1007
|
+
setResponse(null,'loading');
|
|
1008
|
+
|
|
253
1009
|
const start = Date.now();
|
|
254
1010
|
|
|
255
|
-
try
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
1011
|
+
try{
|
|
1012
|
+
|
|
1013
|
+
const res =
|
|
1014
|
+
await fetch(url,{
|
|
1015
|
+
method:ep.method,
|
|
1016
|
+
headers,
|
|
1017
|
+
body
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
const ms =
|
|
1021
|
+
Date.now() - start;
|
|
1022
|
+
|
|
1023
|
+
const text =
|
|
1024
|
+
await res.text();
|
|
1025
|
+
|
|
259
1026
|
let json;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
1027
|
+
|
|
1028
|
+
try{
|
|
1029
|
+
json = JSON.parse(text);
|
|
1030
|
+
}catch{
|
|
1031
|
+
json = text;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
setResponse(
|
|
1035
|
+
json,
|
|
1036
|
+
res.ok ? 'ok' : 'err',
|
|
1037
|
+
res.status,
|
|
1038
|
+
ms
|
|
1039
|
+
);
|
|
1040
|
+
|
|
1041
|
+
}catch(err){
|
|
1042
|
+
|
|
1043
|
+
setResponse(
|
|
1044
|
+
{ error: err.message },
|
|
1045
|
+
'err',
|
|
1046
|
+
'FAIL',
|
|
1047
|
+
0
|
|
1048
|
+
);
|
|
264
1049
|
}
|
|
265
1050
|
}
|
|
266
1051
|
|
|
267
|
-
function setResponse(
|
|
268
|
-
|
|
269
|
-
|
|
1052
|
+
function setResponse(
|
|
1053
|
+
data,
|
|
1054
|
+
state,
|
|
1055
|
+
status,
|
|
1056
|
+
ms
|
|
1057
|
+
){
|
|
1058
|
+
|
|
1059
|
+
const badge =
|
|
1060
|
+
document.getElementById(
|
|
1061
|
+
'status-badge'
|
|
1062
|
+
);
|
|
1063
|
+
|
|
1064
|
+
const body =
|
|
1065
|
+
document.getElementById(
|
|
1066
|
+
'response-body'
|
|
1067
|
+
);
|
|
1068
|
+
|
|
1069
|
+
if(state === 'loading'){
|
|
1070
|
+
|
|
1071
|
+
badge.className =
|
|
1072
|
+
'status-badge status-idle';
|
|
270
1073
|
|
|
271
|
-
if (state === 'loading') {
|
|
272
|
-
badge.className = 'status-badge status-idle';
|
|
273
1074
|
badge.textContent = '...';
|
|
274
|
-
|
|
1075
|
+
|
|
1076
|
+
body.innerHTML =
|
|
1077
|
+
'Executing transmission...';
|
|
1078
|
+
|
|
275
1079
|
return;
|
|
276
1080
|
}
|
|
277
1081
|
|
|
278
|
-
badge.className =
|
|
279
|
-
|
|
1082
|
+
badge.className =
|
|
1083
|
+
'status-badge ' +
|
|
1084
|
+
(
|
|
1085
|
+
state === 'ok'
|
|
1086
|
+
? 'status-ok'
|
|
1087
|
+
: 'status-err'
|
|
1088
|
+
);
|
|
1089
|
+
|
|
1090
|
+
badge.textContent =
|
|
1091
|
+
status + ' · ' + ms + 'ms';
|
|
1092
|
+
|
|
280
1093
|
body.className = 'response-body';
|
|
281
|
-
|
|
1094
|
+
|
|
1095
|
+
body.innerHTML =
|
|
1096
|
+
highlightJson(
|
|
1097
|
+
typeof data === 'string'
|
|
1098
|
+
? data
|
|
1099
|
+
: JSON.stringify(data,null,2)
|
|
1100
|
+
);
|
|
282
1101
|
}
|
|
283
1102
|
|
|
284
|
-
function clearResponse()
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
|
|
1103
|
+
function clearResponse(){
|
|
1104
|
+
|
|
1105
|
+
const badge =
|
|
1106
|
+
document.getElementById(
|
|
1107
|
+
'status-badge'
|
|
1108
|
+
);
|
|
1109
|
+
|
|
1110
|
+
const body =
|
|
1111
|
+
document.getElementById(
|
|
1112
|
+
'response-body'
|
|
1113
|
+
);
|
|
1114
|
+
|
|
1115
|
+
badge.className =
|
|
1116
|
+
'status-badge status-idle';
|
|
1117
|
+
|
|
288
1118
|
badge.textContent = '—';
|
|
289
|
-
|
|
290
|
-
body.
|
|
1119
|
+
|
|
1120
|
+
body.className =
|
|
1121
|
+
'response-body empty';
|
|
1122
|
+
|
|
1123
|
+
body.textContent =
|
|
1124
|
+
'Execute a request row to generate feedback data';
|
|
291
1125
|
}
|
|
292
1126
|
|
|
293
|
-
function highlightJson(str)
|
|
1127
|
+
function highlightJson(str){
|
|
1128
|
+
|
|
294
1129
|
return str
|
|
295
|
-
.replace(/&/g,
|
|
296
|
-
.replace(/
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
1130
|
+
.replace(/&/g,'&')
|
|
1131
|
+
.replace(/[<]/g,'<')
|
|
1132
|
+
.replace(/[>]/g,'>')
|
|
1133
|
+
|
|
1134
|
+
.replace(
|
|
1135
|
+
/("(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\"])*"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,
|
|
1136
|
+
|
|
1137
|
+
function(match){
|
|
1138
|
+
|
|
1139
|
+
if(/^"/.test(match)){
|
|
1140
|
+
|
|
1141
|
+
if(/:$/.test(match)){
|
|
1142
|
+
return '<span class="json-key">' + match + '</span>';
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
return '<span class="json-str">' + match + '</span>';
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
return '<span class="json-num">' + match + '</span>';
|
|
300
1149
|
}
|
|
301
|
-
|
|
302
|
-
});
|
|
1150
|
+
);
|
|
303
1151
|
}
|
|
304
1152
|
|
|
305
|
-
function showToast(msg)
|
|
306
|
-
|
|
1153
|
+
function showToast(msg){
|
|
1154
|
+
|
|
1155
|
+
const t =
|
|
1156
|
+
document.getElementById('toast');
|
|
1157
|
+
|
|
307
1158
|
t.textContent = msg;
|
|
1159
|
+
|
|
308
1160
|
t.classList.add('show');
|
|
309
|
-
|
|
1161
|
+
|
|
1162
|
+
setTimeout(()=>{
|
|
1163
|
+
t.classList.remove('show');
|
|
1164
|
+
},2500);
|
|
310
1165
|
}
|
|
311
1166
|
|
|
312
1167
|
buildSidebar();
|
|
313
1168
|
</script>
|
|
1169
|
+
|
|
314
1170
|
</body>
|
|
315
1171
|
</html>
|
|
316
1172
|
`;
|