mockaton 8.2.19 → 8.2.21

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
@@ -17,20 +17,21 @@ By the way, [this browser
17
17
  extension](https://github.com/ericfortis/devtools-ext-tar-http-requests)
18
18
  can create a TAR of your requests following that convention.
19
19
 
20
- Nonetheless, you don’t need to mock all your APIs. Mockaton can request from your backend
21
- the routes you don’t have mocks for. That’s done with `config.proxyFallback = 'http://mybackend'`
20
+ Nonetheless, you don’t need to mock all your APIs. If you don’t add
21
+ a mock for some route, Mockaton can request it from your backend.
22
+ That’s done with `config.proxyFallback = 'http://mybackend'`
22
23
 
23
24
  ## Multiple Mock Variants
24
25
  Each route can have many mocks, which could either be:
25
26
  - Different response __status code__. For example, for triggering errors.
26
27
  - __Comment__ on the filename, which is anything within parentheses.
27
- For example, `api/login(locked out user).POST.423.json`
28
+ - e.g. `api/login(locked out user).POST.423.json`
28
29
 
29
30
 
30
31
  ## Dashboard UI
31
32
 
32
33
  In the dashboard, you can select a mock variant for a particular
33
- route, among other options. But there’s also a programmatic API,
34
+ route, among other options. In addition, there’s a programmatic API,
34
35
  which is handy for setting up tests (see **Commander API** below).
35
36
 
36
37
  <picture>
@@ -64,12 +65,14 @@ node --import=tsx my-mockaton.js
64
65
 
65
66
 
66
67
  ## Running the Demo Example
67
- This demo uses the [sample-mocks/](./sample-mocks) directory of this repository.
68
+ This demo uses the [sample-mocks/](./sample-mocks) of this repository.
68
69
 
69
- - `git clone https://github.com/ericfortis/mockaton.git`
70
- - `cd mockaton`
71
- - `npm install tsx` (optional)
72
- - `npm run demo:ts` it will open a dashboard
70
+ ```sh
71
+ git clone https://github.com/ericfortis/mockaton.git
72
+ cd mockaton
73
+ npm install tsx
74
+ npm run demo:ts
75
+ ```
73
76
 
74
77
  Experiment with the Dashboard:
75
78
 
@@ -93,9 +96,9 @@ The _Reset_ button is for registering newly added, removed, or renamed mocks.
93
96
  - slow to build assets
94
97
 
95
98
  ### Time Travel
96
- If you commit the mocks in the repo, when bisecting a bug, you don’t
97
- have to sync the frontend with many backend repos. Similarly, it
98
- allows for checking out long-lived branches with old API contracts.
99
+ If you commit the mocks to your repo, it’s straightforward to bisect bugs and
100
+ checking out long-lived branches. In other words, you don’t have to downgrade
101
+ backends to old API contracts or databases.
99
102
 
100
103
  ### Deterministic Standalone Demo Server
101
104
  Perhaps you need to demo your app, but the ideal flow is too complex to
@@ -231,23 +234,24 @@ documenting the URL contract.
231
234
  api/video<b>?limit=[limit]</b>.GET.200.json
232
235
  </pre>
233
236
 
234
- Speaking of which, in Windows, filenames containing "?" are [not
237
+ Speaking of which, on Windows filenames containing "?" are [not
235
238
  permitted](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file), but since that’s part of the query string, it’s ignored anyway.
236
239
 
237
240
 
238
241
  ### Index-like route
239
242
  For instance, if you have `api/foo/bar` and
240
- `api/foo`. For the latter you have two options:
243
+ `api/foo`, you have two options:
241
244
 
242
- **Option A.**
245
+ **Option A:**
243
246
  ```
244
247
  api/foo.GET.200.json
245
248
  api/foo/bar.GET.200.json
246
249
  ```
247
250
 
248
- **Option B.** Omit the filename.
251
+ **Option B:** Omit the filename.
249
252
  ```text
250
253
  api/foo/.GET.200.json
254
+ api/foo/bar.GET.200.json
251
255
  ```
252
256
 
253
257
  ---
@@ -269,8 +273,7 @@ Defaults to `/(\.DS_Store|~)$/`
269
273
 
270
274
 
271
275
  ### `delay?: number` 🕓
272
- The clock icon next to the mock selector is a checkbox for delaying a particular
273
- response. The delay is globally configurable via `config.delay = 1200` (milliseconds).
276
+ The delay is globally configurable, it defaults to `1200` (milliseconds).
274
277
 
275
278
 
276
279
  ### `proxyFallback?: string`
@@ -431,7 +434,7 @@ await mockaton.select('api/foo.200.GET.json')
431
434
  ```js
432
435
  await mockaton.bulkSelectByComment('(demo-a)')
433
436
  ```
434
- Parentheses are optional. You can pass a partial match.
437
+ Parentheses are optional, so you can pass a partial match.
435
438
  For example, passing `'demo-'` (without the final `a`), selects the
436
439
  first mock in alphabetical order that matches.
437
440
 
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.19",
5
+ "version": "8.2.21",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
package/src/Dashboard.css CHANGED
@@ -218,7 +218,6 @@ main {
218
218
  .MockSelector {
219
219
  width: 300px;
220
220
  height: 30px;
221
- padding: 8px 1px;
222
221
  border: 0;
223
222
  border-left: 3px solid transparent;
224
223
  text-align: right;
package/src/Dashboard.js CHANGED
@@ -60,8 +60,7 @@ init()
60
60
 
61
61
  function App(apiResponses) {
62
62
  empty(document.body)
63
- createRoot(document.body)
64
- .render(DevPanel(apiResponses))
63
+ document.body.appendChild(DevPanel(apiResponses))
65
64
  }
66
65
 
67
66
  function DevPanel([brokersByMethod, cookies, comments, corsAllowed, fallbackAddress, staticFiles]) {
@@ -404,14 +403,6 @@ function empty(node) {
404
403
  // These are simplified React-compatible implementations.
405
404
  // IOW, for switching to React, remove the `createRoot`, `createElement`, `useRef`
406
405
 
407
- function createRoot(root) {
408
- return {
409
- render(app) {
410
- root.appendChild(app)
411
- }
412
- }
413
- }
414
-
415
406
  function createElement(elem, props = null, ...children) {
416
407
  if (typeof elem === 'function')
417
408
  return elem(props)
@@ -3,7 +3,7 @@ import { join } from 'node:path'
3
3
  import { proxy } from './ProxyRelay.js'
4
4
  import { cookie } from './cookie.js'
5
5
  import { Config } from './Config.js'
6
- import { preprocessPlugins } from './MockDispatcherPlugins.js'
6
+ import { applyPlugins } from './MockDispatcherPlugins.js'
7
7
  import * as mockBrokerCollection from './mockBrokersCollection.js'
8
8
  import { JsonBodyParserError } from './utils/http-request.js'
9
9
  import { sendInternalServerError, sendNotFound, sendBadRequest } from './utils/http-response.js'
@@ -31,7 +31,7 @@ export async function dispatchMock(req, response) {
31
31
 
32
32
  const { mime, body } = broker.isTemp500
33
33
  ? { mime: '', body: '' }
34
- : await preprocessPlugins(join(Config.mocksDir, broker.file), req, response)
34
+ : await applyPlugins(join(Config.mocksDir, broker.file), req, response)
35
35
 
36
36
  response.setHeader('Content-Type', mime)
37
37
  setTimeout(() => response.end(body), broker.delay)
@@ -3,7 +3,7 @@ import { mimeFor } from './utils/mime.js'
3
3
  import { Config } from './Config.js'
4
4
 
5
5
 
6
- export async function preprocessPlugins(filePath, req, response) {
6
+ export async function applyPlugins(filePath, req, response) {
7
7
  for (const [regex, plugin] of Config.plugins) // TESTME capitalizePlugin
8
8
  if (regex.test(filePath))
9
9
  return await plugin(filePath, req, response)
package/src/Mockaton.js CHANGED
@@ -13,10 +13,8 @@ import { apiPatchRequests, apiGetRequests } from './Api.js'
13
13
  export function Mockaton(options) {
14
14
  setup(options)
15
15
  mockBrokerCollection.init()
16
-
17
- const server = createServer(onRequest)
18
- server.listen(Config.port, Config.host, (error) => {
19
- const { address, port } = server.address()
16
+ return createServer(onRequest).listen(Config.port, Config.host, function (error) {
17
+ const { address, port } = this.address()
20
18
  const url = `http://${address}:${port}`
21
19
  console.log('Listening', url)
22
20
  console.log('Dashboard', url + API.dashboard)
@@ -25,7 +23,6 @@ export function Mockaton(options) {
25
23
  else
26
24
  Config.onReady(url + API.dashboard)
27
25
  })
28
- return server
29
26
  }
30
27
 
31
28
  async function onRequest(req, response) {
@@ -98,6 +98,7 @@ const fixtures = [
98
98
  ],
99
99
 
100
100
  // Query String
101
+ // TODO ignore on Windows (because of ?)
101
102
  [
102
103
  '/api/my-query-string?foo=[foo]&bar=[bar]',
103
104
  'api/my-query-string?foo=[foo]&bar=[bar].GET.200.json',
package/src/utils/fs.js CHANGED
@@ -1,4 +1,4 @@
1
- import { join } from 'node:path'
1
+ import path, { join } from 'node:path'
2
2
  import { lstatSync, readFileSync, readdirSync } from 'node:fs'
3
3
 
4
4
 
@@ -9,4 +9,5 @@ export const read = path => readFileSync(path)
9
9
 
10
10
  /** @returns {Array<string>} paths relative to `dir` */
11
11
  export const listFilesRecursively = dir => readdirSync(dir, { recursive: true })
12
+ .map(f => f.replaceAll(path.sep, path.posix.sep)) // TESTME
12
13
  .filter(f => isFile(join(dir, f)))
@@ -6,7 +6,7 @@ export function openInBrowser(address) {
6
6
  case 'darwin':
7
7
  exec(`open ${address}`)
8
8
  break
9
- case 'win32': // TESTME
9
+ case 'win32':
10
10
  exec(`start ${address}`)
11
11
  break
12
12
  }