mockaton 10.6.2 → 10.6.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 +58 -57
package/package.json
CHANGED
package/src/Dashboard.js
CHANGED
|
@@ -69,6 +69,10 @@ const state = /** @type {State} */ {
|
|
|
69
69
|
return Boolean(state.proxyFallback)
|
|
70
70
|
},
|
|
71
71
|
|
|
72
|
+
fileFor(method, urlMask) {
|
|
73
|
+
return state.brokersByMethod[method]?.[urlMask]?.currentMock.file
|
|
74
|
+
},
|
|
75
|
+
|
|
72
76
|
leftSideWidth: window.innerWidth / 2,
|
|
73
77
|
|
|
74
78
|
groupByMethod: initPreference('groupByMethod'),
|
|
@@ -81,6 +85,9 @@ const state = /** @type {State} */ {
|
|
|
81
85
|
chosenLink: { method: '', urlMask: '' },
|
|
82
86
|
setChosenLink(method, urlMask) {
|
|
83
87
|
state.chosenLink = { method, urlMask }
|
|
88
|
+
},
|
|
89
|
+
get hasChosenLink() {
|
|
90
|
+
return state.chosenLink.method && state.chosenLink.urlMask
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -95,7 +102,7 @@ async function updateState() {
|
|
|
95
102
|
const response = await mockaton.getState()
|
|
96
103
|
if (!response.ok)
|
|
97
104
|
throw response.status
|
|
98
|
-
|
|
105
|
+
|
|
99
106
|
Object.assign(state, await response.json())
|
|
100
107
|
|
|
101
108
|
const focusedElem = selectorFor(document.activeElement)
|
|
@@ -103,10 +110,8 @@ async function updateState() {
|
|
|
103
110
|
if (focusedElem)
|
|
104
111
|
document.querySelector(focusedElem)?.focus()
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
await previewMock(method, urlMask)
|
|
109
|
-
|
|
113
|
+
if (state.hasChosenLink)
|
|
114
|
+
await previewMock(state.chosenLink.method, state.chosenLink.urlMask)
|
|
110
115
|
}
|
|
111
116
|
catch (error) {
|
|
112
117
|
onError(error)
|
|
@@ -335,6 +340,7 @@ function SaveProxiedCheckbox(ref) {
|
|
|
335
340
|
|
|
336
341
|
function ResetButton() {
|
|
337
342
|
function onClick() {
|
|
343
|
+
state.setChosenLink('', '')
|
|
338
344
|
mockaton.reset()
|
|
339
345
|
.then(parseError)
|
|
340
346
|
.then(updateState)
|
|
@@ -702,31 +708,25 @@ function Resizer() {
|
|
|
702
708
|
/** # Payload Preview */
|
|
703
709
|
|
|
704
710
|
const payloadViewerTitleRef = useRef()
|
|
705
|
-
const
|
|
706
|
-
const SPINNER_DELAY = 80
|
|
711
|
+
const payloadViewerCodeRef = useRef()
|
|
707
712
|
|
|
708
713
|
function PayloadViewer() {
|
|
714
|
+
const { hasChosenLink } = state
|
|
709
715
|
return (
|
|
710
716
|
r('div', className(CSS.PayloadViewer),
|
|
711
|
-
r('h2', { ref: payloadViewerTitleRef },
|
|
717
|
+
r('h2', { ref: payloadViewerTitleRef },
|
|
718
|
+
!hasChosenLink && t`Preview`),
|
|
712
719
|
r('pre', null,
|
|
713
|
-
r('code', { ref:
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
function PayloadViewerProgressBar() {
|
|
717
|
-
return (
|
|
718
|
-
r('div', className(CSS.ProgressBar),
|
|
719
|
-
r('div', { style: { animationDuration: state.delay - SPINNER_DELAY + 'ms' } })))
|
|
720
|
+
r('code', { ref: payloadViewerCodeRef },
|
|
721
|
+
!hasChosenLink && t`Click a link to preview it`))))
|
|
720
722
|
}
|
|
721
723
|
|
|
722
724
|
function PayloadViewerTitle({ file, statusText }) {
|
|
723
|
-
const
|
|
724
|
-
const
|
|
725
|
-
const status = tokens.pop()
|
|
726
|
-
const urlAndMethod = tokens.join('.') + '.'
|
|
725
|
+
const { method, status, ext } = parseFilename(file)
|
|
726
|
+
const fileNameWithComments = file.split('.').slice(0, -3).join('.')
|
|
727
727
|
return (
|
|
728
728
|
r('span', null,
|
|
729
|
-
|
|
729
|
+
fileNameWithComments + '.' + method + '.',
|
|
730
730
|
r('abbr', { title: statusText }, status),
|
|
731
731
|
'.' + ext))
|
|
732
732
|
}
|
|
@@ -741,13 +741,20 @@ function PayloadViewerTitleWhenProxied({ mime, status, statusText, gatewayIsBad
|
|
|
741
741
|
' ' + mime))
|
|
742
742
|
}
|
|
743
743
|
|
|
744
|
+
const SPINNER_DELAY = 80
|
|
745
|
+
function PayloadViewerProgressBar() {
|
|
746
|
+
return (
|
|
747
|
+
r('div', className(CSS.ProgressBar),
|
|
748
|
+
r('div', { style: { animationDuration: state.delay - SPINNER_DELAY + 'ms' } })))
|
|
749
|
+
}
|
|
750
|
+
|
|
744
751
|
async function previewMock(method, urlMask) {
|
|
745
752
|
previewMock.controller?.abort()
|
|
746
753
|
previewMock.controller = new AbortController
|
|
747
754
|
|
|
748
755
|
const spinnerTimer = setTimeout(() => {
|
|
749
756
|
payloadViewerTitleRef.current.replaceChildren(t`Fetching…`)
|
|
750
|
-
|
|
757
|
+
payloadViewerCodeRef.current.replaceChildren(PayloadViewerProgressBar())
|
|
751
758
|
}, SPINNER_DELAY)
|
|
752
759
|
|
|
753
760
|
try {
|
|
@@ -756,48 +763,48 @@ async function previewMock(method, urlMask) {
|
|
|
756
763
|
signal: previewMock.controller.signal
|
|
757
764
|
})
|
|
758
765
|
clearTimeout(spinnerTimer)
|
|
759
|
-
|
|
766
|
+
const file = state.fileFor(method, urlMask)
|
|
767
|
+
if (file === '')
|
|
768
|
+
await updatePayloadViewer(STR_PROXIED, response)
|
|
769
|
+
else if (file)
|
|
770
|
+
await updatePayloadViewer(file, response)
|
|
771
|
+
else {/* e.g. selected was deleted */}
|
|
760
772
|
}
|
|
761
773
|
catch (err) {
|
|
762
774
|
onError(err)
|
|
763
|
-
|
|
775
|
+
payloadViewerCodeRef.current.replaceChildren()
|
|
764
776
|
}
|
|
765
777
|
}
|
|
766
778
|
|
|
767
|
-
|
|
768
|
-
async function updatePayloadViewer(method, urlMask, response) {
|
|
779
|
+
async function updatePayloadViewer(file, response) {
|
|
769
780
|
const mime = response.headers.get('content-type') || ''
|
|
770
781
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
statusText: response.statusText,
|
|
784
|
-
file
|
|
785
|
-
}))
|
|
782
|
+
payloadViewerTitleRef.current.replaceChildren(
|
|
783
|
+
file === STR_PROXIED
|
|
784
|
+
? PayloadViewerTitleWhenProxied({
|
|
785
|
+
mime,
|
|
786
|
+
status: response.status,
|
|
787
|
+
statusText: response.statusText,
|
|
788
|
+
gatewayIsBad: response.headers.get(HEADER_FOR_502)
|
|
789
|
+
})
|
|
790
|
+
: PayloadViewerTitle({
|
|
791
|
+
file,
|
|
792
|
+
statusText: response.statusText
|
|
793
|
+
}))
|
|
786
794
|
|
|
787
|
-
if (mime.startsWith('image/'))
|
|
788
|
-
|
|
795
|
+
if (mime.startsWith('image/')) // Naively assumes GET.200
|
|
796
|
+
payloadViewerCodeRef.current.replaceChildren(
|
|
789
797
|
r('img', {
|
|
790
798
|
src: URL.createObjectURL(await response.blob())
|
|
791
799
|
}))
|
|
792
|
-
}
|
|
793
800
|
else {
|
|
794
801
|
const body = await response.text() || t`/* Empty Response Body */`
|
|
795
802
|
if (mime === 'application/json')
|
|
796
|
-
|
|
803
|
+
payloadViewerCodeRef.current.replaceChildren(r('span', className(CSS.json), syntaxJSON(body)))
|
|
797
804
|
else if (isXML(mime))
|
|
798
|
-
|
|
805
|
+
payloadViewerCodeRef.current.replaceChildren(syntaxXML(body))
|
|
799
806
|
else
|
|
800
|
-
|
|
807
|
+
payloadViewerCodeRef.current.textContent = body
|
|
801
808
|
}
|
|
802
809
|
}
|
|
803
810
|
|
|
@@ -807,12 +814,6 @@ function isXML(mime) {
|
|
|
807
814
|
}
|
|
808
815
|
|
|
809
816
|
|
|
810
|
-
function mockSelectorFor(method, urlMask) {
|
|
811
|
-
const tr = document.querySelector(`tr[key="${method}::${urlMask}"]`)
|
|
812
|
-
return tr?.querySelector(`.${CSS.MockSelector}`)
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
|
|
816
817
|
function initKeyboardNavigation() {
|
|
817
818
|
addEventListener('keydown', onKeyDown)
|
|
818
819
|
|
|
@@ -1013,19 +1014,19 @@ function selectorFor(elem) {
|
|
|
1013
1014
|
|
|
1014
1015
|
const path = []
|
|
1015
1016
|
while (elem) {
|
|
1016
|
-
let
|
|
1017
|
+
let qualifier = ''
|
|
1017
1018
|
if (elem.hasAttribute('key'))
|
|
1018
|
-
|
|
1019
|
+
qualifier = `[key="${elem.getAttribute('key')}"]`
|
|
1019
1020
|
else {
|
|
1020
1021
|
let i = 0
|
|
1021
1022
|
let sib = elem
|
|
1022
1023
|
while ((sib = sib.previousElementSibling))
|
|
1023
|
-
if (sib.
|
|
1024
|
+
if (sib.tagName === elem.tagName)
|
|
1024
1025
|
i++
|
|
1025
1026
|
if (i)
|
|
1026
|
-
|
|
1027
|
+
qualifier = `:nth-of-type(${i + 1})`
|
|
1027
1028
|
}
|
|
1028
|
-
path.push(elem.
|
|
1029
|
+
path.push(elem.tagName + qualifier)
|
|
1029
1030
|
elem = elem.parentElement
|
|
1030
1031
|
}
|
|
1031
1032
|
return path.reverse().join('>')
|