mockaton 8.2.5 → 8.2.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <img src="src/mockaton-logo.svg" alt="Mockaton Logo" width="210" style="margin-top: 30px"/>
2
2
 
3
- _Mockaton_ is a mock server for developing and testing frontends.
3
+ _Mockaton_ is a mock server for improving the frontend development and testing experience.
4
4
 
5
5
  The mock filename convention is similar to the URL paths. For
6
6
  example, the following file will be served on `/api/user/1234`
@@ -8,9 +8,12 @@ example, the following file will be served on `/api/user/1234`
8
8
  my-mocks-dir/api/user/[user-id].GET.200.json
9
9
  ```
10
10
 
11
- By the way, [this browser
12
- extension](https://github.com/ericfortis/devtools-ext-tar-http-requests)
13
- can create a TAR of your XHR requests following that convention.
11
+ By the way, [this browser extension](https://github.com/ericfortis/devtools-ext-tar-http-requests)
12
+ can create a TAR of your requests following that convention.
13
+
14
+ Nonetheless, you don’t need to mock everything. Indicate
15
+ your backend address in `Config.proxyFallback`, and Mockaton
16
+ will request from it routes you don’t have mocks for.
14
17
 
15
18
  ### Dashboard Example
16
19
 
@@ -33,7 +36,7 @@ import { resolve } from 'node:path'
33
36
  import { Mockaton } from 'mockaton'
34
37
 
35
38
 
36
- // The Config options are explained in a section below
39
+ // See the Config section below for more options
37
40
  Mockaton({
38
41
  mocksDir: resolve('my-mocks-dir'),
39
42
  port: 2345
@@ -56,8 +59,7 @@ This demo uses the [sample-mocks/](./sample-mocks) directory of this repository.
56
59
 
57
60
  Experiment with the Dashboard:
58
61
 
59
- - Pick a mock variant from the Mock dropdown (we’ll discuss
60
- them later)
62
+ - Pick a mock variant from the Mock dropdown (we’ll discuss them later)
61
63
  - Toggle the 🕓 Clock button, which _Delays_ responses (e.g. for testing spinners)
62
64
  - Toggle the _500_ button, which sends and _Internal Server Error_ on that endpoint
63
65
 
@@ -122,10 +124,14 @@ export default [
122
124
  **Option B:** Function
123
125
 
124
126
  Think of this as an HTTP handler. You can read or write to a
125
- database, or pull data from a backend.
127
+ database, or pull data from a backend. Also, you can modify the
128
+ response object, e.g. for changing the status code and mime.
126
129
 
127
130
  Don’t call `response.end()`, just return a `string | Buffer | Uint8Array`.
128
131
 
132
+ If you need to serve a static `.js` file, put it in your
133
+ `Config.staticDir` without the mock filename convention.
134
+
129
135
  ```js
130
136
  export default function requestCounter(request, response) {
131
137
  globalThis.myDatabase ??= { count: 0 }
@@ -136,11 +142,8 @@ export default function requestCounter(request, response) {
136
142
  }
137
143
  ```
138
144
 
139
- If you need to serve a static `.js` file, put it in your
140
- `Config.staticDir` without the mock filename convention.
141
-
145
+ This example will echo the request body concatenated with another fixture.
142
146
  ```js
143
- // This example will echo the request body concatenated with another fixture.
144
147
  // api/color.POST.201.js
145
148
 
146
149
  import colors from './colors.json' with { type: 'json' }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mockaton",
3
3
  "description": "A deterministic server-side for developing and testing frontend clients",
4
4
  "type": "module",
5
- "version": "8.2.5",
5
+ "version": "8.2.7",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
package/src/Dashboard.css CHANGED
@@ -5,7 +5,7 @@
5
5
  @media (prefers-color-scheme: light) {
6
6
  :root {
7
7
  --color4xxBackground: #ffedd1;
8
- --colorAccent: #0081ef;
8
+ --colorAccent: #0078e1;
9
9
  --colorAccentAlt: #009c71;
10
10
  --colorBackground: #fff;
11
11
  --colorHeaderBackground: #f7f7f7;
@@ -13,7 +13,7 @@
13
13
  --colorComboBoxHeaderBackground: #fff;
14
14
  --colorDisabled: #444;
15
15
  --colorHover: #dfefff;
16
- --colorLabel: #666;
16
+ --colorLabel: #444;
17
17
  --colorLightRed: #ffe4ee;
18
18
  --colorRed: #da0f00;
19
19
  --colorSecondaryButtonBackground: #fafafa;
@@ -105,7 +105,7 @@ menu {
105
105
 
106
106
  input[type=url],
107
107
  select {
108
- height: 24px;
108
+ height: 28px;
109
109
  width: 150px;
110
110
  padding: 4px 2px;
111
111
  border-right: 3px solid transparent;
@@ -123,8 +123,9 @@ menu {
123
123
  }
124
124
  }
125
125
 
126
- button {
126
+ .ResetButton {
127
127
  padding: 4px 12px;
128
+ margin-bottom: 4px;
128
129
  border: 1px solid var(--colorRed);
129
130
  background: transparent;
130
131
  color: var(--colorRed);
@@ -141,7 +142,7 @@ menu {
141
142
  .CorsCheckbox {
142
143
  display: flex;
143
144
  align-items: center;
144
- margin-bottom: 4px;
145
+ margin-bottom: 8px;
145
146
  gap: 4px;
146
147
  }
147
148
  }
@@ -150,7 +151,7 @@ menu {
150
151
  main {
151
152
  display: flex;
152
153
  align-items: flex-start;
153
- margin-top: 56px;
154
+ margin-top: 64px;
154
155
 
155
156
  > table {
156
157
  border-collapse: collapse;
@@ -333,6 +334,7 @@ main {
333
334
  summary {
334
335
  margin-bottom: 8px;
335
336
  cursor: pointer;
337
+ font-weight: bold;
336
338
  }
337
339
 
338
340
  li {
package/src/Dashboard.js CHANGED
@@ -12,7 +12,7 @@ const Strings = {
12
12
  cookie_disabled_title: 'No cookies specified in Config.cookies',
13
13
  delay: 'Delay',
14
14
  empty_response_body: '/* Empty Response Body */',
15
- fallback_server: 'Fallback Server',
15
+ fallback_server: 'Fallback Backend',
16
16
  fallback_server_placeholder: 'Type Server Address',
17
17
  internal_server_error: 'Internal Server Error',
18
18
  mock: 'Mock',
@@ -22,6 +22,7 @@ const Strings = {
22
22
  }
23
23
 
24
24
  const CSS = {
25
+ ResetButton: 'ResetButton',
25
26
  CorsCheckbox: 'CorsCheckbox',
26
27
  DelayToggler: 'DelayToggler',
27
28
  InternalServerErrorToggler: 'InternalServerErrorToggler',
@@ -42,6 +43,7 @@ const refPayloadViewerFileTitle = useRef()
42
43
 
43
44
  const mockaton = new Commander(window.location.origin)
44
45
 
46
+
45
47
  function init() {
46
48
  Promise.all([
47
49
  mockaton.listMocks(),
@@ -52,7 +54,7 @@ function init() {
52
54
  mockaton.listStaticFiles()
53
55
  ].map(api => api.then(response => response.ok && response.json())))
54
56
  .then(App)
55
- .catch(console.error)
57
+ .catch(onError)
56
58
  }
57
59
  init()
58
60
 
@@ -86,7 +88,7 @@ function DevPanel([brokersByMethod, cookies, comments, corsAllowed, fallbackAddr
86
88
  function CookieSelector({ list }) {
87
89
  function onChange() {
88
90
  mockaton.selectCookie(this.value)
89
- .catch(console.error)
91
+ .catch(onError)
90
92
  }
91
93
  const disabled = list.length <= 1
92
94
  return (
@@ -107,7 +109,7 @@ function BulkSelector({ comments }) {
107
109
  function onChange() {
108
110
  mockaton.bulkSelectByComment(this.value)
109
111
  .then(init)
110
- .catch(console.error)
112
+ .catch(onError)
111
113
  }
112
114
  const disabled = !comments.length
113
115
  const list = disabled
@@ -135,7 +137,7 @@ function ProxyFallbackField({ fallbackAddress = '' }) {
135
137
  input.reportValidity()
136
138
  else
137
139
  mockaton.setProxyFallback(input.value)
138
- .catch(console.error)
140
+ .catch(onError)
139
141
  }
140
142
 
141
143
  return (
@@ -154,7 +156,7 @@ function ProxyFallbackField({ fallbackAddress = '' }) {
154
156
  function CorsCheckbox({ corsAllowed }) {
155
157
  function onChange(event) {
156
158
  mockaton.setCorsAllowed(event.currentTarget.checked)
157
- .catch(console.error)
159
+ .catch(onError)
158
160
  }
159
161
  return (
160
162
  r('label', { className: CSS.CorsCheckbox },
@@ -170,10 +172,11 @@ function CorsCheckbox({ corsAllowed }) {
170
172
  function ResetButton() {
171
173
  return (
172
174
  r('button', {
175
+ className: CSS.ResetButton,
173
176
  onClick() {
174
177
  mockaton.reset()
175
178
  .then(init)
176
- .catch(console.error)
179
+ .catch(onError)
177
180
  }
178
181
  }, Strings.reset))
179
182
  }
@@ -240,7 +243,7 @@ function PreviewLink({ method, urlMask }) {
240
243
  }))
241
244
  }
242
245
  catch (error) {
243
- console.error(error)
246
+ onError(error)
244
247
  }
245
248
  }
246
249
  return (
@@ -295,7 +298,7 @@ function MockSelector({ broker }) {
295
298
  this.closest('tr').querySelector(`.${CSS.InternalServerErrorToggler}>[type=checkbox]`).checked = status === 500
296
299
  this.className = className(this.value === this.options[0].value, status)
297
300
  })
298
- .catch(console.error)
301
+ .catch(onError)
299
302
  }
300
303
 
301
304
  function className(defaultIsSelected, status) {
@@ -331,7 +334,7 @@ function DelayRouteToggler({ broker }) {
331
334
  function onChange(event) {
332
335
  const { method, urlMask } = parseFilename(this.name)
333
336
  mockaton.setRouteIsDelayed(method, urlMask, event.currentTarget.checked)
334
- .catch(console.error)
337
+ .catch(onError)
335
338
  }
336
339
  return (
337
340
  r('label', {
@@ -361,7 +364,7 @@ function InternalServerErrorToggler({ broker }) {
361
364
  ? broker.mocks.find(f => parseFilename(f).status === 500)
362
365
  : broker.mocks[0])
363
366
  .then(init)
364
- .catch(console.error)
367
+ .catch(onError)
365
368
  }
366
369
  return (
367
370
  r('label', {
@@ -380,6 +383,12 @@ function InternalServerErrorToggler({ broker }) {
380
383
  }
381
384
 
382
385
 
386
+ function onError(error) {
387
+ if (error?.message === 'Failed to fetch')
388
+ alert('Looks like the Mockaton server is not running')
389
+ console.error(error)
390
+ }
391
+
383
392
 
384
393
  /* === Utils === */
385
394
  function cssClass(...args) {
@@ -43,7 +43,7 @@ export async function dispatchMock(req, response) {
43
43
  sendNotFound(response)
44
44
  else if (error.code === 'ERR_UNKNOWN_FILE_EXTENSION') {
45
45
  if (error.toString().includes('Unknown file extension ".ts'))
46
- console.error('Looks like you need a TypeScript compiler')
46
+ console.error('\nLooks like you need a TypeScript compiler\n')
47
47
  sendInternalServerError(response, error)
48
48
  }
49
49
  else