mockaton 8.14.0 → 8.15.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 +4 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/Api.js +2 -1
- package/src/Dashboard.css +6 -5
- package/src/MockDispatcher.js +3 -3
- package/src/Mockaton.js +2 -2
- package/src/StaticDispatcher.js +8 -16
- package/src/config.js +5 -0
- package/src/mockaton-logo.svg +1 -1
package/README.md
CHANGED
|
@@ -362,6 +362,10 @@ Defaults to `0`, which means auto-assigned
|
|
|
362
362
|
Defaults to `1200` milliseconds. Although routes can individually be delayed
|
|
363
363
|
with the 🕓 Checkbox, the amount is globally configurable with this option.
|
|
364
364
|
|
|
365
|
+
### `delayJitter?: number`
|
|
366
|
+
Defaults to `0`. Range: `[0.0, 3.0]`. Maximum percentage of the delay to add.
|
|
367
|
+
For example, `0.5` will add at most `600ms` to the default delay.
|
|
368
|
+
|
|
365
369
|
<br/>
|
|
366
370
|
|
|
367
371
|
### `proxyFallback?: string`
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/src/Api.js
CHANGED
|
@@ -9,9 +9,9 @@ import { parseJSON } from './utils/http-request.js'
|
|
|
9
9
|
import { uiSyncVersion } from './Watcher.js'
|
|
10
10
|
import * as mockBrokersCollection from './mockBrokersCollection.js'
|
|
11
11
|
import { config, ConfigValidator } from './config.js'
|
|
12
|
-
import { getStaticFilesCollection, findStaticBrokerByRoute } from './StaticDispatcher.js'
|
|
13
12
|
import { DF, API, LONG_POLL_SERVER_TIMEOUT } from './ApiConstants.js'
|
|
14
13
|
import { sendOK, sendJSON, sendUnprocessableContent, sendFile } from './utils/http-response.js'
|
|
14
|
+
import { getStaticFilesCollection, findStaticBrokerByRoute, initStaticCollection } from './StaticDispatcher.js'
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
const dashboardAssets = [
|
|
@@ -101,6 +101,7 @@ function longPollClientSyncVersion(req, response) {
|
|
|
101
101
|
|
|
102
102
|
function reinitialize(_, response) {
|
|
103
103
|
mockBrokersCollection.init()
|
|
104
|
+
initStaticCollection() // TESTME
|
|
104
105
|
sendOK(response)
|
|
105
106
|
}
|
|
106
107
|
|
package/src/Dashboard.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
@media (prefers-color-scheme: light) {
|
|
8
8
|
:root {
|
|
9
9
|
--color4xxBackground: #ffedd1;
|
|
10
|
-
--colorAccent: #
|
|
10
|
+
--colorAccent: #0068c1;
|
|
11
11
|
--colorAccentAlt: #068185;
|
|
12
12
|
--colorBackground: #fff;
|
|
13
13
|
--colorComboBoxHeaderBackground: #fff;
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
--color4xxBackground: #403630;
|
|
29
29
|
--colorAccent: #2495ff;
|
|
30
30
|
--colorBackground: #161616;
|
|
31
|
-
--colorHeaderBackground: #
|
|
31
|
+
--colorHeaderBackground: #111;
|
|
32
32
|
--colorComboBoxBackground: #2a2a2a;
|
|
33
33
|
--colorSecondaryButtonBackground: #2a2a2a;
|
|
34
34
|
--colorSecondaryAction: #999;
|
|
@@ -115,7 +115,6 @@ select {
|
|
|
115
115
|
width: 100%;
|
|
116
116
|
align-items: flex-end;
|
|
117
117
|
padding: 16px;
|
|
118
|
-
border-bottom: 1px solid rgba(127, 127, 127, 0.1);
|
|
119
118
|
background: var(--colorHeaderBackground);
|
|
120
119
|
box-shadow: var(--boxShadow1);
|
|
121
120
|
gap: 10px;
|
|
@@ -296,7 +295,8 @@ table {
|
|
|
296
295
|
word-break: break-word;
|
|
297
296
|
|
|
298
297
|
span {
|
|
299
|
-
opacity: 0.
|
|
298
|
+
opacity: 0.6;
|
|
299
|
+
filter: saturate(0);
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
&:hover {
|
|
@@ -513,7 +513,8 @@ table {
|
|
|
513
513
|
}
|
|
514
514
|
|
|
515
515
|
span {
|
|
516
|
-
opacity: 0.
|
|
516
|
+
opacity: 0.6;
|
|
517
|
+
filter: saturate(0);
|
|
517
518
|
}
|
|
518
519
|
}
|
|
519
520
|
}
|
package/src/MockDispatcher.js
CHANGED
|
@@ -2,8 +2,8 @@ import { join } from 'node:path'
|
|
|
2
2
|
|
|
3
3
|
import { proxy } from './ProxyRelay.js'
|
|
4
4
|
import { cookie } from './cookie.js'
|
|
5
|
-
import { config } from './config.js'
|
|
6
5
|
import { applyPlugins } from './MockDispatcherPlugins.js'
|
|
6
|
+
import { config, calcDelay } from './config.js'
|
|
7
7
|
import { BodyReaderError } from './utils/http-request.js'
|
|
8
8
|
import * as mockBrokerCollection from './mockBrokersCollection.js'
|
|
9
9
|
import { sendInternalServerError, sendNotFound, sendUnprocessableContent } from './utils/http-response.js'
|
|
@@ -14,7 +14,7 @@ export async function dispatchMock(req, response) {
|
|
|
14
14
|
const broker = mockBrokerCollection.findBrokerByRoute(req.method, req.url)
|
|
15
15
|
if (!broker || broker.proxied) {
|
|
16
16
|
if (config.proxyFallback)
|
|
17
|
-
await proxy(req, response,
|
|
17
|
+
await proxy(req, response, Number(broker?.delayed && calcDelay()))
|
|
18
18
|
else
|
|
19
19
|
sendNotFound(response)
|
|
20
20
|
return
|
|
@@ -34,7 +34,7 @@ export async function dispatchMock(req, response) {
|
|
|
34
34
|
: await applyPlugins(join(config.mocksDir, broker.file), req, response)
|
|
35
35
|
|
|
36
36
|
response.setHeader('Content-Type', mime)
|
|
37
|
-
setTimeout(() => response.end(body),
|
|
37
|
+
setTimeout(() => response.end(body), Number(broker.delayed && calcDelay()))
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
40
40
|
if (error instanceof BodyReaderError)
|
package/src/Mockaton.js
CHANGED
|
@@ -8,7 +8,7 @@ import { BodyReaderError } from './utils/http-request.js'
|
|
|
8
8
|
import * as mockBrokerCollection from './mockBrokersCollection.js'
|
|
9
9
|
import { setCorsHeaders, isPreflight } from './utils/http-cors.js'
|
|
10
10
|
import { apiPatchRequests, apiGetRequests } from './Api.js'
|
|
11
|
-
import { dispatchStatic,
|
|
11
|
+
import { dispatchStatic, initStaticCollection, findStaticBrokerByRoute } from './StaticDispatcher.js'
|
|
12
12
|
import { sendNoContent, sendInternalServerError, sendUnprocessableContent } from './utils/http-response.js'
|
|
13
13
|
|
|
14
14
|
|
|
@@ -53,7 +53,7 @@ async function onRequest(req, response) {
|
|
|
53
53
|
else if (method === 'GET' && apiGetRequests.has(url))
|
|
54
54
|
apiGetRequests.get(url)(req, response)
|
|
55
55
|
|
|
56
|
-
else if (method === 'GET' &&
|
|
56
|
+
else if (method === 'GET' && findStaticBrokerByRoute(req.url))
|
|
57
57
|
await dispatchStatic(req, response)
|
|
58
58
|
|
|
59
59
|
else
|
package/src/StaticDispatcher.js
CHANGED
|
@@ -2,7 +2,7 @@ import { join } from 'node:path'
|
|
|
2
2
|
import { readFileSync } from 'node:fs'
|
|
3
3
|
|
|
4
4
|
import { mimeFor } from './utils/mime.js'
|
|
5
|
-
import { config, isFileAllowed } from './config.js'
|
|
5
|
+
import { config, isFileAllowed, calcDelay } from './config.js'
|
|
6
6
|
import { sendPartialContent, sendNotFound } from './utils/http-response.js'
|
|
7
7
|
import { isDirectory, isFile, listFilesRecursively } from './utils/fs.js'
|
|
8
8
|
|
|
@@ -55,29 +55,21 @@ export function getStaticFilesCollection() {
|
|
|
55
55
|
return collection
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export function isStatic(req) {
|
|
59
|
-
return req.url in collection || join(req.url, 'index.html') in collection
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// TODO improve
|
|
63
58
|
export async function dispatchStatic(req, response) {
|
|
64
|
-
|
|
65
|
-
if (!broker && req.url in collection)
|
|
66
|
-
broker = collection[req.url]
|
|
59
|
+
const broker = findStaticBrokerByRoute(req.url)
|
|
67
60
|
|
|
68
|
-
if (broker?.should404) { // TESTME
|
|
69
|
-
sendNotFound(response)
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const file = broker.resolvedPath
|
|
74
61
|
setTimeout(async () => {
|
|
62
|
+
if (!broker || broker.should404) { // TESTME
|
|
63
|
+
sendNotFound(response)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
const file = broker.resolvedPath
|
|
75
67
|
if (req.headers.range)
|
|
76
68
|
await sendPartialContent(response, req.headers.range, file)
|
|
77
69
|
else {
|
|
78
70
|
response.setHeader('Content-Type', mimeFor(file))
|
|
79
71
|
response.end(readFileSync(file))
|
|
80
72
|
}
|
|
81
|
-
}, broker.delayed
|
|
73
|
+
}, Number(broker.delayed && calcDelay()))
|
|
82
74
|
}
|
|
83
75
|
|
package/src/config.js
CHANGED
|
@@ -26,6 +26,7 @@ const schema = {
|
|
|
26
26
|
formatCollectedJSON: [true, is(Boolean)],
|
|
27
27
|
|
|
28
28
|
delay: [1200, ms => Number.isInteger(ms) && ms >= 0],
|
|
29
|
+
delayJitter: [0, percent => percent >= 0 && percent <= 3],
|
|
29
30
|
|
|
30
31
|
cookies: [{}, is(Object)], // defaults to the first kv
|
|
31
32
|
|
|
@@ -66,6 +67,10 @@ export const ConfigValidator = Object.freeze(validators)
|
|
|
66
67
|
|
|
67
68
|
export const isFileAllowed = f => !config.ignore.test(f)
|
|
68
69
|
|
|
70
|
+
export const calcDelay = () => config.delayJitter
|
|
71
|
+
? config.delay * (1 + Math.random() * config.delayJitter)
|
|
72
|
+
: config.delay
|
|
73
|
+
|
|
69
74
|
|
|
70
75
|
export function setup(options) {
|
|
71
76
|
Object.assign(config, options)
|
package/src/mockaton-logo.svg
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<svg version="1.1" viewBox="0 0 570 100" xmlns="http://www.w3.org/2000/svg">
|
|
3
3
|
<style>
|
|
4
4
|
:root { --color: #000000; }
|
|
5
|
-
@media (prefers-color-scheme: light) { :root { --color: #
|
|
5
|
+
@media (prefers-color-scheme: light) { :root { --color: #444 } }
|
|
6
6
|
@media (prefers-color-scheme: dark) { :root { --color: #eee } }
|
|
7
7
|
path { fill: var(--color) }
|
|
8
8
|
</style>
|