mockaton 12.7.2 → 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 +3 -7
- package/src/client/ApiConstants.js +1 -4
- package/src/client/Filename.js +20 -20
- package/src/client/app-header.js +6 -6
- package/src/client/app-payload-viewer.js +43 -16
- package/src/client/app-store.js +11 -64
- package/src/client/app-store.test.js +15 -1
- package/src/client/app.css +51 -38
- 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 +65 -181
- package/src/server/Watcher.js +0 -32
- 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/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
|
}
|
|
@@ -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
|
}
|
|
@@ -351,6 +357,7 @@ main {
|
|
|
351
357
|
&:active {
|
|
352
358
|
border-color: var(--colorBorderActive);
|
|
353
359
|
}
|
|
360
|
+
|
|
354
361
|
&::before,
|
|
355
362
|
&::after {
|
|
356
363
|
position: absolute;
|
|
@@ -360,7 +367,7 @@ main {
|
|
|
360
367
|
&::before {
|
|
361
368
|
top: calc(50% + 6px);
|
|
362
369
|
height: 22px;
|
|
363
|
-
border-left:
|
|
370
|
+
border-left: 2px solid var(--colorBg);
|
|
364
371
|
}
|
|
365
372
|
&::after {
|
|
366
373
|
top: calc(50% + 10px);
|
|
@@ -379,10 +386,11 @@ main {
|
|
|
379
386
|
padding-right: 14px;
|
|
380
387
|
padding-left: 16px;
|
|
381
388
|
border-bottom: 1px solid var(--colorBorder);
|
|
382
|
-
background: var(--
|
|
389
|
+
background: var(--colorBgHeader);
|
|
383
390
|
}
|
|
384
391
|
|
|
385
|
-
.GroupByMethod
|
|
392
|
+
.GroupByMethod,
|
|
393
|
+
.ViewSourceCheckbox {
|
|
386
394
|
display: flex;
|
|
387
395
|
align-items: center;
|
|
388
396
|
gap: 6px;
|
|
@@ -399,7 +407,7 @@ main {
|
|
|
399
407
|
text-align-last: center;
|
|
400
408
|
color: var(--colorText);
|
|
401
409
|
font-size: 11px;
|
|
402
|
-
background-color: var(--
|
|
410
|
+
background-color: var(--colorBgHeaderField);
|
|
403
411
|
border-radius: var(--radius);
|
|
404
412
|
}
|
|
405
413
|
}
|
|
@@ -426,13 +434,6 @@ main {
|
|
|
426
434
|
&.canProxy {
|
|
427
435
|
margin-left: 100px;
|
|
428
436
|
}
|
|
429
|
-
&.nonGroupedByMethod {
|
|
430
|
-
margin-left: 118px;
|
|
431
|
-
|
|
432
|
-
&.canProxy {
|
|
433
|
-
margin-left: 146px;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
437
|
}
|
|
437
438
|
|
|
438
439
|
.TableRow {
|
|
@@ -458,7 +459,7 @@ main {
|
|
|
458
459
|
min-width: 38px;
|
|
459
460
|
padding: 4px 0;
|
|
460
461
|
margin-right: 8px;
|
|
461
|
-
color: var(--
|
|
462
|
+
color: var(--colorLabel);
|
|
462
463
|
font-size: 11px;
|
|
463
464
|
text-align: center;
|
|
464
465
|
white-space: nowrap;
|
|
@@ -505,7 +506,7 @@ main {
|
|
|
505
506
|
font-size: 11px;
|
|
506
507
|
}
|
|
507
508
|
&.status4xx {
|
|
508
|
-
background: var(--
|
|
509
|
+
background: var(--colorBg4xx);
|
|
509
510
|
}
|
|
510
511
|
&:disabled {
|
|
511
512
|
padding-right: 4px;
|
|
@@ -514,7 +515,7 @@ main {
|
|
|
514
515
|
appearance: none;
|
|
515
516
|
background: transparent;
|
|
516
517
|
cursor: default;
|
|
517
|
-
color: var(--
|
|
518
|
+
color: var(--colorLabel);
|
|
518
519
|
opacity: 0.8;
|
|
519
520
|
}
|
|
520
521
|
}
|
|
@@ -546,7 +547,7 @@ main {
|
|
|
546
547
|
border-color: var(--colorAccent);
|
|
547
548
|
fill: var(--colorAccent);
|
|
548
549
|
background: var(--colorAccent);
|
|
549
|
-
stroke: var(--
|
|
550
|
+
stroke: var(--colorBg);
|
|
550
551
|
}
|
|
551
552
|
|
|
552
553
|
&:enabled:hover:not(:checked) + .checkboxBody {
|
|
@@ -564,7 +565,7 @@ main {
|
|
|
564
565
|
justify-content: center;
|
|
565
566
|
border: 1px solid var(--colorBorder);
|
|
566
567
|
fill: none;
|
|
567
|
-
stroke: var(--
|
|
568
|
+
stroke: var(--colorLabel);
|
|
568
569
|
stroke-width: 2.5px;
|
|
569
570
|
border-radius: 50%;
|
|
570
571
|
}
|
|
@@ -611,7 +612,7 @@ main {
|
|
|
611
612
|
padding: 4px;
|
|
612
613
|
font-size: 10px;
|
|
613
614
|
font-weight: bold;
|
|
614
|
-
color: var(--
|
|
615
|
+
color: var(--colorLabel);
|
|
615
616
|
}
|
|
616
617
|
}
|
|
617
618
|
|
|
@@ -626,16 +627,28 @@ main {
|
|
|
626
627
|
padding-top: 12px;
|
|
627
628
|
font-family: monospace;
|
|
628
629
|
|
|
630
|
+
&:has(> code > :is(iframe, video)) {
|
|
631
|
+
padding: 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
629
634
|
> code {
|
|
630
635
|
white-space: pre;
|
|
631
636
|
tab-size: 2;
|
|
632
|
-
color: var(--
|
|
637
|
+
color: var(--colorLabel);
|
|
638
|
+
|
|
639
|
+
> video {
|
|
640
|
+
width: 100%;
|
|
641
|
+
}
|
|
642
|
+
> iframe {
|
|
643
|
+
width: 100%;
|
|
644
|
+
height: 100%;
|
|
645
|
+
}
|
|
633
646
|
}
|
|
634
647
|
}
|
|
635
648
|
}
|
|
636
649
|
|
|
637
650
|
.syntaxPunc {
|
|
638
|
-
color: var(--
|
|
651
|
+
color: var(--colorLabel);
|
|
639
652
|
}
|
|
640
653
|
.syntaxKey,
|
|
641
654
|
.syntaxTag {
|
|
@@ -657,7 +670,7 @@ main {
|
|
|
657
670
|
left: -16px;
|
|
658
671
|
width: calc(100% + 32px);
|
|
659
672
|
height: 2px;
|
|
660
|
-
background: var(--
|
|
673
|
+
background: var(--colorBgHeaderField);
|
|
661
674
|
|
|
662
675
|
> div {
|
|
663
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
|
-
}
|