mockaton 12.7.1 → 13.0.0
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 +53 -17
- package/index.d.ts +2 -13
- package/package.json +4 -9
- package/src/client/ApiCommander.js +7 -11
- package/src/client/ApiConstants.js +1 -4
- package/src/client/Filename.js +22 -22
- package/src/client/app-header.js +6 -6
- package/src/client/app-payload-viewer.js +52 -25
- package/src/client/app-store.js +11 -64
- package/src/client/app-store.test.js +15 -1
- package/src/client/app.css +54 -44
- package/src/client/app.js +28 -100
- package/src/client/{app-icons.js → graphics.js} +1 -1
- package/src/client/watcherDev.js +7 -7
- package/src/server/Api.js +4 -38
- package/src/server/MockBroker.js +16 -13
- package/src/server/MockDispatcher.js +18 -4
- package/src/server/Mockaton.js +1 -8
- package/src/server/Mockaton.test.config.js +1 -3
- package/src/server/Mockaton.test.js +98 -194
- package/src/server/ProxyRelay.js +26 -15
- package/src/server/Watcher.js +1 -33
- package/src/server/cli.js +9 -13
- package/src/server/cli.test.js +4 -5
- package/src/server/config.js +0 -7
- package/src/server/mockBrokersCollection.js +11 -13
- package/src/server/utils/mime.js +0 -1
- package/src/server/StaticDispatcher.js +0 -36
- package/src/server/staticCollection.js +0 -56
package/src/client/app.css
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
color-scheme: light dark;
|
|
3
|
-
--
|
|
4
|
-
--
|
|
5
|
-
|
|
6
|
-
--
|
|
7
|
-
--
|
|
3
|
+
--colorBg: light-dark(#fff, #181818);
|
|
4
|
+
--colorBgField: light-dark(#fcfcfc, #2c2c2c);
|
|
5
|
+
|
|
6
|
+
--colorBgHeader: light-dark(#f2f2f3, #141414);
|
|
7
|
+
--colorBgHeaderField: light-dark(#fff, #222);
|
|
8
|
+
|
|
8
9
|
--colorBorder: light-dark(#e0e0e0, #323232);
|
|
9
10
|
--colorBorderActive: light-dark(#c8c8c8, #3c3c3c);
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
--colorLabel: light-dark(#555, #aaa);
|
|
12
|
-
--colorDisabledMockSelector: light-dark(#444, #a9b9b9);
|
|
13
13
|
--colorText: light-dark(#000, #fff);
|
|
14
14
|
|
|
15
15
|
--colorAccent: light-dark(#0059dd, #2495ff);
|
|
16
|
-
--colorHover: light-dark(
|
|
16
|
+
--colorHover: light-dark(#bbe0ff, #062d59);
|
|
17
|
+
|
|
17
18
|
--colorRed: light-dark(#da0f00, #f41606);
|
|
18
19
|
--colorPink: light-dark(#ed206a, #f92672);
|
|
19
20
|
--colorPurple: light-dark(#9b71e8, #ae81ff);
|
|
20
21
|
--colorGreen: light-dark(#388e3c, #a6e22e);
|
|
21
|
-
--
|
|
22
|
+
--colorBg4xx: light-dark(#ffedd1, #68554a);
|
|
22
23
|
|
|
23
24
|
accent-color: var(--colorAccent);
|
|
24
25
|
--radius: 16px;
|
|
@@ -33,7 +34,7 @@ body {
|
|
|
33
34
|
body {
|
|
34
35
|
display: grid;
|
|
35
36
|
grid-template-rows: auto 1fr;
|
|
36
|
-
background: var(--
|
|
37
|
+
background: var(--colorBg);
|
|
37
38
|
color: var(--colorText);
|
|
38
39
|
font-family: system-ui, sans-serif;
|
|
39
40
|
}
|
|
@@ -46,7 +47,7 @@ body {
|
|
|
46
47
|
font-family: inherit;
|
|
47
48
|
font-size: 100%;
|
|
48
49
|
scrollbar-width: thin;
|
|
49
|
-
corner-shape: squircle
|
|
50
|
+
corner-shape: squircle;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
a:focus-visible,
|
|
@@ -88,12 +89,14 @@ select {
|
|
|
88
89
|
|
|
89
90
|
&:enabled {
|
|
90
91
|
border-color: var(--colorBorder);
|
|
91
|
-
background-color: var(--
|
|
92
|
+
background-color: var(--colorBgField);
|
|
93
|
+
|
|
92
94
|
&:hover {
|
|
93
95
|
border-color: var(--colorHover);
|
|
94
96
|
background-color: var(--colorHover);
|
|
95
97
|
}
|
|
96
98
|
}
|
|
99
|
+
|
|
97
100
|
&:disabled {
|
|
98
101
|
cursor: not-allowed;
|
|
99
102
|
opacity: 50%;
|
|
@@ -105,13 +108,13 @@ header {
|
|
|
105
108
|
display: flex;
|
|
106
109
|
flex: 0 0 100%;
|
|
107
110
|
padding: 16px;
|
|
108
|
-
background: var(--
|
|
111
|
+
background: var(--colorBgHeader);
|
|
109
112
|
|
|
110
113
|
.Logo {
|
|
111
114
|
align-self: end;
|
|
112
115
|
margin-right: 22px;
|
|
113
116
|
margin-bottom: 3px;
|
|
114
|
-
opacity:
|
|
117
|
+
opacity: 94%;
|
|
115
118
|
transition: opacity 240ms ease-in-out;
|
|
116
119
|
|
|
117
120
|
&:hover {
|
|
@@ -186,7 +189,7 @@ header {
|
|
|
186
189
|
align-self: end;
|
|
187
190
|
margin-left: auto;
|
|
188
191
|
border-radius: 50%;
|
|
189
|
-
fill: var(--
|
|
192
|
+
fill: var(--colorLabel);
|
|
190
193
|
|
|
191
194
|
&:hover {
|
|
192
195
|
fill: var(--colorAccent);
|
|
@@ -227,7 +230,7 @@ header {
|
|
|
227
230
|
margin-top: 2px;
|
|
228
231
|
color: var(--colorText);
|
|
229
232
|
font-size: 11px;
|
|
230
|
-
background-color: var(--
|
|
233
|
+
background-color: var(--colorBgHeaderField);
|
|
231
234
|
border-radius: var(--radius);
|
|
232
235
|
}
|
|
233
236
|
|
|
@@ -256,6 +259,11 @@ header {
|
|
|
256
259
|
|
|
257
260
|
&.GlobalDelayJitter {
|
|
258
261
|
width: 80px;
|
|
262
|
+
|
|
263
|
+
&:focus-within {
|
|
264
|
+
z-index: 100;
|
|
265
|
+
}
|
|
266
|
+
|
|
259
267
|
span {
|
|
260
268
|
margin-left: 4px;
|
|
261
269
|
}
|
|
@@ -264,9 +272,6 @@ header {
|
|
|
264
272
|
border-bottom-left-radius: 0;
|
|
265
273
|
border-top-left-radius: 0;
|
|
266
274
|
}
|
|
267
|
-
&:focus-within {
|
|
268
|
-
z-index: 100;
|
|
269
|
-
}
|
|
270
275
|
}
|
|
271
276
|
|
|
272
277
|
&.CookieSelector {
|
|
@@ -294,6 +299,7 @@ header {
|
|
|
294
299
|
input:enabled + .checkboxBody {
|
|
295
300
|
cursor: pointer;
|
|
296
301
|
}
|
|
302
|
+
|
|
297
303
|
input:disabled {
|
|
298
304
|
cursor: not-allowed;
|
|
299
305
|
}
|
|
@@ -306,9 +312,6 @@ header {
|
|
|
306
312
|
}
|
|
307
313
|
|
|
308
314
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
315
|
main {
|
|
313
316
|
display: flex;
|
|
314
317
|
min-width: 0;
|
|
@@ -354,6 +357,7 @@ main {
|
|
|
354
357
|
&:active {
|
|
355
358
|
border-color: var(--colorBorderActive);
|
|
356
359
|
}
|
|
360
|
+
|
|
357
361
|
&::before,
|
|
358
362
|
&::after {
|
|
359
363
|
position: absolute;
|
|
@@ -363,7 +367,7 @@ main {
|
|
|
363
367
|
&::before {
|
|
364
368
|
top: calc(50% + 6px);
|
|
365
369
|
height: 22px;
|
|
366
|
-
border-left:
|
|
370
|
+
border-left: 2px solid var(--colorBg);
|
|
367
371
|
}
|
|
368
372
|
&::after {
|
|
369
373
|
top: calc(50% + 10px);
|
|
@@ -382,10 +386,11 @@ main {
|
|
|
382
386
|
padding-right: 14px;
|
|
383
387
|
padding-left: 16px;
|
|
384
388
|
border-bottom: 1px solid var(--colorBorder);
|
|
385
|
-
background: var(--
|
|
389
|
+
background: var(--colorBgHeader);
|
|
386
390
|
}
|
|
387
391
|
|
|
388
|
-
.GroupByMethod
|
|
392
|
+
.GroupByMethod,
|
|
393
|
+
.ViewSourceCheckbox {
|
|
389
394
|
display: flex;
|
|
390
395
|
align-items: center;
|
|
391
396
|
gap: 6px;
|
|
@@ -402,7 +407,7 @@ main {
|
|
|
402
407
|
text-align-last: center;
|
|
403
408
|
color: var(--colorText);
|
|
404
409
|
font-size: 11px;
|
|
405
|
-
background-color: var(--
|
|
410
|
+
background-color: var(--colorBgHeaderField);
|
|
406
411
|
border-radius: var(--radius);
|
|
407
412
|
}
|
|
408
413
|
}
|
|
@@ -423,19 +428,12 @@ main {
|
|
|
423
428
|
text-align: left;
|
|
424
429
|
|
|
425
430
|
&:first-of-type {
|
|
426
|
-
border-top: 0
|
|
431
|
+
border-top: 0;
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
&.canProxy {
|
|
430
435
|
margin-left: 100px;
|
|
431
436
|
}
|
|
432
|
-
&.nonGroupedByMethod {
|
|
433
|
-
margin-left: 118px;
|
|
434
|
-
|
|
435
|
-
&.canProxy {
|
|
436
|
-
margin-left: 146px;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
437
|
}
|
|
440
438
|
|
|
441
439
|
.TableRow {
|
|
@@ -461,7 +459,7 @@ main {
|
|
|
461
459
|
min-width: 38px;
|
|
462
460
|
padding: 4px 0;
|
|
463
461
|
margin-right: 8px;
|
|
464
|
-
color: var(--
|
|
462
|
+
color: var(--colorLabel);
|
|
465
463
|
font-size: 11px;
|
|
466
464
|
text-align: center;
|
|
467
465
|
white-space: nowrap;
|
|
@@ -508,7 +506,7 @@ main {
|
|
|
508
506
|
font-size: 11px;
|
|
509
507
|
}
|
|
510
508
|
&.status4xx {
|
|
511
|
-
background: var(--
|
|
509
|
+
background: var(--colorBg4xx);
|
|
512
510
|
}
|
|
513
511
|
&:disabled {
|
|
514
512
|
padding-right: 4px;
|
|
@@ -517,7 +515,7 @@ main {
|
|
|
517
515
|
appearance: none;
|
|
518
516
|
background: transparent;
|
|
519
517
|
cursor: default;
|
|
520
|
-
color: var(--
|
|
518
|
+
color: var(--colorLabel);
|
|
521
519
|
opacity: 0.8;
|
|
522
520
|
}
|
|
523
521
|
}
|
|
@@ -536,7 +534,7 @@ main {
|
|
|
536
534
|
&:focus-visible {
|
|
537
535
|
outline: 0;
|
|
538
536
|
& + .checkboxBody {
|
|
539
|
-
outline: 2px solid var(--colorAccent)
|
|
537
|
+
outline: 2px solid var(--colorAccent);
|
|
540
538
|
}
|
|
541
539
|
}
|
|
542
540
|
|
|
@@ -549,7 +547,7 @@ main {
|
|
|
549
547
|
border-color: var(--colorAccent);
|
|
550
548
|
fill: var(--colorAccent);
|
|
551
549
|
background: var(--colorAccent);
|
|
552
|
-
stroke: var(--
|
|
550
|
+
stroke: var(--colorBg);
|
|
553
551
|
}
|
|
554
552
|
|
|
555
553
|
&:enabled:hover:not(:checked) + .checkboxBody {
|
|
@@ -567,7 +565,7 @@ main {
|
|
|
567
565
|
justify-content: center;
|
|
568
566
|
border: 1px solid var(--colorBorder);
|
|
569
567
|
fill: none;
|
|
570
|
-
stroke: var(--
|
|
568
|
+
stroke: var(--colorLabel);
|
|
571
569
|
stroke-width: 2.5px;
|
|
572
570
|
border-radius: 50%;
|
|
573
571
|
}
|
|
@@ -614,7 +612,7 @@ main {
|
|
|
614
612
|
padding: 4px;
|
|
615
613
|
font-size: 10px;
|
|
616
614
|
font-weight: bold;
|
|
617
|
-
color: var(--
|
|
615
|
+
color: var(--colorLabel);
|
|
618
616
|
}
|
|
619
617
|
}
|
|
620
618
|
|
|
@@ -629,16 +627,28 @@ main {
|
|
|
629
627
|
padding-top: 12px;
|
|
630
628
|
font-family: monospace;
|
|
631
629
|
|
|
630
|
+
&:has(> code > :is(iframe, video)) {
|
|
631
|
+
padding: 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
632
634
|
> code {
|
|
633
635
|
white-space: pre;
|
|
634
636
|
tab-size: 2;
|
|
635
|
-
color: var(--
|
|
637
|
+
color: var(--colorLabel);
|
|
638
|
+
|
|
639
|
+
> video {
|
|
640
|
+
width: 100%;
|
|
641
|
+
}
|
|
642
|
+
> iframe {
|
|
643
|
+
width: 100%;
|
|
644
|
+
height: 100%;
|
|
645
|
+
}
|
|
636
646
|
}
|
|
637
647
|
}
|
|
638
648
|
}
|
|
639
649
|
|
|
640
650
|
.syntaxPunc {
|
|
641
|
-
color: var(--
|
|
651
|
+
color: var(--colorLabel);
|
|
642
652
|
}
|
|
643
653
|
.syntaxKey,
|
|
644
654
|
.syntaxTag {
|
|
@@ -660,7 +670,7 @@ main {
|
|
|
660
670
|
left: -16px;
|
|
661
671
|
width: calc(100% + 32px);
|
|
662
672
|
height: 2px;
|
|
663
|
-
background: var(--
|
|
673
|
+
background: var(--colorBgHeaderField);
|
|
664
674
|
|
|
665
675
|
> div {
|
|
666
676
|
position: absolute;
|
package/src/client/app.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createElement as r,
|
|
3
|
-
t, classNames, restoreFocus, Fragment, defineClassNames
|
|
4
|
-
} from './dom-utils.js'
|
|
1
|
+
import { createElement as r, t, classNames, restoreFocus, Fragment, defineClassNames } from './dom-utils.js'
|
|
5
2
|
|
|
6
3
|
import { store } from './app-store.js'
|
|
7
4
|
import { API } from './ApiConstants.js'
|
|
8
5
|
import { Header } from './app-header.js'
|
|
9
|
-
import { TimerIcon, CloudIcon } from './
|
|
6
|
+
import { TimerIcon, CloudIcon } from './graphics.js'
|
|
10
7
|
import { PayloadViewer, previewMock } from './app-payload-viewer.js'
|
|
11
8
|
|
|
12
9
|
import CSS from './app.css' with { type: 'css' }
|
|
@@ -48,9 +45,7 @@ function Main() {
|
|
|
48
45
|
r('div', { className: CSS.SubToolbar },
|
|
49
46
|
GroupByMethod(),
|
|
50
47
|
BulkSelector()),
|
|
51
|
-
r('div', { className: CSS.Table },
|
|
52
|
-
MockList(),
|
|
53
|
-
StaticFilesList())),
|
|
48
|
+
r('div', { className: CSS.Table }, MockList())),
|
|
54
49
|
r('div', { className: CSS.rightSide },
|
|
55
50
|
Resizer(leftSideRef),
|
|
56
51
|
PayloadViewer())))
|
|
@@ -82,8 +77,8 @@ function BulkSelector() {
|
|
|
82
77
|
r('label', { className: CSS.BulkSelector },
|
|
83
78
|
r('span', null, t`Bulk Select`),
|
|
84
79
|
r('select', {
|
|
85
|
-
autocomplete: 'off',
|
|
86
80
|
disabled,
|
|
81
|
+
autocomplete: 'off',
|
|
87
82
|
title: disabled
|
|
88
83
|
? t`No mock files have comments which are anything within parentheses on the filename.`
|
|
89
84
|
: undefined,
|
|
@@ -101,14 +96,11 @@ function MockList() {
|
|
|
101
96
|
return r('div', null, t`No mocks found`)
|
|
102
97
|
|
|
103
98
|
if (store.groupByMethod)
|
|
104
|
-
return Object.keys(store.brokersByMethod).map(method =>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
store.canProxy && CSS.canProxy)
|
|
110
|
-
}, method),
|
|
111
|
-
store.brokersAsRowsByMethod(method).map(Row)))
|
|
99
|
+
return Object.keys(store.brokersByMethod).map(method => Fragment(
|
|
100
|
+
r('div', {
|
|
101
|
+
className: classNames(CSS.TableHeading, store.canProxy && CSS.canProxy)
|
|
102
|
+
}, method),
|
|
103
|
+
store.brokersAsRowsByMethod(method).map(Row)))
|
|
112
104
|
|
|
113
105
|
return store.brokersAsRowsByMethod('*').map(Row)
|
|
114
106
|
}
|
|
@@ -122,9 +114,7 @@ function Row(row, i) {
|
|
|
122
114
|
return (
|
|
123
115
|
r('div', {
|
|
124
116
|
key: row.key,
|
|
125
|
-
className: classNames(
|
|
126
|
-
CSS.TableRow,
|
|
127
|
-
mounted && row.isNew && CSS.animIn)
|
|
117
|
+
className: classNames(CSS.TableRow, mounted && row.isNew && CSS.animIn)
|
|
128
118
|
},
|
|
129
119
|
store.canProxy && ProxyToggler(method, urlMask, row.proxied),
|
|
130
120
|
|
|
@@ -136,12 +126,12 @@ function Row(row, i) {
|
|
|
136
126
|
}),
|
|
137
127
|
|
|
138
128
|
StatusCodeToggler({
|
|
139
|
-
title: t`Internal Server Error`,
|
|
140
|
-
body: t`500`,
|
|
141
|
-
disabled: row.opts.length === 1 && row.status === 500,
|
|
142
|
-
checked: !row.proxied && row.status === 500,
|
|
129
|
+
title: row.isStatic ? t`Not Found` : t`Internal Server Error`,
|
|
130
|
+
body: row.isStatic ? t`404` : t`500`,
|
|
131
|
+
disabled: row.opts.length === 1 && (row.isStatic ? row.status === 404 : row.status === 500),
|
|
132
|
+
checked: !row.proxied && (row.isStatic ? row.status === 404 : row.status === 500),
|
|
143
133
|
commit() {
|
|
144
|
-
store.
|
|
134
|
+
store.toggleStatus(row.isStatic ? 404 : 500, method, urlMask)
|
|
145
135
|
}
|
|
146
136
|
}),
|
|
147
137
|
|
|
@@ -201,9 +191,7 @@ function PreviewLink(method, urlMask, urlMaskDittoed, autofocus) {
|
|
|
201
191
|
const [ditto, tail] = urlMaskDittoed
|
|
202
192
|
return (
|
|
203
193
|
r('a', {
|
|
204
|
-
className: classNames(
|
|
205
|
-
CSS.PreviewLink,
|
|
206
|
-
isChosen && CSS.chosen),
|
|
194
|
+
className: classNames(CSS.PreviewLink, isChosen && CSS.chosen),
|
|
207
195
|
href: urlMask,
|
|
208
196
|
autofocus,
|
|
209
197
|
onClick
|
|
@@ -241,76 +229,16 @@ function ProxyToggler(method, urlMask, checked) {
|
|
|
241
229
|
return ClickDragToggler({
|
|
242
230
|
className: CSS.ProxyToggler,
|
|
243
231
|
title: t`Proxy Toggler`,
|
|
232
|
+
body: CloudIcon(),
|
|
244
233
|
checked,
|
|
245
234
|
commit(checked) {
|
|
246
235
|
store.setProxied(method, urlMask, checked)
|
|
247
|
-
}
|
|
248
|
-
body: CloudIcon()
|
|
236
|
+
}
|
|
249
237
|
})
|
|
250
238
|
}
|
|
251
239
|
|
|
252
240
|
|
|
253
241
|
|
|
254
|
-
/** # StaticFilesList */
|
|
255
|
-
|
|
256
|
-
function StaticFilesList() {
|
|
257
|
-
const rows = store.staticBrokersAsRows()
|
|
258
|
-
return !rows.length
|
|
259
|
-
? null
|
|
260
|
-
: Fragment(
|
|
261
|
-
r('div', {
|
|
262
|
-
className: classNames(CSS.TableHeading,
|
|
263
|
-
store.canProxy && CSS.canProxy,
|
|
264
|
-
!store.groupByMethod && CSS.nonGroupedByMethod),
|
|
265
|
-
},
|
|
266
|
-
store.groupByMethod
|
|
267
|
-
? t`Static GET`
|
|
268
|
-
: t`Static`),
|
|
269
|
-
rows.map(StaticRow))
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/** @param {StaticBrokerRowModel} row */
|
|
273
|
-
function StaticRow(row) {
|
|
274
|
-
const { groupByMethod } = store
|
|
275
|
-
const [ditto, tail] = row.urlMaskDittoed
|
|
276
|
-
return (
|
|
277
|
-
r('div', {
|
|
278
|
-
key: row.key,
|
|
279
|
-
className: classNames(
|
|
280
|
-
CSS.TableRow,
|
|
281
|
-
mounted && row.isNew && CSS.animIn)
|
|
282
|
-
},
|
|
283
|
-
|
|
284
|
-
DelayToggler({
|
|
285
|
-
optClassName: store.canProxy && CSS.canProxy,
|
|
286
|
-
checked: row.delayed,
|
|
287
|
-
commit(checked) {
|
|
288
|
-
store.setDelayedStatic(row.urlMask, checked)
|
|
289
|
-
}
|
|
290
|
-
}),
|
|
291
|
-
|
|
292
|
-
StatusCodeToggler({
|
|
293
|
-
title: t`Not Found`,
|
|
294
|
-
body: t`404`,
|
|
295
|
-
checked: row.status === 404,
|
|
296
|
-
commit(checked) {
|
|
297
|
-
store.setStaticRouteStatus(row.urlMask, checked
|
|
298
|
-
? 404
|
|
299
|
-
: 200)
|
|
300
|
-
}
|
|
301
|
-
}),
|
|
302
|
-
|
|
303
|
-
!groupByMethod && r('span', { className: CSS.Method }, 'GET'),
|
|
304
|
-
|
|
305
|
-
r('a', {
|
|
306
|
-
href: row.urlMask,
|
|
307
|
-
target: '_blank',
|
|
308
|
-
className: CSS.PreviewLink,
|
|
309
|
-
}, ditto
|
|
310
|
-
? [r('span', { className: CSS.dittoDir }, ditto), tail]
|
|
311
|
-
: tail)))
|
|
312
|
-
}
|
|
313
|
-
|
|
314
242
|
function StatusCodeToggler({ title, body, commit, checked, disabled }) {
|
|
315
243
|
return ClickDragToggler({
|
|
316
244
|
title,
|
|
@@ -322,12 +250,12 @@ function StatusCodeToggler({ title, body, commit, checked, disabled }) {
|
|
|
322
250
|
})
|
|
323
251
|
}
|
|
324
252
|
|
|
325
|
-
function DelayToggler({ checked, commit,
|
|
253
|
+
function DelayToggler({ checked, commit, className }) {
|
|
326
254
|
return ClickDragToggler({
|
|
327
|
-
canClickDrag: true,
|
|
328
255
|
checked,
|
|
329
256
|
commit,
|
|
330
|
-
className: classNames(CSS.DelayToggler,
|
|
257
|
+
className: classNames(CSS.DelayToggler, className),
|
|
258
|
+
canClickDrag: true,
|
|
331
259
|
title: t`Delay`,
|
|
332
260
|
body: TimerIcon()
|
|
333
261
|
})
|
|
@@ -480,7 +408,7 @@ ErrorToast.close = () => {
|
|
|
480
408
|
/** The version increments when a mock file is added, removed, or renamed. */
|
|
481
409
|
function onRealTimeUpdate(onUpdate) {
|
|
482
410
|
let oldVersion = -1
|
|
483
|
-
let
|
|
411
|
+
let conn = null
|
|
484
412
|
let timer = null
|
|
485
413
|
|
|
486
414
|
connect()
|
|
@@ -493,12 +421,12 @@ function onRealTimeUpdate(onUpdate) {
|
|
|
493
421
|
window.addEventListener('beforeunload', teardown)
|
|
494
422
|
|
|
495
423
|
function connect() {
|
|
496
|
-
if (
|
|
424
|
+
if (conn) return
|
|
497
425
|
|
|
498
426
|
clearTimeout(timer)
|
|
499
|
-
|
|
427
|
+
conn = new EventSource(API.syncVersion)
|
|
500
428
|
|
|
501
|
-
|
|
429
|
+
conn.onmessage = function (event) {
|
|
502
430
|
if (ErrorToast.isOffline)
|
|
503
431
|
ErrorToast.close()
|
|
504
432
|
|
|
@@ -509,7 +437,7 @@ function onRealTimeUpdate(onUpdate) {
|
|
|
509
437
|
}
|
|
510
438
|
}
|
|
511
439
|
|
|
512
|
-
|
|
440
|
+
conn.onerror = function () {
|
|
513
441
|
teardown()
|
|
514
442
|
timer = setTimeout(connect, 3000)
|
|
515
443
|
}
|
|
@@ -517,8 +445,8 @@ function onRealTimeUpdate(onUpdate) {
|
|
|
517
445
|
|
|
518
446
|
function teardown() {
|
|
519
447
|
clearTimeout(timer)
|
|
520
|
-
|
|
521
|
-
|
|
448
|
+
conn?.close()
|
|
449
|
+
conn = null
|
|
522
450
|
}
|
|
523
451
|
}
|
|
524
452
|
|
|
@@ -5,7 +5,7 @@ export function Logo() {
|
|
|
5
5
|
return (
|
|
6
6
|
s('svg', { viewBox: '0 0 556 100' },
|
|
7
7
|
s('path', { d: 'm13.75 1.8789c-5.9487 0.19352-10.865 4.5652-11.082 11.686v81.445c-1e-7 2.216 1.784 4 4 4h4.793c2.216 0 4-1.784 4-4v-64.982c0.02794-3.4488 3.0988-3.5551 4.2031-1.1562l16.615 59.059c1.4393 5.3711 5.1083 7.9633 8.7656 7.9473 3.6573 0.01603 7.3263-2.5762 8.7656-7.9473l16.615-59.059c1.1043-2.3989 4.1752-2.2925 4.2031 1.1562v64.982c0 2.216 1.784 4 4 4h4.793c2.216 0 4-1.784 4-4v-81.445c-0.17732-7.0807-5.1334-11.492-11.082-11.686-5.9487-0.19352-12.652 3.8309-15.609 13.619l-15.686 57.334-15.686-57.334c-2.9569-9.7882-9.6607-13.813-15.609-13.619zm239.19 0.074219c-2.216 0-4 1.784-4 4v89.057c0 2.216 1.784 4 4 4h4.793c2.216 0 3.9868-1.784 4-4l0.10644-17.94c0.0734-0.07237 12.175-13.75 12.175-13.75 5.6772 11.091 11.404 22.158 17.113 33.232 1.0168 1.9689 3.4217 2.7356 5.3906 1.7188l4.2578-2.1992c1.9689-1.0168 2.7356-3.4217 1.7188-5.3906-6.4691-12.585-12.958-25.16-19.442-37.738l17.223-19.771c1.4555-1.671 1.2803-4.189-0.39062-5.6445l-3.6133-3.1465c-0.73105-0.63679-1.6224-0.96212-2.5176-0.98633-1.151-0.03113-2.3063 0.43508-3.125 1.375l-28.896 33.174v-51.99c0-2.216-1.784-4-4-4zm-58.255 23.316c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312l-0.125-7.8457c0-2.216-1.784-4-4-4h-4.6524c-2.216 0-4 1.784-4 4l3e-3 6.7888c3e-3 3.8063-1.5601 9.3694-8.4716 9.3694h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.6937 0 8.3697 5.2207 8.4687 11.828v2.2207c0 2.216 1.784 4 4 4h4.6524c2.216 0 4-1.784 4-4l0.125-5.7363c0-10.699-8.6117-19.312-19.311-19.312zm-72.182 0c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312v-34.535c0-10.699-8.6117-19.312-19.311-19.312zm1.9356 11h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v26.209c0 6.9115-1.5631 12.475-8.4746 12.475h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477z' }),
|
|
8
|
-
s('path', { opacity: 0.
|
|
8
|
+
s('path', { opacity: 0.6, d: 'm331.9 25.27c-10.699 0-19.312 8.6137-19.312 19.312v4.3682c0 2.216 1.784 4 4 4h4.7715c2.216 0 4-1.784 4-4v-0.20414c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v7.0148h-28.059c-10.699 0-19.312 8.6117-19.312 19.311v4.0477c0 10.699 8.6137 19.313 19.312 19.312h17.812c2.216-1e-6 4-1.784 4-4v-4.7715c0-2.216-1.784-4-4-4h-13.648c-6.9115-2e-5 -12.477-1.5651-12.477-8.5649 0-6.9998 5.5651-8.5629 12.477-8.5629h23.895v25.897c0 2.216 1.784 4 4 4h4.7715c2.216-1e-6 4-1.784 4-4v-49.848c0-10.699-8.6117-19.312-19.311-19.312z' }),
|
|
9
9
|
s('path', { d: 'm392.75 1.373c-2.216 0-4 1.784-4 4v18.043h-5.3086c-2.216 0-4 1.784-4 4v4.793c0 2.216 1.784 4 4 4h5.3086v51.398c0 6.1465 3.7064 10.823 9.232 10.823h16.531c2.216 0 4-1.784 4-4v-4.793c0-2.216-1.784-4-4-4h-12.97v-49.428h9.8711c2.216 0 4-1.784 4-4v-4.793c0-2.216-1.784-4-4-4h-9.8711v-18.043c0-2.216-1.784-4-4-4zm122.96 23.896c-10.699 0-19.312 8.6137-19.312 19.312v49.812c0 2.216 1.784 4 4 4h4.7715c2.216 0 4-1.784 4-4v-45.648c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v45.684c0 2.216 1.784 4 4 4h4.7715c2.216-1e-6 4-1.784 4-4v-49.848c0-10.699-8.6117-19.312-19.311-19.312zm-69.999 0c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312v-34.535c0-10.699-8.6117-19.312-19.311-19.312zm1.9356 11h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v26.209c0 6.9115-1.5631 12.475-8.4746 12.475h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477z' })))
|
|
10
10
|
}
|
|
11
11
|
|
package/src/client/watcherDev.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { API } from './ApiConstants.js'
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
let
|
|
4
|
+
let conn = null
|
|
5
5
|
let timer = null
|
|
6
6
|
|
|
7
7
|
window.addEventListener('beforeunload', teardown)
|
|
8
8
|
connect()
|
|
9
9
|
function connect() {
|
|
10
|
-
if (
|
|
10
|
+
if (conn) return
|
|
11
11
|
|
|
12
12
|
clearTimeout(timer)
|
|
13
|
-
|
|
13
|
+
conn = new EventSource(API.watchHotReload)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
conn.onmessage = function (event) {
|
|
16
16
|
const file = event.data
|
|
17
17
|
if (file.endsWith('.css'))
|
|
18
18
|
hotReloadCSS(file)
|
|
@@ -20,7 +20,7 @@ function connect() {
|
|
|
20
20
|
location.reload()
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
conn.onerror = function () {
|
|
24
24
|
console.error('hot reload')
|
|
25
25
|
teardown()
|
|
26
26
|
timer = setTimeout(connect, 3000)
|
|
@@ -29,8 +29,8 @@ function connect() {
|
|
|
29
29
|
|
|
30
30
|
function teardown() {
|
|
31
31
|
clearTimeout(timer)
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
conn?.close()
|
|
33
|
+
conn = null
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
async function hotReloadCSS(file) {
|
package/src/server/Api.js
CHANGED
|
@@ -20,7 +20,6 @@ import { IndexHtml, CSP } from '../client/IndexHtml.js'
|
|
|
20
20
|
import { cookie } from './cookie.js'
|
|
21
21
|
import { config, ConfigValidator } from './config.js'
|
|
22
22
|
|
|
23
|
-
import * as staticCollection from './staticCollection.js'
|
|
24
23
|
import * as mockBrokersCollection from './mockBrokersCollection.js'
|
|
25
24
|
|
|
26
25
|
|
|
@@ -51,10 +50,7 @@ export const apiPatchReqs = new Map([
|
|
|
51
50
|
[API.delay, setRouteIsDelayed],
|
|
52
51
|
[API.select, selectMock],
|
|
53
52
|
[API.proxied, setRouteIsProxied],
|
|
54
|
-
[API.
|
|
55
|
-
|
|
56
|
-
[API.delayStatic, setStaticRouteIsDelayed],
|
|
57
|
-
[API.staticStatus, setStaticRouteStatusCode],
|
|
53
|
+
[API.toggleStatus, toggleRouteStatus],
|
|
58
54
|
|
|
59
55
|
[API.watchMocks, setWatchMocks]
|
|
60
56
|
])
|
|
@@ -78,7 +74,6 @@ function getState(_, response) {
|
|
|
78
74
|
comments: mockBrokersCollection.extractAllComments(),
|
|
79
75
|
|
|
80
76
|
brokersByMethod: mockBrokersCollection.all(),
|
|
81
|
-
staticBrokers: staticCollection.all(),
|
|
82
77
|
|
|
83
78
|
delay: config.delay,
|
|
84
79
|
delayJitter: config.delayJitter,
|
|
@@ -94,7 +89,6 @@ function getState(_, response) {
|
|
|
94
89
|
|
|
95
90
|
function reset(_, response) {
|
|
96
91
|
mockBrokersCollection.init()
|
|
97
|
-
staticCollection.init()
|
|
98
92
|
response.ok()
|
|
99
93
|
}
|
|
100
94
|
|
|
@@ -205,14 +199,14 @@ async function selectMock(req, response) {
|
|
|
205
199
|
}
|
|
206
200
|
|
|
207
201
|
|
|
208
|
-
async function
|
|
209
|
-
const [method, urlMask] = await req.json()
|
|
202
|
+
async function toggleRouteStatus(req, response) {
|
|
203
|
+
const [status, method, urlMask] = await req.json()
|
|
210
204
|
|
|
211
205
|
const broker = mockBrokersCollection.brokerByRoute(method, urlMask)
|
|
212
206
|
if (!broker)
|
|
213
207
|
response.unprocessable(`Route does not exist: ${method} ${urlMask}`)
|
|
214
208
|
else {
|
|
215
|
-
broker.
|
|
209
|
+
broker.toggleStatus(status)
|
|
216
210
|
response.json(broker)
|
|
217
211
|
}
|
|
218
212
|
}
|
|
@@ -251,31 +245,3 @@ async function setRouteIsProxied(req, response) {
|
|
|
251
245
|
|
|
252
246
|
|
|
253
247
|
|
|
254
|
-
async function setStaticRouteStatusCode(req, response) {
|
|
255
|
-
const [route, status] = await req.json()
|
|
256
|
-
|
|
257
|
-
const broker = staticCollection.brokerByRoute(route)
|
|
258
|
-
if (!broker)
|
|
259
|
-
response.unprocessable(`Static route does not exist: ${route}`)
|
|
260
|
-
else if (!(status === 200 || status === 404))
|
|
261
|
-
response.unprocessable(`Expected 200 or 404 status code`)
|
|
262
|
-
else {
|
|
263
|
-
broker.setStatus(status)
|
|
264
|
-
response.ok()
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
async function setStaticRouteIsDelayed(req, response) {
|
|
270
|
-
const [route, delayed] = await req.json()
|
|
271
|
-
|
|
272
|
-
const broker = staticCollection.brokerByRoute(route)
|
|
273
|
-
if (!broker)
|
|
274
|
-
response.unprocessable(`Static route does not exist: ${route}`)
|
|
275
|
-
else if (typeof delayed !== 'boolean')
|
|
276
|
-
response.unprocessable(`Expected boolean for "delayed"`)
|
|
277
|
-
else {
|
|
278
|
-
broker.setDelayed(delayed)
|
|
279
|
-
response.ok()
|
|
280
|
-
}
|
|
281
|
-
}
|