mockaton 10.5.0 → 10.5.2
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/Api.js +11 -16
- package/src/Dashboard.css +0 -1
- package/src/Dashboard.js +8 -7
- package/src/{Dashboard.html → DashboardHtml.js} +40 -3
- package/src/utils/http-response.js +8 -0
package/package.json
CHANGED
package/src/Api.js
CHANGED
|
@@ -4,26 +4,21 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { join } from 'node:path'
|
|
7
|
+
|
|
7
8
|
import { cookie } from './cookie.js'
|
|
8
9
|
import { parseJSON } from './utils/http-request.js'
|
|
9
10
|
import { uiSyncVersion } from './Watcher.js'
|
|
10
11
|
import * as staticCollection from './staticCollection.js'
|
|
11
12
|
import * as mockBrokersCollection from './mockBrokersCollection.js'
|
|
12
13
|
import { config, ConfigValidator } from './config.js'
|
|
14
|
+
import { LinkHeader, DashboardHtml, CSP, dashboardAssets } from './DashboardHtml.js'
|
|
13
15
|
import { DF, API, LONG_POLL_SERVER_TIMEOUT } from './ApiConstants.js'
|
|
14
|
-
import { sendOK, sendJSON, sendUnprocessableContent, sendFile } from './utils/http-response.js'
|
|
16
|
+
import { sendOK, sendJSON, sendUnprocessableContent, sendFile, sendHTML } from './utils/http-response.js'
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
export const apiGetRequests = new Map([
|
|
18
|
-
[API.dashboard,
|
|
19
|
-
...[
|
|
20
|
-
'/ApiConstants.js',
|
|
21
|
-
'/ApiCommander.js',
|
|
22
|
-
'/Dashboard.css',
|
|
23
|
-
'/Dashboard.js',
|
|
24
|
-
'/Filename.js',
|
|
25
|
-
'/Logo.svg'
|
|
26
|
-
].map(f => [API.dashboard + f, serveDashboardAsset(f)]),
|
|
20
|
+
[API.dashboard, serveDashboard],
|
|
21
|
+
...dashboardAssets.map(f => [API.dashboard + f, serveStatic(f)]),
|
|
27
22
|
|
|
28
23
|
[API.state, getState],
|
|
29
24
|
[API.syncVersion, longPollClientSyncVersion],
|
|
@@ -49,12 +44,12 @@ export const apiPatchRequests = new Map([
|
|
|
49
44
|
|
|
50
45
|
/** # GET */
|
|
51
46
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
function serveDashboard(_, response) {
|
|
48
|
+
sendHTML(response, DashboardHtml, CSP, LinkHeader)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function serveStatic(f) {
|
|
52
|
+
return (_, response) => sendFile(response, join(import.meta.dirname, f))
|
|
58
53
|
}
|
|
59
54
|
|
|
60
55
|
function getState(_, response) {
|
package/src/Dashboard.css
CHANGED
package/src/Dashboard.js
CHANGED
|
@@ -76,7 +76,7 @@ const state = /** @type {State} */ {
|
|
|
76
76
|
|
|
77
77
|
const mockaton = new Commander(location.origin)
|
|
78
78
|
updateState()
|
|
79
|
-
initLongPoll
|
|
79
|
+
deferred(initLongPoll)
|
|
80
80
|
|
|
81
81
|
async function updateState() {
|
|
82
82
|
try {
|
|
@@ -93,7 +93,6 @@ async function updateState() {
|
|
|
93
93
|
|
|
94
94
|
const r = createElement
|
|
95
95
|
const s = createSvgElement
|
|
96
|
-
|
|
97
96
|
const t = translation => translation[0]
|
|
98
97
|
|
|
99
98
|
const leftSideRef = useRef()
|
|
@@ -124,7 +123,8 @@ function Header() {
|
|
|
124
123
|
r('img', {
|
|
125
124
|
alt: t`Mockaton`,
|
|
126
125
|
src: 'mockaton/Logo.svg',
|
|
127
|
-
width:
|
|
126
|
+
width: 120,
|
|
127
|
+
height: 22
|
|
128
128
|
}),
|
|
129
129
|
r('div', null,
|
|
130
130
|
GlobalDelayField(),
|
|
@@ -645,6 +645,7 @@ Resizer.onUp = function () {
|
|
|
645
645
|
|
|
646
646
|
const payloadViewerTitleRef = useRef()
|
|
647
647
|
const payloadViewerRef = useRef()
|
|
648
|
+
const SPINNER_DELAY = 80
|
|
648
649
|
|
|
649
650
|
function PayloadViewer() {
|
|
650
651
|
return (
|
|
@@ -657,7 +658,7 @@ function PayloadViewer() {
|
|
|
657
658
|
function PayloadViewerProgressBar() {
|
|
658
659
|
return (
|
|
659
660
|
r('div', className(CSS.ProgressBar),
|
|
660
|
-
r('div', { style: { animationDuration: state.delay + 'ms' } })))
|
|
661
|
+
r('div', { style: { animationDuration: state.delay - SPINNER_DELAY + 'ms' } })))
|
|
661
662
|
}
|
|
662
663
|
|
|
663
664
|
function PayloadViewerTitle({ file, statusText }) {
|
|
@@ -689,7 +690,7 @@ async function previewMock(method, urlMask, href) {
|
|
|
689
690
|
const spinnerTimer = setTimeout(() => {
|
|
690
691
|
payloadViewerTitleRef.current.replaceChildren(t`Fetching…`)
|
|
691
692
|
payloadViewerRef.current.replaceChildren(PayloadViewerProgressBar())
|
|
692
|
-
},
|
|
693
|
+
}, SPINNER_DELAY)
|
|
693
694
|
|
|
694
695
|
try {
|
|
695
696
|
const response = await fetch(href, {
|
|
@@ -970,7 +971,7 @@ function dittoSplitPaths(paths) {
|
|
|
970
971
|
return result
|
|
971
972
|
}
|
|
972
973
|
|
|
973
|
-
|
|
974
|
+
dittoSplitPaths.test = function () {
|
|
974
975
|
const input = [
|
|
975
976
|
'/api/user',
|
|
976
977
|
'/api/user/avatar',
|
|
@@ -992,7 +993,7 @@ function dittoSplitPaths(paths) {
|
|
|
992
993
|
['/v2/foo/', 'bar']
|
|
993
994
|
]
|
|
994
995
|
console.assert(JSON.stringify(dittoSplitPaths(input)) === JSON.stringify(expected))
|
|
995
|
-
}
|
|
996
|
+
}
|
|
996
997
|
|
|
997
998
|
|
|
998
999
|
|
|
@@ -1,14 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
import { API } from './ApiConstants.js'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const DashboardHtml = `<!DOCTYPE html>
|
|
2
5
|
<html lang="en-US">
|
|
3
6
|
<head>
|
|
4
7
|
<meta charset="UTF-8">
|
|
5
|
-
<link rel="stylesheet" href="./mockaton/Dashboard.css"
|
|
8
|
+
<link rel="stylesheet" href="./mockaton/Dashboard.css" />
|
|
6
9
|
<link rel="icon" href="data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m235 33.7v202c0 9.19-5.81 14-17.4 14-11.6 0-17.4-4.83-17.4-14v-151c-0.115-4.49-6.72-5.88-8.46-0.87l-48.3 155c-2.22 7.01-7.72 10.1-16 9.9-3.63-0.191-7.01-1.14-9.66-2.89-2.89-1.72-4.83-4.34-5.57-7.72-11.1-37-22.6-74.3-34.1-111-4.34-14-8.95-31.4-14-48.3-1.82-4.83-8.16-5.32-8.46 1.16v156c0 9.19-5.81 14-17.4 14-11.6 0-17.4-4.83-17.4-14v-207c0-5.74 2.62-13.2 9.39-16.3 7.5-3.14 15-4.05 21.8-3.8 3.14 0 6.03 0.686 8.95 1.46 3.14 0.797 6.03 1.98 8.7 3.63 2.65 1.38 5.32 3.14 7.5 5.57 2.22 2.22 3.87 4.83 5.07 7.72l45.8 157c4.63-15.9 32.4-117 33.3-121 4.12-13.8 7.72-26.5 10.9-38.7 1.16-2.65 2.89-5.32 5.07-7.5 2.15-2.15 4.58-4.12 7.5-5.32 2.65-1.57 5.57-2.89 8.46-3.63 3.14-0.797 9.44-0.988 12.1-0.988 11.6 1.07 29.4 9.14 29.4 27z' fill='%23808080'/%3E%3C/svg%3E">
|
|
7
10
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
11
|
<meta name="description" content="HTTP Mock Server">
|
|
9
12
|
<title>Mockaton</title>
|
|
10
13
|
</head>
|
|
11
14
|
<body>
|
|
12
|
-
<script src="./mockaton/Dashboard.js"
|
|
15
|
+
<script type="module" src="./mockaton/Dashboard.js"></script>
|
|
13
16
|
</body>
|
|
14
17
|
</html>
|
|
18
|
+
`
|
|
19
|
+
|
|
20
|
+
export const CSP = [
|
|
21
|
+
`default-src 'self'`,
|
|
22
|
+
`img-src data: blob: 'self'`
|
|
23
|
+
].join(';')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const assets = {
|
|
27
|
+
style: ['/Dashboard.css'],
|
|
28
|
+
script: ['/Dashboard.js'],
|
|
29
|
+
module: ['/ApiConstants.js', '/ApiCommander.js', '/Filename.js'],
|
|
30
|
+
image: ['/Logo.svg']
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const dashboardAssets = Object.values(assets).flat()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// Link Header. This is not very useful in localhost (only optimizes 2ms).
|
|
37
|
+
const attrMap = {
|
|
38
|
+
module: 'rel=modulepreload',
|
|
39
|
+
image: 'rel=preload; as=image',
|
|
40
|
+
style: 'rel=preload; as=style',
|
|
41
|
+
script: 'rel=preload; as=script; crossorigin',
|
|
42
|
+
fetch: 'rel=preload; as=fetch; crossorigin'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let links = []
|
|
46
|
+
for (const [type, files] of Object.entries(assets))
|
|
47
|
+
for (const f of files)
|
|
48
|
+
links.push(`<${API.dashboard + f}>; ${attrMap[type]}`)
|
|
49
|
+
links.push(`<${API.state}>; ${attrMap.fetch}`)
|
|
50
|
+
|
|
51
|
+
export const LinkHeader = links.join(',')
|
|
@@ -9,6 +9,14 @@ export function sendOK(response) {
|
|
|
9
9
|
response.end()
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export function sendHTML(response, html, csp, link) {
|
|
13
|
+
logger.access(response)
|
|
14
|
+
response.setHeader('Content-Type', mimeFor('html'))
|
|
15
|
+
response.setHeader('Content-Security-Policy', csp)
|
|
16
|
+
response.setHeader('Link', link)
|
|
17
|
+
response.end(html)
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
export function sendJSON(response, payload) {
|
|
13
21
|
logger.access(response)
|
|
14
22
|
response.setHeader('Content-Type', 'application/json')
|