mockaton 8.0.3 → 8.1.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 +10 -10
- package/package.json +1 -1
- package/src/Dashboard.css +6 -4
- package/src/Dashboard.html +1 -1
- package/src/Dashboard.js +108 -5
- package/src/Filename.js +2 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ can be used for downloading a TAR of your XHR requests following that convention
|
|
|
15
15
|
|
|
16
16
|
## Getting Started Demo
|
|
17
17
|
- Checkout this repo
|
|
18
|
-
- `npm install tsx`
|
|
18
|
+
- `npm install tsx` (optional)
|
|
19
19
|
- `npm run demo:ts`
|
|
20
20
|
which will open the following dashboard
|
|
21
21
|
- Explore the [sample-mocks/](./sample-mocks) directory
|
|
@@ -47,7 +47,7 @@ _Reset_ button is for registering newly added, removed, or renamed mocks.
|
|
|
47
47
|
- Similarly, it allows for checking out long-lived branches that have old API contracts
|
|
48
48
|
|
|
49
49
|
## Motivation
|
|
50
|
-
- Avoids
|
|
50
|
+
- Avoids spinning up and maintaining hefty backends when developing UIs.
|
|
51
51
|
- For a deterministic and comprehensive backend state. For example, having all the possible
|
|
52
52
|
state variants of a collection helps for spotting inadvertent bugs.
|
|
53
53
|
|
|
@@ -177,7 +177,7 @@ but since that’s part of the query string, it’s ignored anyway.
|
|
|
177
177
|
|
|
178
178
|
|
|
179
179
|
### Index-like route
|
|
180
|
-
For instance, let
|
|
180
|
+
For instance, let’s say you have `api/foo/bar`, and
|
|
181
181
|
`api/foo`. For the latter you have two options:
|
|
182
182
|
|
|
183
183
|
**Option A.** Place it outside the directory:
|
|
@@ -207,11 +207,6 @@ Defaults to `0`, which means auto-assigned
|
|
|
207
207
|
Defaults to `/(\.DS_Store|~)$/`
|
|
208
208
|
|
|
209
209
|
|
|
210
|
-
### `proxyFallback?: string`
|
|
211
|
-
Lets you specify a target server for serving routes you don’t have mocks for.
|
|
212
|
-
For example, `Config.proxyFallback = 'http://example.com:8080'`
|
|
213
|
-
|
|
214
|
-
|
|
215
210
|
### `delay?: number` 🕓
|
|
216
211
|
The clock icon next to the mock selector is a checkbox for delaying a
|
|
217
212
|
particular response. They are handy for testing spinners.
|
|
@@ -219,6 +214,11 @@ particular response. They are handy for testing spinners.
|
|
|
219
214
|
The delay is globally configurable via `Config.delay = 1200` (milliseconds).
|
|
220
215
|
|
|
221
216
|
|
|
217
|
+
### `proxyFallback?: string`
|
|
218
|
+
Lets you specify a target server for serving routes you don’t have mocks for.
|
|
219
|
+
For example, `Config.proxyFallback = 'http://example.com:8080'`
|
|
220
|
+
|
|
221
|
+
|
|
222
222
|
### `staticDir?: string`
|
|
223
223
|
Files under `Config.staticDir` don’t use the filename convention.
|
|
224
224
|
Also, they take precedence over the `GET` mocks in `Config.mockDir`.
|
|
@@ -305,7 +305,7 @@ import { jsToJsonPlugin } from 'mockaton'
|
|
|
305
305
|
|
|
306
306
|
Config.plugins = [
|
|
307
307
|
[/\.(js|ts)$/, jsToJsonPlugin], // Default
|
|
308
|
-
[/\.
|
|
308
|
+
[/\.yml$/, yamlToJsonPlugin],
|
|
309
309
|
[/foo\.GET\.200\.txt$/, capitalizePlugin], // e.g. GET /api/foo would be capitalized
|
|
310
310
|
]
|
|
311
311
|
|
|
@@ -328,7 +328,7 @@ function capitalizePlugin(filePath) {
|
|
|
328
328
|
### `corsAllowed?: boolean`
|
|
329
329
|
Defaults to `corsAllowed = false`
|
|
330
330
|
|
|
331
|
-
When `corsAllowed === true`, these are the default options:
|
|
331
|
+
When `Config.corsAllowed === true`, these are the default options:
|
|
332
332
|
```js
|
|
333
333
|
Config.corsOrigins = ['*']
|
|
334
334
|
Config.corsMethods = ['GET', 'PUT', 'DELETE', 'POST', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']
|
package/package.json
CHANGED
package/src/Dashboard.css
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
@media (prefers-color-scheme: light) {
|
|
6
6
|
:root {
|
|
7
7
|
--color4xxBackground: #ffedd1;
|
|
8
|
-
--colorAccent: #
|
|
8
|
+
--colorAccent: #0072d6;
|
|
9
|
+
--colorAccentAlt: #01873b;
|
|
9
10
|
--colorBackground: #fff;
|
|
10
11
|
--colorHeaderBackground: #f4f4f4;
|
|
11
12
|
--colorComboBoxBackground: #fafafa;
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
:root {
|
|
24
25
|
--color4xxBackground: #403630;
|
|
25
26
|
--colorAccent: #1f91ff;
|
|
27
|
+
--colorAccentAlt: #00E676;
|
|
26
28
|
--colorBackground: #161616;
|
|
27
29
|
--colorHeaderBackground: #090909;
|
|
28
30
|
--colorComboBoxBackground: #252525;
|
|
@@ -286,7 +288,7 @@ main {
|
|
|
286
288
|
.ProgressBar {
|
|
287
289
|
position: relative;
|
|
288
290
|
width: 100%;
|
|
289
|
-
height:
|
|
291
|
+
height: 2px;
|
|
290
292
|
background: var(--colorComboBoxHeaderBackground);
|
|
291
293
|
|
|
292
294
|
div {
|
|
@@ -295,7 +297,7 @@ main {
|
|
|
295
297
|
left: 0;
|
|
296
298
|
height: 100%;
|
|
297
299
|
background: var(--colorAccent);
|
|
298
|
-
animation: _kfProgress;
|
|
300
|
+
animation-name: _kfProgress;
|
|
299
301
|
/*animation-duration: It's in JavaScript */
|
|
300
302
|
}
|
|
301
303
|
|
|
@@ -328,7 +330,7 @@ main {
|
|
|
328
330
|
a {
|
|
329
331
|
display: inline-block;
|
|
330
332
|
padding: 6px 0;
|
|
331
|
-
color: var(--
|
|
333
|
+
color: var(--colorAccentAlt);
|
|
332
334
|
text-decoration: none;
|
|
333
335
|
|
|
334
336
|
&:hover {
|
package/src/Dashboard.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<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
7
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
8
|
<meta name="description" content="Mock Server for developing UIs">
|
|
9
|
-
<title>
|
|
9
|
+
<title>Mockaton</title>
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<script src="/Dashboard.js" type="module"></script>
|
package/src/Dashboard.js
CHANGED
|
@@ -6,16 +6,17 @@ import { DEFAULT_500_COMMENT } from '/ApiConstants.js'
|
|
|
6
6
|
const Strings = {
|
|
7
7
|
allow_cors: 'Allow CORS',
|
|
8
8
|
bulk_select_by_comment: 'Bulk Select by Comment',
|
|
9
|
+
bulk_select_by_comment_disabled_title: 'No mock files have comments, which are anything within parentheses on the filename.',
|
|
9
10
|
click_link_to_preview: 'Click a link to preview it',
|
|
10
11
|
cookie: 'Cookie',
|
|
12
|
+
cookie_disabled_title: 'No cookies specified in Config.cookies',
|
|
11
13
|
delay: 'Delay',
|
|
12
14
|
empty_response_body: '/* Empty Response Body */',
|
|
13
15
|
internal_server_error: 'Internal Server Error',
|
|
14
16
|
mock: 'Mock',
|
|
15
17
|
reset: 'Reset',
|
|
16
18
|
select_one: 'Select One',
|
|
17
|
-
static: 'Static'
|
|
18
|
-
title: 'Mockaton'
|
|
19
|
+
static: 'Static'
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const CSS = {
|
|
@@ -59,7 +60,6 @@ function App([brokersByMethod, cookies, comments, corsAllowed, staticFiles]) {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
function DevPanel(brokersByMethod, cookies, comments, corsAllowed, staticFiles) {
|
|
62
|
-
document.title = Strings.title
|
|
63
63
|
return (
|
|
64
64
|
r('div', null,
|
|
65
65
|
r('menu', null,
|
|
@@ -79,12 +79,14 @@ function DevPanel(brokersByMethod, cookies, comments, corsAllowed, staticFiles)
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function CookieSelector({ list }) {
|
|
82
|
+
const disabled = list.length <= 1
|
|
82
83
|
return (
|
|
83
84
|
r('label', null,
|
|
84
85
|
r('span', null, Strings.cookie),
|
|
85
86
|
r('select', {
|
|
86
87
|
autocomplete: 'off',
|
|
87
|
-
disabled
|
|
88
|
+
disabled,
|
|
89
|
+
title: disabled ? Strings.cookie_disabled_title : '',
|
|
88
90
|
onChange() {
|
|
89
91
|
mockaton.selectCookie(this.value)
|
|
90
92
|
.catch(console.error)
|
|
@@ -107,6 +109,7 @@ function BulkSelector({ comments }) {
|
|
|
107
109
|
r('select', {
|
|
108
110
|
autocomplete: 'off',
|
|
109
111
|
disabled,
|
|
112
|
+
title: disabled ? Strings.bulk_select_by_comment_disabled_title : '',
|
|
110
113
|
onChange() {
|
|
111
114
|
mockaton.bulkSelectByComment(this.value)
|
|
112
115
|
.then(init)
|
|
@@ -202,7 +205,10 @@ function PreviewLink({ method, urlMask }) {
|
|
|
202
205
|
renderPayloadImage(this.href)
|
|
203
206
|
else
|
|
204
207
|
updatePayloadViewer(await res.text() || Strings.empty_response_body, mime)
|
|
205
|
-
refPayloadFile.current
|
|
208
|
+
empty(refPayloadFile.current)
|
|
209
|
+
refPayloadFile.current.append(PayloadViewerTitle({
|
|
210
|
+
file: this.closest('tr').querySelector('select').value
|
|
211
|
+
}))
|
|
206
212
|
}
|
|
207
213
|
catch (error) {
|
|
208
214
|
console.error(error)
|
|
@@ -211,6 +217,15 @@ function PreviewLink({ method, urlMask }) {
|
|
|
211
217
|
}, urlMask))
|
|
212
218
|
}
|
|
213
219
|
|
|
220
|
+
function PayloadViewerTitle({ file }) {
|
|
221
|
+
const { urlMask, method, status, ext } = parseFilename(file)
|
|
222
|
+
return (
|
|
223
|
+
r('span', null,
|
|
224
|
+
urlMask + '.' + method + '.',
|
|
225
|
+
r('abbr', { title: HttpStatus[status] }, status),
|
|
226
|
+
'.' + ext))
|
|
227
|
+
}
|
|
228
|
+
|
|
214
229
|
function ProgressBar() {
|
|
215
230
|
return (
|
|
216
231
|
r('div', { className: CSS.ProgressBar },
|
|
@@ -382,3 +397,91 @@ function createSvgElement(tagName, props, ...children) {
|
|
|
382
397
|
function useRef() {
|
|
383
398
|
return { current: null }
|
|
384
399
|
}
|
|
400
|
+
|
|
401
|
+
const HttpStatus = {
|
|
402
|
+
100: 'Continue',
|
|
403
|
+
101: 'Switching Protocols',
|
|
404
|
+
102: 'Processing',
|
|
405
|
+
103: 'Early Hints',
|
|
406
|
+
200: 'OK',
|
|
407
|
+
201: 'Created',
|
|
408
|
+
202: 'Accepted',
|
|
409
|
+
203: 'Non-Authoritative Information',
|
|
410
|
+
204: 'No Content',
|
|
411
|
+
205: 'Reset Content',
|
|
412
|
+
206: 'Partial Content',
|
|
413
|
+
207: 'Multi-Status',
|
|
414
|
+
208: 'Already Reported',
|
|
415
|
+
218: 'This is fine (Apache Web Server)',
|
|
416
|
+
226: 'IM Used',
|
|
417
|
+
300: 'Multiple Choices',
|
|
418
|
+
301: 'Moved Permanently',
|
|
419
|
+
302: 'Found',
|
|
420
|
+
303: 'See Other',
|
|
421
|
+
304: 'Not Modified',
|
|
422
|
+
306: 'Switch Proxy',
|
|
423
|
+
307: 'Temporary Redirect',
|
|
424
|
+
308: 'Resume Incomplete',
|
|
425
|
+
400: 'Bad Request',
|
|
426
|
+
401: 'Unauthorized',
|
|
427
|
+
402: 'Payment Required',
|
|
428
|
+
403: 'Forbidden',
|
|
429
|
+
404: 'Not Found',
|
|
430
|
+
405: 'Method Not Allowed',
|
|
431
|
+
406: 'Not Acceptable',
|
|
432
|
+
407: 'Proxy Authentication Required',
|
|
433
|
+
408: 'Request Timeout',
|
|
434
|
+
409: 'Conflict',
|
|
435
|
+
410: 'Gone',
|
|
436
|
+
411: 'Length Required',
|
|
437
|
+
412: 'Precondition Failed',
|
|
438
|
+
413: 'Request Entity Too Large',
|
|
439
|
+
414: 'Request-URI Too Long',
|
|
440
|
+
415: 'Unsupported Media Type',
|
|
441
|
+
416: 'Requested Range Not Satisfiable',
|
|
442
|
+
417: 'Expectation Failed',
|
|
443
|
+
418: 'I’m a teapot',
|
|
444
|
+
419: 'Page Expired (Laravel Framework)',
|
|
445
|
+
420: 'Method Failure (Spring Framework)',
|
|
446
|
+
421: 'Misdirected Request',
|
|
447
|
+
422: 'Unprocessable Entity',
|
|
448
|
+
423: 'Locked',
|
|
449
|
+
424: 'Failed Dependency',
|
|
450
|
+
426: 'Upgrade Required',
|
|
451
|
+
428: 'Precondition Required',
|
|
452
|
+
429: 'Too Many Requests',
|
|
453
|
+
431: 'Request Header Fields Too Large',
|
|
454
|
+
440: 'Login Time-out',
|
|
455
|
+
444: 'Connection Closed Without Response',
|
|
456
|
+
449: 'Retry With',
|
|
457
|
+
450: 'Blocked by Windows Parental Controls',
|
|
458
|
+
451: 'Unavailable For Legal Reasons',
|
|
459
|
+
494: 'Request Header Too Large',
|
|
460
|
+
495: 'SSL Certificate Error',
|
|
461
|
+
496: 'SSL Certificate Required',
|
|
462
|
+
497: 'HTTP Request Sent to HTTPS Port',
|
|
463
|
+
498: 'Invalid Token (Esri)',
|
|
464
|
+
499: 'Client Closed Request',
|
|
465
|
+
500: 'Internal Server Error',
|
|
466
|
+
501: 'Not Implemented',
|
|
467
|
+
502: 'Bad Gateway',
|
|
468
|
+
503: 'Service Unavailable',
|
|
469
|
+
504: 'Gateway Timeout',
|
|
470
|
+
505: 'HTTP Version Not Supported',
|
|
471
|
+
506: 'Variant Also Negotiates',
|
|
472
|
+
507: 'Insufficient Storage',
|
|
473
|
+
508: 'Loop Detected',
|
|
474
|
+
509: 'Bandwidth Limit Exceeded',
|
|
475
|
+
510: 'Not Extended',
|
|
476
|
+
511: 'Network Authentication Required',
|
|
477
|
+
520: 'Unknown Error',
|
|
478
|
+
521: 'Web Server Is Down',
|
|
479
|
+
522: 'Connection Timed Out',
|
|
480
|
+
523: 'Origin Is Unreachable',
|
|
481
|
+
524: 'A Timeout Occurred',
|
|
482
|
+
525: 'SSL Handshake Failed',
|
|
483
|
+
526: 'Invalid SSL Certificate',
|
|
484
|
+
527: 'Railgun Listener to Origin Error',
|
|
485
|
+
530: 'Origin DNS Error',
|
|
486
|
+
598: 'Network Read Timeout Error'
|
|
487
|
+
}
|
package/src/Filename.js
CHANGED