mockaton 8.4.1 → 8.5.1

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
@@ -49,8 +49,8 @@ which is handy for setting up tests (see **Commander API** below).
49
49
 
50
50
  ## Basic Usage
51
51
  `tsx` is only needed if you want to write mocks in TypeScript
52
- ```
53
- npm install mockaton tsx
52
+ ```sh
53
+ npm install mockaton tsx --save-dev
54
54
  ```
55
55
 
56
56
  Create a `my-mockaton.js` file
@@ -70,23 +70,19 @@ node --import=tsx my-mockaton.js
70
70
  ```
71
71
 
72
72
 
73
- ## Running the Built-in Demo
74
- This demo uses the [sample-mocks/](./sample-mocks) of this repository.
73
+ ## Running the demo app (Vite)
74
+
75
+ This is a minimal React + Vite + Mockaton app.
75
76
 
76
77
  ```sh
77
78
  git clone https://github.com/ericfortis/mockaton.git
78
- cd mockaton
79
- npm install tsx
80
- npm run demo:ts
79
+ cd mockaton/demo-app-vite
80
+ npm install
81
+ npm run mockaton
82
+ npm run start
81
83
  ```
82
84
 
83
- Experiment with the Dashboard:
84
-
85
- - Pick a mock variant from the _Mock dropdown_
86
- - Toggle the 🕓 _Delay Responses_ button, (e.g. for testing spinners)
87
- - Toggle the _500_ button, which sends and _Internal Server Error_ on that endpoint
88
-
89
- Finally, edit a mock file in your IDE. You don’t need to restart Mockaton.
85
+ By the way, that directory has a script for opening Mockaton and Vite in one command.
90
86
 
91
87
 
92
88
  ## Use Cases
@@ -175,7 +171,7 @@ export default async function insertColor(request, response) {
175
171
  }
176
172
  ```
177
173
 
178
- `api/colors.GET.200.js`
174
+ `api/colors(assorted)(default).GET.200.ts`
179
175
  ```js
180
176
  import colorsFixture from './colors.json' with { type: 'json' }
181
177
 
@@ -334,14 +330,16 @@ config.cookies = {
334
330
  'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
335
331
  'My Normal User': 'my-cookie=0;Path=/;SameSite=strict',
336
332
  'My JWT': jwtCookie('my-cookie', {
337
- email: 'john.doe@example.com',
333
+ name: 'John Doe',
338
334
  picture: 'https://cdn.auth0.com/avatars/jd.png'
339
335
  })
340
336
  }
341
337
  ```
342
338
  The selected cookie, which is the first one by default, is sent in every
343
- response in a `Set-Cookie` header. If you need to send more
344
- cookies, inject them globally in `config.extraHeaders`.
339
+ response in a `Set-Cookie` header.
340
+
341
+ If you need to send more cookies, you can either inject them globally
342
+ in `config.extraHeaders`, or in function `.js` or `.ts` mock.
345
343
 
346
344
  By the way, the `jwtCookie` helper has a hardcoded header and signature.
347
345
  In other words, it’s useful only if you care about its payload.
@@ -436,8 +434,8 @@ config.corsExposedHeaders = [] // headers you need to access in client-side JS
436
434
 
437
435
 
438
436
  ### `onReady?: (dashboardUrl: string) => void`
439
- This defaults to trying to open the dashboard in your default browser on macOS and
440
- Windows. For a more cross-platform utility, you could `npm install open` and pass it.
437
+ By default, it will open the dashboard in your default browser on macOS and
438
+ Windows. But for a more cross-platform utility, you could `npm install open` and pass it.
441
439
  ```js
442
440
  import open from 'open'
443
441
  config.onReady = open
@@ -448,6 +446,7 @@ If you don’t want to open a browser, pass a noop:
448
446
  config.onReady = () => {}
449
447
  ```
450
448
 
449
+ Nonetheless, you can trigger any command besides opening a browser.
451
450
 
452
451
  ---
453
452
 
@@ -498,6 +497,6 @@ await mockaton.reset()
498
497
  ```
499
498
 
500
499
  <div style="display: flex; align-items: center; gap: 20px">
501
- <img src="./sample-mocks/api/user/avatar.GET.200.png" width="170"/>
500
+ <img src="fixtures-mocks/api/user/avatar.GET.200.png" width="170"/>
502
501
  <p style="font-size: 18px">“Use Mockaton”</p>
503
502
  </div>
package/TODO.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # TODO
2
2
 
3
3
  - Refactor tests
4
- - Add Collect Proxied checkbox to the dashboard
5
- - Dashboard refresh (poll?)
4
+ - Add Collect Proxied checkbox to the dashboard (remove Allow CORS)
5
+ - Dashboard refresh (long polling ?)
@@ -1,10 +1,11 @@
1
1
  import { join } from 'node:path'
2
- import { Mockaton, jwtCookie } from './index.js' // from 'mockaton'
2
+ import { Mockaton, jwtCookie } from './index.js'
3
+
3
4
 
4
5
  Mockaton({
5
6
  port: 2345,
6
- mocksDir: join(import.meta.dirname, 'sample-mocks'),
7
- staticDir: join(import.meta.dirname, 'sample-static'),
7
+ mocksDir: join(import.meta.dirname, 'fixtures-mocks'),
8
+ staticDir: join(import.meta.dirname, 'fixtures-static-mocks'),
8
9
  cookies: {
9
10
  'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
10
11
  'My Normal User': 'my-cookie=0;Path=/;SameSite=strict',
package/package.json CHANGED
@@ -2,16 +2,16 @@
2
2
  "name": "mockaton",
3
3
  "description": "A deterministic server-side for developing and testing frontend clients",
4
4
  "type": "module",
5
- "version": "8.4.1",
5
+ "version": "8.5.1",
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
- "demo": "node _usage_example.js",
13
- "demo:ts": "node --import=tsx _usage_example.js",
14
- "demo:test-ui": "node --test --import=./ui-tests/_setup.js --experimental-test-isolation=none \"./ui-tests/**/*.test.js\"",
12
+ "start": "node dev-mockaton.js",
13
+ "start:ts": "node --import=tsx dev-mockaton.js",
14
+ "test-ui": "node --test --import=./ui-tests/_setup.js --experimental-test-isolation=none \"./ui-tests/**/*.test.js\"",
15
15
  "outdated": "npm outdated --parseable | awk -F: '{ printf \"npm i %-30s ;# %s\\n\", $4, $2 }'"
16
16
  },
17
17
  "optionalDependencies": {
package/src/Dashboard.js CHANGED
@@ -16,6 +16,7 @@ const Strings = {
16
16
  fallback_server_placeholder: 'Type Server Address',
17
17
  internal_server_error: 'Internal Server Error',
18
18
  mock: 'Mock',
19
+ no_mocks_found: 'No mocks found',
19
20
  reset: 'Reset',
20
21
  select_one: 'Select One',
21
22
  static: 'Static'
@@ -43,7 +44,6 @@ const refPayloadViewerFileTitle = useRef()
43
44
 
44
45
  const mockaton = new Commander(window.location.origin)
45
46
 
46
- window.onfocus = init
47
47
  function init() {
48
48
  Promise.all([
49
49
  mockaton.listMocks(),
@@ -64,6 +64,7 @@ function App(apiResponses) {
64
64
  }
65
65
 
66
66
  function DevPanel([brokersByMethod, cookies, comments, corsAllowed, fallbackAddress, staticFiles]) {
67
+ const isEmpty = Object.keys(brokersByMethod).length === 0
67
68
  return (
68
69
  r('div', null,
69
70
  r('menu', null,
@@ -73,13 +74,15 @@ function DevPanel([brokersByMethod, cookies, comments, corsAllowed, fallbackAddr
73
74
  r(ProxyFallbackField, { fallbackAddress }),
74
75
  r(CorsCheckbox, { corsAllowed }),
75
76
  r(ResetButton)),
76
- r('main', null,
77
- r('table', null, Object.entries(brokersByMethod).map(([method, brokers]) =>
78
- r(SectionByMethod, { method, brokers }))),
79
- r('div', { className: CSS.PayloadViewer },
80
- r('h2', { ref: refPayloadViewerFileTitle }, Strings.mock),
81
- r('pre', null,
82
- r('code', { ref: refPayloadViewer }, Strings.click_link_to_preview)))),
77
+ isEmpty
78
+ ? r('main', null, Strings.no_mocks_found)
79
+ : r('main', null,
80
+ r('table', null, Object.entries(brokersByMethod).map(([method, brokers]) =>
81
+ r(SectionByMethod, { method, brokers }))),
82
+ r('div', { className: CSS.PayloadViewer },
83
+ r('h2', { ref: refPayloadViewerFileTitle }, Strings.mock),
84
+ r('pre', null,
85
+ r('code', { ref: refPayloadViewer }, Strings.click_link_to_preview)))),
83
86
  r(StaticFilesList, { staticFiles })))
84
87
  }
85
88
 
package/src/MockBroker.js CHANGED
@@ -28,7 +28,7 @@ export class MockBroker {
28
28
  this.updateFile(file)
29
29
  }
30
30
  this.mocks.push(file)
31
- this.sortMocks()
31
+ this.#sortMocks()
32
32
  }
33
33
 
34
34
  #deleteTemp500() {
@@ -68,7 +68,7 @@ export class MockBroker {
68
68
 
69
69
  #isTemp500(file) { return includesComment(file, DEFAULT_500_COMMENT) }
70
70
 
71
- sortMocks() {
71
+ #sortMocks() {
72
72
  this.mocks.sort()
73
73
  const defaults = this.mocks.filter(file => includesComment(file, DEFAULT_MOCK_COMMENT))
74
74
  const temp500 = this.mocks.filter(file => includesComment(file, DEFAULT_500_COMMENT))
package/src/Mockaton.js CHANGED
@@ -16,12 +16,15 @@ export function Mockaton(options) {
16
16
  setup(options)
17
17
  mockBrokerCollection.init()
18
18
 
19
- watch(config.mocksDir, { recursive: true, persistent: false }, (_, filename) => {
20
- if (existsSync(join(config.mocksDir, filename)))
21
- mockBrokerCollection.registerMock(filename, 'ensureItHas500')
22
- else
23
- mockBrokerCollection.unregisterMock(filename)
24
- })
19
+ watch(config.mocksDir, { recursive: true, persistent: false },
20
+ function handleAddedOrDeletedMocks(_, filename) {
21
+ if (!filename)
22
+ return
23
+ if (existsSync(join(config.mocksDir, filename)))
24
+ mockBrokerCollection.registerMock(filename, 'ensureItHas500')
25
+ else
26
+ mockBrokerCollection.unregisterMock(filename)
27
+ })
25
28
 
26
29
  return createServer(onRequest).listen(config.port, config.host, function (error) {
27
30
  const { address, port } = this.address()
@@ -18,8 +18,8 @@ import { listFilesRecursively, read } from './utils/fs.js'
18
18
  import { API, DEFAULT_500_COMMENT, DEFAULT_MOCK_COMMENT } from './ApiConstants.js'
19
19
 
20
20
 
21
- const tmpDir = mkdtempSync(tmpdir()) + '/'
22
- const staticTmpDir = mkdtempSync(tmpdir()) + '/'
21
+ const tmpDir = mkdtempSync(tmpdir() + '/mocks') + '/'
22
+ const staticTmpDir = mkdtempSync(tmpdir() + '/static') + '/'
23
23
 
24
24
  const fixtureCustomMime = [
25
25
  '/api/custom-mime',