mockaton 12.5.0 → 12.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
CHANGED
package/src/client/Filename.js
CHANGED
|
@@ -9,7 +9,7 @@ const METHODS = [ // @KeepSync node:http.METHODS
|
|
|
9
9
|
'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE'
|
|
10
10
|
]
|
|
11
11
|
|
|
12
|
-
const reComments = /\(
|
|
12
|
+
const reComments = /\([^()]*\)/g // Anything within parentheses
|
|
13
13
|
|
|
14
14
|
export function extractComments(file) {
|
|
15
15
|
return Array.from(file.matchAll(reComments), ([c]) => c)
|
|
@@ -44,13 +44,17 @@ export function parseFilename(file) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function removeTrailingSlash(url = '') {
|
|
47
|
+
export function removeTrailingSlash(url = '') {
|
|
48
48
|
return url
|
|
49
49
|
.replace(/\/$/, '')
|
|
50
50
|
.replace('/?', '?')
|
|
51
51
|
.replace('/#', '#')
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export function removeQueryStringAndFragment(url = '') {
|
|
55
|
+
return new URL(url, 'http://_').pathname
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
function responseStatusIsValid(status) {
|
|
55
59
|
return Number.isInteger(status)
|
|
56
60
|
&& status >= 100
|
package/src/client/app.js
CHANGED
|
@@ -679,7 +679,7 @@ async function onError(error) {
|
|
|
679
679
|
msg = error.statusText
|
|
680
680
|
}
|
|
681
681
|
else if (error?.message === 'Failed to fetch') {
|
|
682
|
-
msg = t`Looks like
|
|
682
|
+
msg = t`Looks like Mockaton server is not running`
|
|
683
683
|
isOffline = true
|
|
684
684
|
}
|
|
685
685
|
else
|
|
@@ -714,7 +714,7 @@ function Logo() {
|
|
|
714
714
|
return (
|
|
715
715
|
s('svg', { viewBox: '0 0 556 100' },
|
|
716
716
|
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' }),
|
|
717
|
-
s('path', { opacity: 0.
|
|
717
|
+
s('path', { opacity: 0.7, 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' }),
|
|
718
718
|
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' })))
|
|
719
719
|
}
|
|
720
720
|
|
|
@@ -734,7 +734,7 @@ function CloudIcon() {
|
|
|
734
734
|
function HelpIcon() {
|
|
735
735
|
return (
|
|
736
736
|
s('svg', { viewBox: '0 0 24 24' },
|
|
737
|
-
s('path', { d: '
|
|
737
|
+
s('path', { d: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m1 17h-2v-2h2zm2.07-7.75-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25' })))
|
|
738
738
|
}
|
|
739
739
|
|
|
740
740
|
|
package/src/client/styles.css
CHANGED
|
@@ -1,51 +1,25 @@
|
|
|
1
1
|
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
--colorBackground: light-dark(#fff, #181818);
|
|
4
|
+
--colorComboBoxHeaderBackground: light-dark(#fff, #222);
|
|
5
|
+
--colorSecondaryButtonBackground: light-dark(#fcfcfc, #2c2c2c);
|
|
6
|
+
--colorHeaderBackground: light-dark(#f2f2f3, #141414);
|
|
7
|
+
--colorComboBoxBackground: light-dark(#eee, #2a2a2a);
|
|
8
|
+
--colorBorder: light-dark(#e0e0e0, #333);
|
|
9
|
+
--colorSecondaryAction: light-dark(#666, #aaa);
|
|
10
|
+
--colorLabel: light-dark(#555, #aaa);
|
|
11
|
+
--colorDisabledMockSelector: light-dark(#444, #a9b9b9);
|
|
12
|
+
--colorText: light-dark(#000, #fff);
|
|
13
|
+
--colorAccent: light-dark(#0059dd, #2495ff);
|
|
14
|
+
--colorHover: light-dark(rgba(119, 193, 255, 0.4), rgba(0, 63, 115, 0.5));
|
|
15
|
+
--colorRed: light-dark(#da0f00, #f41606);
|
|
16
|
+
--colorPink: light-dark(#ed206a, #f92672);
|
|
17
|
+
--colorPurple: light-dark(#9b71e8, #ae81ff);
|
|
18
|
+
--colorGreen: light-dark(#388e3c, #a6e22e);
|
|
19
|
+
--color4xxBackground: light-dark(#ffedd1, #68554a);
|
|
20
|
+
|
|
21
|
+
accent-color: var(--colorAccent);
|
|
2
22
|
--radius: 16px;
|
|
3
|
-
--boxShadow1: rgba(0, 0, 0, 0.18) 0 2px 1px -1px, rgba(0, 0, 0, 0.12) 0 1px 1px 0, rgba(0, 0, 0, 0.1) 0 1px 3px 0px;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
@media (prefers-color-scheme: light) {
|
|
7
|
-
:root {
|
|
8
|
-
color-scheme: light;
|
|
9
|
-
--colorBackground: #fff;
|
|
10
|
-
--colorComboBoxHeaderBackground: #fff;
|
|
11
|
-
--colorSecondaryButtonBackground: #fcfcfc;
|
|
12
|
-
--colorHeaderBackground: #f2f2f3;
|
|
13
|
-
--colorComboBoxBackground: #eee;
|
|
14
|
-
--colorSecondaryActionBorder: #e0e0e0;
|
|
15
|
-
--colorSecondaryAction: #666;
|
|
16
|
-
--colorLabel: #555;
|
|
17
|
-
--colorDisabledMockSelector: #444;
|
|
18
|
-
--colorText: #000;
|
|
19
|
-
--colorAccent: #0059dd;
|
|
20
|
-
--colorHover: rgba(119, 193, 255, 0.4);
|
|
21
|
-
--colorRed: #da0f00;
|
|
22
|
-
--colorPink: #ed206a;
|
|
23
|
-
--colorPurple: #9b71e8;
|
|
24
|
-
--colorGreen: #388e3c;
|
|
25
|
-
--color4xxBackground: #ffedd1;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
@media (prefers-color-scheme: dark) {
|
|
29
|
-
:root {
|
|
30
|
-
color-scheme: dark;
|
|
31
|
-
--colorBackground: #181818;
|
|
32
|
-
--colorComboBoxHeaderBackground: #222;
|
|
33
|
-
--colorSecondaryButtonBackground: #2c2c2c;
|
|
34
|
-
--colorHeaderBackground: #141414;
|
|
35
|
-
--colorComboBoxBackground: #2a2a2a;
|
|
36
|
-
--colorSecondaryActionBorder: #333;
|
|
37
|
-
--colorSecondaryAction: #aaa;
|
|
38
|
-
--colorLabel: #aaa;
|
|
39
|
-
--colorDisabledMockSelector: #a9b9b9;
|
|
40
|
-
--colorText: #fff;
|
|
41
|
-
--colorAccent: #2495ff;
|
|
42
|
-
--colorHover: rgba(0, 63, 115, 0.5);
|
|
43
|
-
--colorRed: #f41606;
|
|
44
|
-
--colorPink: #f92672;
|
|
45
|
-
--colorPurple: #ae81ff;
|
|
46
|
-
--colorGreen: #a6e22e;
|
|
47
|
-
--color4xxBackground: #68554a;
|
|
48
|
-
}
|
|
49
23
|
}
|
|
50
24
|
|
|
51
25
|
html,
|
|
@@ -112,7 +86,7 @@ select {
|
|
|
112
86
|
transition: all 240ms ease-out;
|
|
113
87
|
|
|
114
88
|
&:enabled {
|
|
115
|
-
border-color: var(--
|
|
89
|
+
border-color: var(--colorBorder);
|
|
116
90
|
background-color: var(--colorSecondaryButtonBackground);
|
|
117
91
|
&:hover {
|
|
118
92
|
border-color: var(--colorHover);
|
|
@@ -129,7 +103,6 @@ header {
|
|
|
129
103
|
display: flex;
|
|
130
104
|
flex: 0 0 100%;
|
|
131
105
|
padding: 16px;
|
|
132
|
-
border-bottom: 1px solid var(--colorSecondaryActionBorder);
|
|
133
106
|
background: var(--colorHeaderBackground);
|
|
134
107
|
|
|
135
108
|
.Logo {
|
|
@@ -232,7 +205,7 @@ header {
|
|
|
232
205
|
width: 100%;
|
|
233
206
|
height: 28px;
|
|
234
207
|
padding: 4px 8px;
|
|
235
|
-
border: 1px solid var(--
|
|
208
|
+
border: 1px solid var(--colorBorder);
|
|
236
209
|
margin-top: 2px;
|
|
237
210
|
color: var(--colorText);
|
|
238
211
|
font-size: 11px;
|
|
@@ -337,8 +310,8 @@ main {
|
|
|
337
310
|
|
|
338
311
|
.leftSide {
|
|
339
312
|
width: 50%; /* resizable in js */
|
|
340
|
-
border-
|
|
341
|
-
|
|
313
|
+
border-top: 1px solid var(--colorBorder);
|
|
314
|
+
border-right: 1px solid var(--colorBorder);
|
|
342
315
|
}
|
|
343
316
|
|
|
344
317
|
.rightSide {
|
|
@@ -346,6 +319,7 @@ main {
|
|
|
346
319
|
min-width: 100px;
|
|
347
320
|
min-height: 0;
|
|
348
321
|
flex: 1;
|
|
322
|
+
border-top: 1px solid var(--colorBorder);
|
|
349
323
|
|
|
350
324
|
.Resizer {
|
|
351
325
|
position: absolute;
|
|
@@ -357,7 +331,7 @@ main {
|
|
|
357
331
|
cursor: col-resize;
|
|
358
332
|
|
|
359
333
|
&:active {
|
|
360
|
-
border-color: var(--
|
|
334
|
+
border-color: var(--colorBorder);
|
|
361
335
|
}
|
|
362
336
|
}
|
|
363
337
|
}
|
|
@@ -370,7 +344,7 @@ main {
|
|
|
370
344
|
justify-content: space-between;
|
|
371
345
|
padding-right: 14px;
|
|
372
346
|
padding-left: 16px;
|
|
373
|
-
border-bottom: 1px solid var(--
|
|
347
|
+
border-bottom: 1px solid var(--colorBorder);
|
|
374
348
|
background: var(--colorHeaderBackground);
|
|
375
349
|
}
|
|
376
350
|
|
|
@@ -385,7 +359,7 @@ main {
|
|
|
385
359
|
select {
|
|
386
360
|
width: 110px;
|
|
387
361
|
padding: 6px 8px;
|
|
388
|
-
border: 1px solid var(--
|
|
362
|
+
border: 1px solid var(--colorBorder);
|
|
389
363
|
margin-left: 4px;
|
|
390
364
|
background-image: none;
|
|
391
365
|
text-align-last: center;
|
|
@@ -555,7 +529,7 @@ main {
|
|
|
555
529
|
height: 22px;
|
|
556
530
|
align-items: center;
|
|
557
531
|
justify-content: center;
|
|
558
|
-
border: 1px solid var(--
|
|
532
|
+
border: 1px solid var(--colorBorder);
|
|
559
533
|
fill: none;
|
|
560
534
|
stroke: var(--colorSecondaryAction);
|
|
561
535
|
stroke-width: 2.5px;
|
|
@@ -683,7 +657,6 @@ main {
|
|
|
683
657
|
background: var(--colorRed);
|
|
684
658
|
color: white;
|
|
685
659
|
border-radius: var(--radius);
|
|
686
|
-
box-shadow: var(--boxShadow1);
|
|
687
660
|
opacity: 0;
|
|
688
661
|
transform: translateY(20px);
|
|
689
662
|
animation: _kfToastIn 240ms forwards;
|
package/src/server/MockBroker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_MOCK_COMMENT } from '../client/ApiConstants.js'
|
|
2
|
-
import { parseFilename, includesComment, extractComments } from '../client/Filename.js'
|
|
2
|
+
import { parseFilename, includesComment, extractComments, removeQueryStringAndFragment } from '../client/Filename.js'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -105,15 +105,11 @@ class UrlMatcher {
|
|
|
105
105
|
|
|
106
106
|
#buildUrlRegex(file) {
|
|
107
107
|
let { urlMask } = parseFilename(file)
|
|
108
|
-
urlMask =
|
|
108
|
+
urlMask = removeQueryStringAndFragment(urlMask)
|
|
109
109
|
urlMask = this.#disregardVariables(urlMask)
|
|
110
110
|
return new RegExp('^' + urlMask + '/*$')
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
#removeQueryStringAndFragment(str) {
|
|
114
|
-
return str.replace(/[?#].*/, '')
|
|
115
|
-
}
|
|
116
|
-
|
|
117
113
|
#disregardVariables(str) { // Stars out all parts that are in square brackets
|
|
118
114
|
return str.replace(/\[.*?]/g, '[^/]+')
|
|
119
115
|
}
|
|
@@ -127,7 +123,7 @@ class UrlMatcher {
|
|
|
127
123
|
// slashes. For instance, for routing api/foo/[id]?qs…
|
|
128
124
|
urlMaskMatches = (url) => {
|
|
129
125
|
let u = decodeURIComponent(url)
|
|
130
|
-
u =
|
|
126
|
+
u = removeQueryStringAndFragment(u)
|
|
131
127
|
u += '/'
|
|
132
128
|
return this.#urlRegex.test(u)
|
|
133
129
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { relative } from 'node:path'
|
|
2
2
|
import { config } from '../config.js'
|
|
3
|
-
import {
|
|
3
|
+
import { decode } from './HttpIncomingMessage.js'
|
|
4
|
+
import { parseFilename, removeTrailingSlash, removeQueryStringAndFragment } from '../../client/Filename.js'
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export function parseQueryParams(url) {
|
|
@@ -11,14 +12,16 @@ export function parseSplats(url, filename) {
|
|
|
11
12
|
const { urlMask } = parseFilename(relative(config.mocksDir, filename))
|
|
12
13
|
|
|
13
14
|
const splats = []
|
|
14
|
-
const pattern = urlMask
|
|
15
|
+
const pattern = removeQueryStringAndFragment(decode(urlMask))
|
|
15
16
|
.replace(/\[(.+?)]/g, (_, name) => {
|
|
16
17
|
splats.push(name)
|
|
17
18
|
return '([^/]+)'
|
|
18
19
|
})
|
|
19
|
-
.replace(/\//g, '\\/')
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
let u = removeQueryStringAndFragment(url)
|
|
22
|
+
u = removeTrailingSlash(u)
|
|
23
|
+
|
|
24
|
+
const match = u.match(new RegExp(`^${pattern}$`))
|
|
22
25
|
if (!match)
|
|
23
26
|
return {}
|
|
24
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { test } from 'node:test'
|
|
1
|
+
import { test, describe } from 'node:test'
|
|
2
2
|
import { deepEqual, equal } from 'node:assert/strict'
|
|
3
3
|
import { parseSplats, parseQueryParams } from './UrlParsers.js'
|
|
4
4
|
import { config } from '../config.js'
|
|
@@ -9,14 +9,46 @@ test('parseQueryParams', () => {
|
|
|
9
9
|
})
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
describe('parseSplats', () => {
|
|
13
|
+
test('one splat', () => {
|
|
14
|
+
const splats = parseSplats(
|
|
15
|
+
'/api/company/123',
|
|
16
|
+
`${config.mocksDir}/api/company/[companyId].GET.200.js`
|
|
17
|
+
)
|
|
18
|
+
deepEqual(splats, {
|
|
19
|
+
companyId: '123'
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('one splat with trailing slash', () => {
|
|
24
|
+
const splats = parseSplats(
|
|
25
|
+
'/api/company/123/',
|
|
26
|
+
`${config.mocksDir}/api/company/[companyId].GET.200.js`
|
|
27
|
+
)
|
|
28
|
+
deepEqual(splats, {
|
|
29
|
+
companyId: '123'
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('two splats and comment', () => {
|
|
34
|
+
const splats = parseSplats(
|
|
35
|
+
'/api/company/123/user/456',
|
|
36
|
+
`${config.mocksDir}/api/company/[companyId]/user/[userId](comments).GET.200.js`
|
|
37
|
+
)
|
|
38
|
+
deepEqual(splats, {
|
|
39
|
+
companyId: '123',
|
|
40
|
+
userId: '456',
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('ignores query string', () => {
|
|
45
|
+
const splats = parseSplats(
|
|
46
|
+
'/api/company/123?foo=456',
|
|
47
|
+
`${config.mocksDir}/api/company/[companyId]?foo=[fooId].GET.200.js`
|
|
48
|
+
)
|
|
49
|
+
deepEqual(splats, {
|
|
50
|
+
companyId: '123'
|
|
51
|
+
})
|
|
20
52
|
})
|
|
21
53
|
})
|
|
22
54
|
|