mockaton 8.12.0 → 8.12.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/README.md CHANGED
@@ -3,10 +3,10 @@
3
3
  ![NPM Version](https://img.shields.io/npm/v/mockaton)
4
4
  ![NPM Version](https://img.shields.io/npm/l/mockaton)
5
5
 
6
- Mockaton is an HTTP mock server for enhancing the development and testing experience.
7
-
8
- ## Convention over Code
6
+ An HTTP mock server for simulating APIs with minimal setup
7
+ — ideal for testing edge cases and prototyping UIs.
9
8
 
9
+ ## Convention Over Code
10
10
  With Mockaton you don’t need to write code for wiring mocks. Instead, it scans a
11
11
  given directory for filenames following a convention similar to the URLs.
12
12
 
@@ -31,12 +31,14 @@ for setting up tests. See **Commander API** section.
31
31
  </picture>
32
32
 
33
33
 
34
+ <br/>
35
+ <br/>
36
+
34
37
  ## Multiple Mock Variants
35
- Each route can have different mocks. There’s two options for doing that:
38
+ Each route can have different mocks. There are two options for doing that:
36
39
 
37
40
  ### Adding comments to the filename
38
- Comments are anything within parentheses,
39
- including them. A filename can have many comments.
41
+ Comments are anything within parentheses, including them.
40
42
 
41
43
  <pre>
42
44
  api/login<b>(locked out user)</b>.POST.423.json
@@ -44,8 +46,8 @@ api/login<b>(invalid login attempt)</b>.POST.401.json
44
46
  </pre>
45
47
 
46
48
  ### Different response status code
47
- For instance, using a `4xx` or `5xx` status code for triggering error
48
- responses. Or a `2xx` such as `204` (No Content) for testing empty collections.
49
+ For instance, you can use a `4xx` or `5xx` status code for triggering error
50
+ responses, or a `2xx` such as `204` (No Content) for testing empty collections.
49
51
 
50
52
  <pre>
51
53
  api/videos(empty list).GET.<b>204</b>.json
@@ -54,16 +56,19 @@ api/videos.GET.<b>500</b>.txt
54
56
  </pre>
55
57
 
56
58
 
59
+ <br/>
57
60
 
58
- ## Fallback to your Backend
59
- No need to mock everything. Mockaton can request from your backend the routes
61
+ ## Fallback to Your Backend
62
+ No need to mock everything. Mockaton can forward requests to your backend for routes
60
63
  you don’t have mocks for, or routes that have the ☁️ **Cloud Checkbox** checked.
61
64
 
62
65
 
63
- ### Scrapping Mocks from your Backend
66
+ ### Scraping mocks from your backend
64
67
  If you check **Save Mocks**, Mockaton will collect the responses that hit your backend.
65
- They will be saved on your `config.mocksDir` following the filename convention.
68
+ They will be saved in your `config.mocksDir` following the filename convention.
69
+
66
70
 
71
+ <br/>
67
72
 
68
73
 
69
74
  ## Basic Usage
@@ -91,11 +96,12 @@ Mockaton({
91
96
  node --import=tsx my-mockaton.js
92
97
  ```
93
98
 
99
+ <br/>
94
100
 
95
101
  ## Demo App (Vite)
96
102
 
97
103
  This is a minimal React + Vite + Mockaton app. It’s a list of
98
- colors, which contains all of their possible states. For example,
104
+ colors containing all of their possible states. For example,
99
105
  permutations for out-of-stock, new-arrival, and discontinued.
100
106
 
101
107
  ```sh
@@ -114,6 +120,7 @@ The app looks like this:
114
120
 
115
121
  <img src="./demo-app-vite/pixaton-tests/pic-for-readme.vp500x800.light.gold.png" alt="Mockaton Demo App Screenshot" width="500" />
116
122
 
123
+ <br/>
117
124
 
118
125
  ## Use Cases
119
126
  ### Testing
@@ -121,34 +128,35 @@ The app looks like this:
121
128
  - Spinners by delaying responses
122
129
  - Errors such as _Bad Request_ and _Internal Server Error_
123
130
  - Setting up UI tests
131
+ - Mocking third-party APIs
124
132
  - Polled resources (for triggering their different states)
125
133
  - alerts
126
134
  - notifications
127
135
  - slow to build resources
128
- - Mocking third-party APIs
129
136
 
130
- ### Time Travel
131
- If you commit the mocks to your repo, it’s straightforward to bisect bugs and
132
- checking out long-lived branches. In other words, you don’t have to downgrade
133
- backends to old API contracts or databases.
137
+ ### Time travel
138
+ If you commit the mocks to your repo, it’s straightforward to
139
+ bisect bugs and check out long-lived branches, so you don’t
140
+ have to downgrade backends to old API contracts or databases.
141
+
142
+ ### Simulating complex backend states
143
+ Sometimes, the ideal flow you need is too difficult to reproduce from your actual backend.
144
+ For this, you can **Bulk Select** mocks by comments to simulate the complete states
145
+ you want. For example, by adding `(demo-part1)`, `(demo-part2)` to the filenames.
134
146
 
135
- ### Deterministic Standalone Demo Server
136
- Perhaps you need to demo your app, but the ideal flow is too complex to
137
- simulate from the actual backend. In this case, compile your frontend app and
138
- put its built assets in `config.staticDir`. Then, on the dashboard
139
- **Bulk Select** mocks to simulate the complete states you want to demo.
140
- For bulk-selecting, you just need to add a comment to the mock
141
- filename, such as `(demo-part1)`, `(demo-part2)`.
147
+ Similarly, you can deploy a **Standalone Demo Server** by compiling the frontend app and
148
+ putting its built assets in `config.staticDir`. And simulate the flow by Bulk Selecting mocks.
142
149
 
143
150
 
151
+ <br/>
152
+
144
153
  ## Motivation
145
- - Avoids spinning up and maintaining hefty backends when developing UIs.
146
- - For a deterministic, comprehensive, and consistent backend state. For example, having
154
+ - Avoids spinning up and updating hefty backends when developing UIs.
155
+ - Allows for a deterministic, comprehensive, and consistent backend state. For example, having
147
156
  a collection with all the possible state variants helps for spotting inadvertent bugs.
148
- - Sometimes frontend progress is blocked waiting for some backend API. Similarly,
149
- it’s often delayed due to missing data or inconvenient contracts. Therefore,
150
- many meetings can be saved by prototyping frontend features with mocks, and
151
- then showing those contracts to the backend team.
157
+ - Sometimes frontend progress is blocked by waiting for backend APIs.
158
+
159
+ <br/>
152
160
 
153
161
  ## Alternatives
154
162
  - Chrome DevTools allows for [overriding responses](https://developer.chrome.com/docs/devtools/overrides)
@@ -158,7 +166,8 @@ filename, such as `(demo-part1)`, `(demo-part2)`.
158
166
  - [Fetch Mock](https://github.com/wheresrhys/fetch-mock)
159
167
  - [Mentoss](https://github.com/humanwhocodes/mentoss)
160
168
 
161
- ---
169
+
170
+ <br/>
162
171
 
163
172
  ## You can write JSON mocks in JavaScript or TypeScript
164
173
  For example, `api/foo.GET.200.js`
@@ -179,7 +188,7 @@ export default (request, response) =>
179
188
  JSON.stringify({ foo: 'bar' })
180
189
  ```
181
190
 
182
- Think of these functions as HTTP handlers, so you can
191
+ Think of these functions as HTTP handlers that allow you to
183
192
  intercept requests. For example, for writing to a database.
184
193
 
185
194
  <details>
@@ -221,7 +230,7 @@ export default function listColors() {
221
230
  **What if I need to serve a static .js?**
222
231
  Put it in your `config.staticDir` without the mock filename convention.
223
232
 
224
- ---
233
+ <br/>
225
234
 
226
235
  ## Mock Filename Convention
227
236
 
@@ -256,7 +265,7 @@ want a `Content-Type` header in the response.
256
265
  </p>
257
266
  </details>
258
267
 
259
- ### Dynamic Parameters
268
+ ### Dynamic parameters
260
269
  Anything within square brackets is always matched. For example, for this route
261
270
  `/api/company/1234/user/5678`
262
271
  <pre>
@@ -265,14 +274,16 @@ api/company/<b>[id]</b>/user/<b>[uid]</b>.GET.200.json
265
274
 
266
275
  ### Comments
267
276
  Comments are anything within parentheses, including them.
268
- They are ignored for URL purposes, so they have no effect
277
+ They are ignored for routing purposes, so they have no effect
269
278
  on the URL mask. For example, these two are for `/api/foo`
270
279
  <pre>
271
280
  api/foo<b>(my comment)</b>.GET.200.json
272
281
  api/foo.GET.200.json
273
282
  </pre>
274
283
 
275
- ### Default Mock for a Route
284
+ A filename can have many comments.
285
+
286
+ ### Default mock for a route
276
287
  You can add the comment: `(default)`.
277
288
  Otherwise, the first file in **alphabetical order** wins.
278
289
 
@@ -281,7 +292,7 @@ api/user<b>(default)</b>.GET.200.json
281
292
  </pre>
282
293
 
283
294
 
284
- ### Query String Params
295
+ ### Query string params
285
296
  The query string is ignored when routing to it. In other words, it’s only used for
286
297
  documenting the URL contract.
287
298
  <pre>
@@ -307,7 +318,8 @@ api/foo/.GET.200.json
307
318
  api/foo/bar.GET.200.json
308
319
  ```
309
320
 
310
- ---
321
+ <br/>
322
+
311
323
  ## Config
312
324
  ### `mocksDir: string`
313
325
  This is the only required field. The directory must exist.
@@ -354,7 +366,7 @@ a unique filename comment.
354
366
 
355
367
 
356
368
  <details>
357
- <summary>Extension Details</summary>
369
+ <summary>Extension details</summary>
358
370
  <p>
359
371
  An <code>.empty</code> extension means the <code>Content-Type</code>
360
372
  header was not sent by your backend.
@@ -378,12 +390,12 @@ of `JSON.stringify(data, null, ' ')` (two spaces indentation).
378
390
  build your frontend bundle, and serve it from Mockaton.
379
391
 
380
392
  Files under `config.staticDir` don’t use the filename convention, and
381
- they take precedence over `GET` mocks in `config.mocksDir`.
393
+ they take precedence over corresponding `GET` mocks in `config.mocksDir`.
382
394
  For example, if you have two files for `GET /foo/bar.jpg`
383
395
 
384
396
  <pre>
385
397
  my-static-dir<b>/foo/bar.jpg</b>
386
- my-mocks-dir<b>/foo/bar.jpg</b>.GET.200.jpg // Unreacheable
398
+ my-mocks-dir<b>/foo/bar.jpg</b>.GET.200.jpg // Unreachable
387
399
  </pre>
388
400
 
389
401
 
@@ -412,7 +424,7 @@ In other words, it’s useful only if you care about its payload.
412
424
 
413
425
 
414
426
  ### `extraHeaders?: string[]`
415
- Note it’s a unidimensional array. The header name goes at even indices.
427
+ Note: it’s a one-dimensional array. The header name goes at even indices.
416
428
 
417
429
  ```js
418
430
  config.extraHeaders = [
@@ -451,7 +463,7 @@ the file from disk and compute the MIME from the extension.
451
463
  Note: don’t call `response.end()` on any plugin.
452
464
 
453
465
  <details>
454
- <summary><b> See Plugin Examples </b></summary>
466
+ <summary><b> See plugin examples </b></summary>
455
467
 
456
468
  ```shell
457
469
  npm install yaml
@@ -512,7 +524,7 @@ config.onReady = () => {}
512
524
 
513
525
  At any rate, you can trigger any command besides opening a browser.
514
526
 
515
- ---
527
+ <br/>
516
528
 
517
529
  ## Commander API
518
530
  `Commander` is a client for Mockaton’s HTTP API.
@@ -536,12 +548,12 @@ Parentheses are optional, so you can pass a partial match.
536
548
  For example, passing `'demo-'` (without the final `a`), selects the
537
549
  first mock in alphabetical order that matches.
538
550
 
539
- ### Set Route is Delayed Flag
551
+ ### Set route is delayed flag
540
552
  ```js
541
553
  await mockaton.setRouteIsDelayed('GET', '/api/foo', true)
542
554
  ```
543
555
 
544
- ### Set Route is Proxied
556
+ ### Set route is proxied
545
557
  ```js
546
558
  await mockaton.setRouteIsProxied('GET', '/api/foo', true)
547
559
  ```
@@ -552,13 +564,13 @@ In `config.cookies`, each key is the label used for selecting it.
552
564
  await mockaton.selectCookie('My Normal User')
553
565
  ```
554
566
 
555
- ### Set Fallback Proxy
567
+ ### Set fallback proxy
556
568
  ```js
557
569
  await mockaton.setProxyFallback('http://example.com')
558
570
  ```
559
571
  Pass an empty string to disable it.
560
572
 
561
- ### Set Save Proxied Mocks
573
+ ### Set save proxied mocks
562
574
  ```js
563
575
  await mockaton.setCollectProxied(true)
564
576
  ```
@@ -569,7 +581,3 @@ default, but the `proxyFallback`, `colledProxied`, and `corsAllowed` are not aff
569
581
  ```js
570
582
  await mockaton.reset()
571
583
  ```
572
-
573
- <div style="display: flex; align-items: center; gap: 20px">
574
- <img src="fixtures-mocks/api/user/avatar.GET.200.png" width="170"/>
575
- </div>
package/package.json CHANGED
@@ -2,13 +2,14 @@
2
2
  "name": "mockaton",
3
3
  "description": "A deterministic server-side for developing and testing APIs",
4
4
  "type": "module",
5
- "version": "8.12.0",
5
+ "version": "8.12.2",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
9
9
  "repository": "https://github.com/ericfortis/mockaton",
10
10
  "scripts": {
11
11
  "test": "node --test \"src/**/*.test.js\"",
12
+ "coverage": "node --test --test-reporter=lcov --test-reporter-destination=.coverage/lcov.info --experimental-test-coverage \"src/**/*.test.js\"",
12
13
  "start": "node dev-mockaton.js",
13
14
  "start:ts": "node --import=tsx dev-mockaton.js",
14
15
  "pixaton": "node --test --import=./pixaton-tests/_setup.js --experimental-test-isolation=none \"pixaton-tests/**/*.test.js\"",
package/src/Mockaton.js CHANGED
@@ -20,14 +20,15 @@ export function Mockaton(options) {
20
20
  watchMocksDir()
21
21
 
22
22
  return createServer(onRequest).listen(config.port, config.host, function (error) {
23
+ if (error) {
24
+ console.error(error)
25
+ return
26
+ }
23
27
  const { address, port } = this.address()
24
28
  const url = `http://${address}:${port}`
25
29
  console.log('Listening', url)
26
30
  console.log('Dashboard', url + API.dashboard)
27
- if (error)
28
- console.error(error)
29
- else
30
- config.onReady(url + API.dashboard)
31
+ config.onReady(url + API.dashboard)
31
32
  })
32
33
  }
33
34
 
package/src/ProxyRelay.js CHANGED
@@ -43,7 +43,7 @@ export async function proxy(req, response, delay) {
43
43
  let data = body
44
44
  if (config.formatCollectedJSON && ext === 'json') // TESTME
45
45
  try {
46
- data = JSON.string(JSON.parse(body), null, ' ')
46
+ data = JSON.stringify(JSON.parse(body), null, ' ')
47
47
  }
48
48
  catch {}
49
49
  write(join(config.mocksDir, filename), data)
@@ -20,7 +20,7 @@ export async function dispatchStatic(req, response) {
20
20
  await sendPartialContent(response, req.headers.range, file)
21
21
  else {
22
22
  response.setHeader('Content-Type', mimeFor(file))
23
- response.end(readFileSync(file, 'utf8'))
23
+ response.end(readFileSync(file))
24
24
  }
25
25
  }
26
26
 
@@ -57,7 +57,3 @@ async function sendPartialContent(response, range, file) {
57
57
  })
58
58
  }
59
59
  }
60
-
61
-
62
-
63
-