mockaton 8.7.3 → 8.7.4
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/package.json +1 -1
- package/src/Dashboard.js +61 -65
- package/src/utils/http-cors.test.js +1 -1
package/package.json
CHANGED
package/src/Dashboard.js
CHANGED
|
@@ -45,8 +45,6 @@ const CSS = {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const r = createElement
|
|
48
|
-
const refPayloadViewer = useRef()
|
|
49
|
-
const refPayloadViewerFileTitle = useRef()
|
|
50
48
|
|
|
51
49
|
const mockaton = new Commander(window.location.origin)
|
|
52
50
|
|
|
@@ -59,10 +57,7 @@ function init() {
|
|
|
59
57
|
mockaton.getProxyFallback(),
|
|
60
58
|
mockaton.listStaticFiles()
|
|
61
59
|
].map(api => api.then(response => response.ok && response.json())))
|
|
62
|
-
.then(data =>
|
|
63
|
-
empty(document.body)
|
|
64
|
-
document.body.append(...App(data))
|
|
65
|
-
})
|
|
60
|
+
.then(data => document.body.replaceChildren(...App(data)))
|
|
66
61
|
.catch(onError)
|
|
67
62
|
}
|
|
68
63
|
init()
|
|
@@ -118,9 +113,10 @@ function CookieSelector({ cookies }) {
|
|
|
118
113
|
function BulkSelector({ comments }) {
|
|
119
114
|
// UX wise this should be a menu instead of this `select`.
|
|
120
115
|
// But this way is easier to implement, with a few hacks.
|
|
116
|
+
const firstOption = Strings.pick
|
|
121
117
|
function onChange() {
|
|
122
118
|
const value = this.value
|
|
123
|
-
this.value =
|
|
119
|
+
this.value = firstOption // Hack
|
|
124
120
|
mockaton.bulkSelectByComment(value)
|
|
125
121
|
.then(init)
|
|
126
122
|
.catch(onError)
|
|
@@ -128,7 +124,7 @@ function BulkSelector({ comments }) {
|
|
|
128
124
|
const disabled = !comments.length
|
|
129
125
|
const list = disabled
|
|
130
126
|
? []
|
|
131
|
-
: [
|
|
127
|
+
: [firstOption].concat(comments)
|
|
132
128
|
return (
|
|
133
129
|
r('label', { className: CSS.Field },
|
|
134
130
|
r('span', null, Strings.bulk_select_by_comment),
|
|
@@ -144,14 +140,14 @@ function BulkSelector({ comments }) {
|
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
function ProxyFallbackField({ fallbackAddress = '', collectProxied }) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (!
|
|
152
|
-
|
|
143
|
+
function onChange() {
|
|
144
|
+
const saveCheckbox = this.closest(`.${CSS.FallbackBackend}`).querySelector('[type=checkbox]')
|
|
145
|
+
saveCheckbox.disabled = !this.validity.valid || !this.value.trim()
|
|
146
|
+
|
|
147
|
+
if (!this.validity.valid)
|
|
148
|
+
this.reportValidity()
|
|
153
149
|
else
|
|
154
|
-
mockaton.setProxyFallback(
|
|
150
|
+
mockaton.setProxyFallback(this.value.trim()).catch(onError)
|
|
155
151
|
}
|
|
156
152
|
return (
|
|
157
153
|
r('div', { className: cssClass(CSS.Field, CSS.FallbackBackend) },
|
|
@@ -166,20 +162,17 @@ function ProxyFallbackField({ fallbackAddress = '', collectProxied }) {
|
|
|
166
162
|
})),
|
|
167
163
|
r(SaveProxiedCheckbox, {
|
|
168
164
|
collectProxied,
|
|
169
|
-
disabled: !fallbackAddress
|
|
170
|
-
ref: refSaveProxiedCheckbox
|
|
165
|
+
disabled: !fallbackAddress
|
|
171
166
|
})))
|
|
172
167
|
}
|
|
173
168
|
|
|
174
|
-
function SaveProxiedCheckbox({
|
|
175
|
-
function onChange(
|
|
176
|
-
mockaton.setCollectProxied(
|
|
177
|
-
.catch(onError)
|
|
169
|
+
function SaveProxiedCheckbox({ disabled, collectProxied }) {
|
|
170
|
+
function onChange() {
|
|
171
|
+
mockaton.setCollectProxied(this.checked).catch(onError)
|
|
178
172
|
}
|
|
179
173
|
return (
|
|
180
174
|
r('label', { className: CSS.SaveProxiedCheckbox },
|
|
181
175
|
r('input', {
|
|
182
|
-
ref,
|
|
183
176
|
type: 'checkbox',
|
|
184
177
|
disabled,
|
|
185
178
|
checked: collectProxied,
|
|
@@ -238,14 +231,7 @@ function PreviewLink({ method, urlMask }) {
|
|
|
238
231
|
async function onClick(event) {
|
|
239
232
|
event.preventDefault()
|
|
240
233
|
try {
|
|
241
|
-
|
|
242
|
-
empty(refPayloadViewer.current)
|
|
243
|
-
refPayloadViewer.current.append(PayloadViewerProgressBar())
|
|
244
|
-
}, 180)
|
|
245
|
-
|
|
246
|
-
const response = await fetch(this.href, { method })
|
|
247
|
-
clearTimeout(preloader)
|
|
248
|
-
await updatePayloadViewer(method, urlMask, this.href, response)
|
|
234
|
+
await previewMock(method, urlMask, this.href)
|
|
249
235
|
document.querySelector(`.${CSS.PreviewLink}.${CSS.chosen}`)?.classList.remove(CSS.chosen)
|
|
250
236
|
this.classList.add(CSS.chosen)
|
|
251
237
|
}
|
|
@@ -306,9 +292,9 @@ function MockSelector({ broker }) {
|
|
|
306
292
|
|
|
307
293
|
|
|
308
294
|
function DelayRouteToggler({ broker }) {
|
|
309
|
-
function onChange(
|
|
295
|
+
function onChange() {
|
|
310
296
|
const { method, urlMask } = parseFilename(this.name)
|
|
311
|
-
mockaton.setRouteIsDelayed(method, urlMask,
|
|
297
|
+
mockaton.setRouteIsDelayed(method, urlMask, this.checked)
|
|
312
298
|
.catch(onError)
|
|
313
299
|
}
|
|
314
300
|
return (
|
|
@@ -333,11 +319,12 @@ function DelayRouteToggler({ broker }) {
|
|
|
333
319
|
|
|
334
320
|
|
|
335
321
|
function InternalServerErrorToggler({ broker }) {
|
|
336
|
-
function onChange(
|
|
322
|
+
function onChange() {
|
|
337
323
|
const { urlMask, method } = parseFilename(broker.mocks[0])
|
|
338
|
-
mockaton.select(
|
|
339
|
-
|
|
340
|
-
|
|
324
|
+
mockaton.select(
|
|
325
|
+
this.checked
|
|
326
|
+
? broker.mocks.find(f => parseFilename(f).status === 500)
|
|
327
|
+
: broker.mocks[0])
|
|
341
328
|
.then(init)
|
|
342
329
|
.then(() => linkFor(method, urlMask)?.click())
|
|
343
330
|
.catch(onError)
|
|
@@ -358,18 +345,24 @@ function InternalServerErrorToggler({ broker }) {
|
|
|
358
345
|
)
|
|
359
346
|
}
|
|
360
347
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
348
|
+
|
|
349
|
+
// Payload Preview ===============
|
|
350
|
+
|
|
351
|
+
const payloadViewerTitleRef = useRef()
|
|
352
|
+
const payloadViewerRef = useRef()
|
|
366
353
|
|
|
367
354
|
function PayloadViewer() {
|
|
368
355
|
return (
|
|
369
356
|
r('div', { className: CSS.PayloadViewer },
|
|
370
|
-
r('h2', { ref:
|
|
357
|
+
r('h2', { ref: payloadViewerTitleRef }, Strings.mock),
|
|
371
358
|
r('pre', null,
|
|
372
|
-
r('code', { ref:
|
|
359
|
+
r('code', { ref: payloadViewerRef }, Strings.click_link_to_preview))))
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function PayloadViewerProgressBar() {
|
|
363
|
+
return (
|
|
364
|
+
r('div', { className: CSS.ProgressBar },
|
|
365
|
+
r('div', { style: { animationDuration: '1000ms' } }))) // TODO from Config.delay - 180
|
|
373
366
|
}
|
|
374
367
|
|
|
375
368
|
function PayloadViewerTitle({ file }) {
|
|
@@ -381,27 +374,35 @@ function PayloadViewerTitle({ file }) {
|
|
|
381
374
|
'.' + ext))
|
|
382
375
|
}
|
|
383
376
|
|
|
384
|
-
async function
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
377
|
+
async function previewMock(method, urlMask, href) {
|
|
378
|
+
const timer = setTimeout(renderProgressBar, 180)
|
|
379
|
+
const response = await fetch(href, { method })
|
|
380
|
+
clearTimeout(timer)
|
|
381
|
+
await updatePayloadViewer(method, urlMask, response)
|
|
382
|
+
|
|
383
|
+
function renderProgressBar() {
|
|
384
|
+
payloadViewerRef.current.replaceChildren(PayloadViewerProgressBar())
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async function updatePayloadViewer(method, urlMask, response) {
|
|
389
|
+
payloadViewerTitleRef.current.replaceChildren(
|
|
390
|
+
PayloadViewerTitle({ file: mockSelectorFor(method, urlMask).value }))
|
|
389
391
|
|
|
390
392
|
const mime = response.headers.get('content-type') || ''
|
|
391
|
-
if (mime.startsWith('image/')) //
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
function renderPayloadImage(src) {
|
|
397
|
-
empty(refPayloadViewer.current)
|
|
398
|
-
refPayloadViewer.current.append(r('img', { src }))
|
|
393
|
+
if (mime.startsWith('image/')) { // Naively assumes GET.200
|
|
394
|
+
payloadViewerRef.current.replaceChildren(
|
|
395
|
+
r('img', {
|
|
396
|
+
src: URL.createObjectURL(await response.blob())
|
|
397
|
+
}))
|
|
399
398
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
399
|
+
else {
|
|
400
|
+
const prism = window.Prism
|
|
401
|
+
const body = await response.text() || Strings.empty_response_body
|
|
402
|
+
if (mime === 'application/json' && prism?.highlight && prism?.languages)
|
|
403
|
+
payloadViewerRef.current.innerHTML = prism.highlight(body, prism.languages.json, 'json')
|
|
403
404
|
else
|
|
404
|
-
|
|
405
|
+
payloadViewerRef.current.innerText = body
|
|
405
406
|
}
|
|
406
407
|
}
|
|
407
408
|
|
|
@@ -453,11 +454,6 @@ function cssClass(...args) {
|
|
|
453
454
|
return args.filter(a => a).join(' ')
|
|
454
455
|
}
|
|
455
456
|
|
|
456
|
-
function empty(node) {
|
|
457
|
-
while (node.firstChild)
|
|
458
|
-
node.removeChild(node.firstChild)
|
|
459
|
-
}
|
|
460
|
-
|
|
461
457
|
|
|
462
458
|
// These are simplified React-compatible implementations.
|
|
463
459
|
// IOW, for switching to React, remove the `createRoot`, `createElement`, `useRef`
|
|
@@ -40,7 +40,7 @@ await describe('CORS', async () => {
|
|
|
40
40
|
|
|
41
41
|
await describe('Identifies Preflight Requests', async () => {
|
|
42
42
|
const requiredRequestHeaders = {
|
|
43
|
-
[CH.Origin]: 'http://
|
|
43
|
+
[CH.Origin]: 'http://localhost:9999',
|
|
44
44
|
[CH.AccessControlRequestMethod]: 'POST'
|
|
45
45
|
}
|
|
46
46
|
|