mockaton 11.2.6 → 11.3.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 CHANGED
@@ -7,6 +7,8 @@
7
7
  An HTTP mock server for simulating APIs with minimal setup — ideal
8
8
  for testing difficult to reproduce backend states.
9
9
 
10
+ ## https://mockaton.com ↗
11
+
10
12
  ## Overview
11
13
  With Mockaton, you don’t need to write code for wiring up your
12
14
  mocks. Instead, a given directory is scanned for filenames
@@ -45,854 +47,24 @@ curl localhost:2020/api/user
45
47
 
46
48
  ## Dashboard
47
49
 
50
+
51
+ <picture>
52
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp761x740.light.gold.png">
53
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp761x740.dark.gold.png">
54
+ <img alt="Mockaton Dashboard" src="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp761x740.dark.gold.png">
55
+ </picture>
56
+
48
57
  On the dashboard you can:
49
58
  - Select a mock variant for a particular route
50
59
  - 🕓 Delay responses
51
60
  - Trigger an autogenerated `500` error
52
61
  - …and cycle it off (for testing retries)
53
-
62
+
54
63
  Nonetheless, there’s a programmatic API, which is handy for
55
64
  setting up tests (see **Commander&nbsp;API** section below).
56
65
 
57
- <picture>
58
- <source media="(prefers-color-scheme: light)" srcset="pixaton-tests/tests/macos/pic-for-readme.vp761x740.light.gold.png">
59
- <source media="(prefers-color-scheme: dark)" srcset="pixaton-tests/tests/macos/pic-for-readme.vp761x740.dark.gold.png">
60
- <img alt="Mockaton Dashboard" src="pixaton-tests/tests/macos/pic-for-readme.vp761x740.light.gold.png">
61
- </picture>
62
-
63
-
64
- <br/>
65
- <br/>
66
-
67
- ## Multiple Mock Variants
68
- Each route can have different mocks. There are two
69
- options for doing that, and they can be combined.
70
-
71
- ### Adding comments to the filename
72
- Comments are anything within parentheses, including them.
73
-
74
- <pre>
75
- api/login<b>(locked out user)</b>.POST.423.json
76
- api/login<b>(invalid login attempt)</b>.POST.401.json
77
- </pre>
78
-
79
- You can **Bulk Select** mocks by comments to simulate the complete states
80
- you want. For example:
81
-
82
- <img src="docs/changelog/bulk-select.png" width="180px">
83
-
84
-
85
- ### Different response status code
86
- For instance, you can use a `4xx` or `5xx` status code for triggering error
87
- responses, or a `2xx` such as `204` for testing empty collections.
88
-
89
- <pre>
90
- api/videos.GET.<b>204</b>.empty # No Content
91
- api/videos.GET.<b>403</b>.json # Forbidden
92
- api/videos.GET.<b>500</b>.txt # Internal Server Error
93
- </pre>
94
-
95
-
96
- <br/>
97
-
98
- ## Scraping Mocks from your Backend
99
-
100
- ### Option 1: Browser extension
101
- The companion Chrome [devtools extension](https://chromewebstore.google.com/detail/mockaton-downloader/babjpljmacbefcmlomjedmgmkecnmlaa)
102
- lets you download all the HTTP responses and
103
- save them in bulk following Mockaton’s filename convention.
104
-
105
- ![](browser-extension/README-overview.png)
106
-
107
- ### Option 2: Fallback to your backend
108
- <details>
109
- <summary>Learn more…</summary>
110
-
111
- This option could be a bit elaborate if your backend uses third-party authentication,
112
- because you’d have to manually inject cookies or `sessionStorage` tokens.
113
-
114
- On the other hand, proxying to your backend is straightforward if your backend
115
- handles the session cookie, or if you can develop without auth.
116
-
117
- Either way you can forward requests to your backend for routes you don’t have
118
- mocks for, or routes that have the ☁️ **Cloud Checkbox** checked. In addition, by
119
- checking ✅ **Save Mocks**, you can collect the responses that hit your backend.
120
- They will be saved in your `config.mocksDir` following the filename convention.
121
- </details>
122
-
123
- <br/>
124
- <br/>
125
-
126
-
127
- ## Motivation
128
-
129
- ### Deterministic and comprehensive states
130
- Sometimes the flow you need to test is
131
- too difficult to reproduce from the actual backend.
132
-
133
- - Demo edge cases to PMs, Design, and clients
134
- - Set up screenshot tests (see [pixaton-tests/](pixaton-tests) in this repo)
135
- - Spot inadvertent regressions during development. For example, the demo
136
- app in this repo has a list of colors containing all of their possible
137
- states. This way you’ll indirectly notice if something broke.
138
-
139
- <img src="./demo-app-vite/pixaton-tests/pic-for-readme.vp740x880.light.gold.png" alt="Mockaton Demo App Screenshot" width="740" />
140
-
141
- <br/>
142
-
143
-
144
- ## Benefits
145
-
146
- ### Standalone demo server (Docker)
147
- You can demo your app by compiling the frontend and putting
148
- its built assets in `config.staticDir`. For example, this
149
- repo includes a demo which builds and runs a docker container.
150
-
151
- ```sh
152
- git clone https://github.com/ericfortis/mockaton.git --depth 1
153
- cd mockaton/demo-app-vite
154
- make run-standalone-demo
155
- ```
156
- - App: http://localhost:4040
157
- - Dashboard: http://localhost:4040/mockaton
158
-
159
- ### Testing scenarios that would otherwise be skipped
160
- - Trigger dynamic states on an API. For example, for polled alerts or notifications.
161
- - Testing retries, you can change an endpoint from a 500 to a 200 on the fly.
162
- - Simulate errors on third-party APIs, or on your project’s backend.
163
- - Generate dynamic responses. Use Node’s HTTP handlers (see function mocks below). So you can, e.g.:
164
- - have an in-memory database
165
- - read from disk
166
- - read query string
167
- - pretty much anything you can do with a normal backend request handler
168
-
169
- ### Privacy and security
170
- - Does not write to disk. Except when you select ✅ **Save Mocks** for scraping mocks from a backend
171
- - Does not initiate network connections (no logs, no telemetry)
172
- - Does not hijack your HTTP client
173
- - Auditable
174
- - Organized and small. 4 KLoC (half is UI and tests)
175
- - Zero dependencies. No runtime and no build packages.
176
-
177
- <br/>
178
-
179
- ## Benefits of Mocking APIs in General
180
- The section above highlights benefits specific to Mockaton. There are more, but
181
- in general here are some benefits which Mockaton has but other tools have as well:
182
-
183
- ### Works around unstable dev backends while developing UIs
184
- - Syncing the database and spinning up dev infrastructure can be complex
185
- - Mitigates progress from being blocked by waiting for APIs
186
-
187
- ### Time travel
188
- If you commit the mocks to your repo, you don’t have to downgrade
189
- backends when checking out long-lived branches or bisecting bugs.
190
-
191
- <br/>
192
-
193
-
194
- ## Usage (without Docker)
195
-
196
- _For Docker, see the Quick-Start section above._
197
-
198
- Requires Node.js **v22.18+**, which supports TypeScript mocks.
199
-
200
- 1. Create a mock in the default directory (`./mockaton-mocks`)
201
- ```sh
202
- mkdir -p mockaton-mocks/api
203
- echo "[1,2,3]" > mockaton-mocks/api/foo.GET.200.json
204
- ```
205
- 2. Run Mockaton (`npx` comes with Node, and installs Mockaton if needed)
206
- ```shell
207
- npx mockaton --port 4040
208
- ```
209
-
210
- 3. Test it
211
- ```shell
212
- curl localhost:4040/api/foo
213
- ```
214
-
215
-
216
- ## Or, on Node Projects
217
- ```sh
218
- npm install mockaton --save-dev
219
- ```
220
-
221
- In your `package.json`:
222
- ```json
223
- "scripts": {
224
- "mockaton": "mockaton --port 4040"
225
- }
226
- ```
227
- <br/>
228
-
229
-
230
- ## CLI Options
231
- The CLI options override their counterparts in `mockaton.config.js`
232
-
233
- ```txt
234
- -c, --config <file> (default: ./mockaton.config.js)
235
-
236
- -m, --mocks-dir <dir> (default: ./mockaton-mocks/)
237
- -s, --static-dir <dir> (default: ./mockaton-static-mocks/)
238
-
239
- -H, --host <host> (default: 127.0.0.1)
240
- -p, --port <port> (default: 0) which means auto-assigned
241
-
242
- -q, --quiet Errors only
243
- --no-open Don’t open dashboard in a browser
244
-
245
- -h, --help
246
- -v, --version
247
- ```
248
-
249
-
250
- ## mockaton.config.js (Optional)
251
- Mockaton looks for a file `mockaton.config.js` in its current working directory.
252
-
253
- ### Defaults Overview
254
- The next section has the documentation, but here's an overview of the defaults:
255
-
256
- ```js
257
- import { defineConfig, jsToJsonPlugin, openInBrowser, SUPPORTED_METHODS } from 'mockaton'
258
-
259
- export default defineConfig({
260
- mocksDir: 'mockaton-mocks',
261
- staticDir: 'mockaton-static-mocks',
262
- ignore: /(\.DS_Store|~)$/,
263
- watcherEnabled: true,
264
-
265
- host: '127.0.0.1',
266
- port: 0, // auto-assigned
267
-
268
- logLevel: 'normal',
269
-
270
- delay: 1200, // ms. Applies to routes with the Delay Checkbox "ON"
271
- delayJitter: 0,
272
-
273
- proxyFallback: '',
274
- collectProxied: false,
275
- formatCollectedJSON: true,
276
-
277
- cookies: {},
278
- extraHeaders: [],
279
- extraMimes: {},
280
-
281
- corsAllowed: true,
282
- corsOrigins: ['*'],
283
- corsMethods: SUPPORTED_METHODS,
284
- corsHeaders: ['content-type', 'authorization'],
285
- corsExposedHeaders: [],
286
- corsCredentials: true,
287
- corsMaxAge: 0,
288
-
289
- plugins: [
290
- [/\.(js|ts)$/, jsToJsonPlugin]
291
- ],
292
-
293
- onReady: await openInBrowser
294
- })
295
- ```
296
-
297
- <br/>
298
- <details>
299
- <summary><b>Config Documentation…</b></summary>
300
-
301
- ### `mocksDir?: string`
302
- Defaults to `'mockaton-mocks'`.
303
-
304
- ### `staticDir?: string`
305
- Defaults to `'mockaton-static-mocks'`.
306
- This option is not needed besides serving partial content (e.g., videos). But
307
- it’s convenient for serving 200 GET requests without having to add the filename
308
- extension convention. For example, for using Mockaton as a standalone demo server,
309
- as explained above in the _Use Cases_ section.
310
-
311
- Files under `config.staticDir` take precedence over corresponding
312
- `GET` mocks in `config.mocksDir` (regardless of status code).
313
- For example, if you have two files for `GET` <a href="#">/foo/bar.jpg</a> such as:
314
- <pre>
315
- my-static-dir<b>/foo/bar.jpg</b> <span style="color:green"> // Wins</span>
316
- my-mocks-dir<b>/foo/bar.jpg</b>.GET.200.jpg <span style="color:red"> // Unreachable</span>
317
- </pre>
318
-
319
-
320
- <br/>
321
-
322
- ### `ignore?: RegExp`
323
- Defaults to `/(\.DS_Store|~)$/`
324
-
325
- The regex rule is tested against the basename (filename without directory path).
326
-
327
-
328
- <br/>
329
-
330
-
331
- ### `watcherEnabled?: boolean`
332
- Defaults to `true`
333
-
334
- When `false`, if you **add**, **delete**, or **rename** you’ll need to click **"Reset"**
335
- on the Dashboard, or call `commander.reset()` in order to re-initialize the collection.
336
-
337
- On the other hand, **edits are not affected by this
338
- flag**; mocks are always read from disk on every request.
339
-
340
- <br/>
341
-
342
-
343
- ### `host?: string`
344
- Defaults to `'127.0.0.1'`
345
-
346
- ### `port?: number`
347
- Defaults to `0`, which means auto-assigned
348
-
349
- <br/>
350
-
351
- ### `delay?: number`
352
- Defaults to `1200` milliseconds. Although routes can individually be delayed
353
- with the 🕓 Checkbox, the amount is globally configurable with this option.
354
-
355
- ### `delayJitter?: number`
356
- Defaults to `0`. Range: `[0.0, 3.0]`. Maximum percentage of the delay to add.
357
- For example, `0.5` will add at most `600ms` to the default delay.
358
-
359
- <br/>
360
-
361
- ### `proxyFallback?: string`
362
- For example, `config.proxyFallback = 'http://example.com'`
363
-
364
- Lets you specify a target server for serving routes you don’t have mocks for,
365
- or that you manually picked with the ☁️ **Cloud Checkbox**.
366
-
367
- ### `collectProxied?: boolean`
368
- Defaults to `false`. With this flag you can save mocks that hit
369
- your proxy fallback to `config.mocksDir`. If the URL has v4 UUIDs,
370
- the filename will have `[id]` in their place. For example:
371
-
372
- <pre>
373
- <b>/api/user/</b>d14e09c8-d970-4b07-be42-b2f4ee22f0a6<b>/likes</b> =>
374
- my-mocks-dir<b>/api/user/</b>[id]<b>/likes</b>.GET.200.json
375
- </pre>
376
-
377
- Your existing mocks won’t be overwritten. Responses of routes with
378
- the ☁️ **Cloud Checkbox** selected will be saved with unique filename-comments.
379
-
380
-
381
- <details>
382
- <summary>Extension details</summary>
383
- <p>
384
- An <code>.empty</code> extension means the <code>Content-Type</code>
385
- header was not sent by your backend.
386
- </p>
387
-
388
- <p>
389
- An <code>.unknown</code> extension means the <code>Content-Type</code> is not in
390
- the predefined list. For that, you can add it to <code>config.extraMimes</code>
391
- </p>
392
- </details>
393
-
394
-
395
- ### `formatCollectedJSON?: boolean`
396
- Defaults to `true`. Saves the mock with two spaces indentation &mdash;
397
- the formatting output of `JSON.stringify(data, null, ' ')`
398
-
399
-
400
- <br/>
401
-
402
-
403
- ### `cookies?: { [label: string]: string }`
404
-
405
- ```js
406
- import { jwtCookie } from 'mockaton'
407
-
408
-
409
- config.cookies = {
410
- 'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
411
- 'My Normal User': 'my-cookie=0;Path=/;SameSite=strict',
412
- 'My JWT': jwtCookie('my-cookie', {
413
- name: 'John Doe',
414
- picture: 'https://cdn.auth0.com/avatars/jd.png'
415
- }),
416
- 'None': ''
417
- }
418
- ```
419
- The selected cookie, which is the first one by default, is sent in every response in a
420
- `Set-Cookie` header (as long as its value is not an empty string). The object key is just
421
- a label for UI display purposes, and also for selecting a cookie via the Commander API.
422
-
423
- If you need to send more than one cookie, you can inject them globally
424
- in `config.extraHeaders`, or individually in a function `.js` or `.ts` mock.
425
-
426
- By the way, the `jwtCookie` helper has a hardcoded header and signature.
427
- So it’s useful only if you care about its payload.
428
-
429
- <br/>
430
-
431
- ### `extraHeaders?: string[]`
432
- Note: it’s a one-dimensional array. The header name goes at even indices.
433
-
434
- ```js
435
- config.extraHeaders = [
436
- 'Server', 'Mockaton',
437
- 'Set-Cookie', 'foo=FOO;Path=/;SameSite=strict',
438
- 'Set-Cookie', 'bar=BAR;Path=/;SameSite=strict'
439
- ]
440
- ```
441
-
442
- <br/>
443
-
444
- ### `extraMimes?: { [fileExt: string]: string }`
445
- ```js
446
- config.extraMimes = {
447
- jpe: 'application/jpeg',
448
- html: 'text/html; charset=utf-8' // overrides built-in
449
- }
450
- ```
451
- Those extra media types take precedence over the built-in
452
- [utils/mime.js](src/server/utils/mime.js), so you can override them.
453
-
454
- <br/>
455
-
456
- ### `plugins?: [filenameTester: RegExp, plugin: Plugin][]`
457
- ```ts
458
- type Plugin = (
459
- filePath: string,
460
- request: IncomingMessage,
461
- response: OutgoingMessage
462
- ) => Promise<{
463
- mime: string,
464
- body: string | Uint8Array
465
- }>
466
- ```
467
- Plugins are for processing mocks before sending them. If no
468
- regex matches the filename, the fallback plugin will read
469
- the file from disk and compute the MIME from the extension.
470
-
471
- Note: don’t call `response.end()` on any plugin.
472
-
473
- <details>
474
- <summary><b> See plugin examples </b></summary>
475
-
476
- ```shell
477
- npm install yaml
478
- ```
479
- ```js
480
- import { parse } from 'yaml'
481
- import { readFileSync } from 'node:js'
482
- import { jsToJsonPlugin } from 'mockaton'
483
-
484
-
485
- config.plugins = [
486
-
487
- // Although `jsToJsonPlugin` is set by default, you need to include it if you need it.
488
- // IOW, your plugins array overwrites the default list. This way you can remove it.
489
- [/\.(js|ts)$/, jsToJsonPlugin],
490
-
491
-
492
- [/\.yml$/, yamlToJsonPlugin],
493
-
494
-
495
- // e.g. GET /api/foo would be capitalized
496
- [/foo\.GET\.200\.txt$/, capitalizePlugin]
497
- ]
498
-
499
- function yamlToJsonPlugin(filePath) {
500
- return {
501
- mime: 'application/json',
502
- body: JSON.stringify(parse(readFileSync(filePath, 'utf8')))
503
- }
504
- }
505
-
506
- function capitalizePlugin(filePath) {
507
- return {
508
- mime: 'application/text',
509
- body: readFileSync(filePath, 'utf8').toUpperCase()
510
- }
511
- }
512
- ```
513
- </details>
514
-
515
- <br/>
516
-
517
- ### `corsAllowed?: boolean`
518
- Defaults to `true`. When `true`, these are the default options:
519
-
520
- <details>
521
- <summary>CORS Options</summary>
522
-
523
- ```js
524
- config.corsOrigins = ['*']
525
- config.corsMethods = require('node:http').METHODS
526
- config.corsHeaders = ['content-type', 'authorization']
527
- config.corsCredentials = true
528
- config.corsMaxAge = 0 // seconds to cache the preflight req
529
- config.corsExposedHeaders = [] // headers you need to access in client-side JS
530
- ```
531
- </details>
532
-
533
- <br/>
534
-
535
- ### `onReady?: (dashboardUrl: string) => void`
536
- By default, it will open the dashboard in your default browser on macOS and
537
- Windows. But for a more cross-platform utility you could `npm install open` and
538
- that implementation will be automatically used instead.
539
-
540
- If you don’t want to open a browser, pass a noop:
541
- ```js
542
- config.onReady = () => {}
543
- ```
544
-
545
- At any rate, you can trigger any command besides opening a browser.
546
-
547
- <br/>
548
-
549
- ### `logLevel?: 'quiet' | 'normal' | 'verbose'`
550
- Defaults to `'normal'`.
551
-
552
- - `quiet`: only errors (stderr)
553
- - `normal`: info, mock access, warnings, and errors
554
- - `verbose`: normal + API access
555
-
556
- </details>
557
-
558
-
559
- <details>
560
- <summary>Programmatic Launch (Optional)…</summary>
561
-
562
-
563
- ```js
564
- import { Mockaton } from 'mockaton'
565
- import config from './mockaton.config.js'
566
-
567
- const server = await Mockaton(
568
- config // Not required, but it’s not read by default.
569
- )
570
- ```
571
- </details>
572
-
573
-
574
- <br/>
575
-
576
-
577
- ## You can write JSON mocks in JavaScript or TypeScript
578
- _TypeScript needs **Node 22.18+ or 23.6+**_
579
-
580
- For example, `api/foo.GET.200.js`
581
-
582
- ### Option A: An Object, Array, or String is sent as JSON
583
-
584
- ```js
585
- export default { foo: 'bar' }
586
- ```
587
-
588
- ### Option B: Function Mocks (async or sync)
589
-
590
- **Return** a `string | Buffer | Uint8Array`, but **don’t call** `response.end()`
591
-
592
- ```js
593
- export default (request, response) =>
594
- JSON.stringify({ foo: 'bar' })
595
- ```
596
-
597
- #### About Custom HTTP Handlers
598
-
599
- For example, you can intercept requests to write to a database. Or
600
- act based on some query string value, etc. In summary, you get Node’s
601
- `request`, `response` as arguments, so you can think of Mockaton as a
602
- router, but in the handlers you return, instead of ending the response.
603
-
604
-
605
- <details>
606
- <summary><b>Examples…</b></summary>
607
-
608
- Imagine you have an initial list of colors, and
609
- you want to concatenate newly added colors.
610
-
611
- `api/colors.POST.201.js`
612
- ```js
613
- import { parseJSON } from 'mockaton'
614
-
615
-
616
- export default async function insertColor(request, response) {
617
- const color = await parseJSON(request)
618
- globalThis.newColorsDatabase ??= []
619
- globalThis.newColorsDatabase.push(color)
620
-
621
- // These two lines are not needed but you can change their values
622
- // response.statusCode = 201 // default derived from filename
623
- // response.setHeader('Content-Type', 'application/json') // unconditional default
624
-
625
- return JSON.stringify({ msg: 'CREATED' })
626
- }
627
- ```
628
-
629
- `api/colors.GET.200.js`
630
- ```js
631
- import colorsFixture from './colors.json' with { type: 'json' }
632
-
633
-
634
- export default function listColors() {
635
- return JSON.stringify([
636
- ...colorsFixture,
637
- ...(globalThis.newColorsDatabase || [])
638
- ])
639
- }
640
- ```
641
- </details>
642
-
643
- <br/>
644
-
645
- **What if I need to serve a static .js or .ts?**
646
-
647
- **Option A:** Put it in your `config.staticDir` without the `.GET.200.js` extension.
648
- Mocks in `staticDir` take precedence over `mocksDir/*`.
649
-
650
- **Option B:** Read it and return it. For example:
651
- ```js
652
- import { readFileSync } from 'node:fs'
653
-
654
- export default function (_, response) {
655
- response.setHeader('Content-Type', 'application/javascript')
656
- return readFileSync('./some-dir/foo.js', 'utf8')
657
- }
658
- ```
659
-
660
- <br/>
661
-
662
- ## Mock Filename Convention
663
-
664
- ### Extension
665
-
666
- The last three dots are reserved for the HTTP Method,
667
- Response Status Code, and File Extension.
668
-
669
- ```
670
- api/user.GET.200.json
671
- ```
672
-
673
- You can also use `.empty` or `.unknown` if you don’t
674
- want a `Content-Type` header in the response.
675
-
676
- <details>
677
- <summary>Supported Methods</summary>
678
- <p>
679
- ACL, BIND, CHECKOUT,
680
- CONNECT, COPY, DELETE,
681
- GET, HEAD, LINK,
682
- LOCK, M-SEARCH, MERGE,
683
- MKACTIVITY, MKCALENDAR, MKCOL,
684
- MOVE, NOTIFY, OPTIONS,
685
- PATCH, POST, PROPFIND,
686
- PROPPATCH, PURGE, PUT,
687
- QUERY, REBIND, REPORT,
688
- SEARCH, SOURCE, SUBSCRIBE,
689
- TRACE, UNBIND, UNLINK,
690
- UNLOCK, UNSUBSCRIBE
691
- </p>
692
- </details>
693
-
694
- <br/>
695
-
696
- ### Dynamic parameters
697
- Anything within square brackets is always matched.
698
-
699
- For example, for <a href="#">/api/company/<b>123</b>/user/<b>789</b></a>,
700
- the filename could be:
701
-
702
- <pre><code>api/company/<b>[id]</b>/user/<b>[uid]</b>.GET.200.json</code></pre>
703
-
704
- <br/>
705
-
706
- ### Comments
707
- Comments are anything within parentheses, including them.
708
- They are ignored for routing purposes, so they have no effect
709
- on the URL mask. For example, these two are for `/api/foo`
710
- <pre>
711
- api/foo<b>(my comment)</b>.GET.200.json
712
- api/foo.GET.200.json
713
- </pre>
714
-
715
- A filename can have many comments.
716
-
717
- ### Default mock for a route
718
- You can add the comment: `(default)`.
719
- Otherwise, the first file in **alphabetical order** wins.
720
-
721
- <pre>
722
- api/user<b>(default)</b>.GET.200.json
723
- </pre>
724
-
725
- <br/>
726
-
727
- ### Query string params
728
- The query string is ignored for routing purposes. It’s only used for
729
- documenting the URL contract.
730
- <pre>
731
- api/video<b>?limit=[limit]</b>.GET.200.json
732
- </pre>
733
-
734
- On Windows, filenames containing "?" are [not
735
- permitted](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file), but since that’s part of the query
736
- string, it’s ignored anyway.
737
-
738
- <br/>
739
-
740
- ### Index-like routes
741
- If you have <a href="#">api/foo</a> and <a href="#">api/foo/bar</a>, you have two options:
742
-
743
- **Option A.** Standard naming:
744
- ```
745
- api/foo.GET.200.json
746
- api/foo/bar.GET.200.json
747
- ```
748
-
749
- **Option B.** Omit the URL on the filename:
750
- ```text
751
- api/foo/.GET.200.json
752
- api/foo/bar.GET.200.json
753
- ```
754
-
755
- <br/>
756
-
757
- <br/>
758
-
759
- ## Commander API
760
- [openapi.yaml](docs/openapi.yaml)
761
-
762
- `Commander` is a JavaScript client for Mockaton’s HTTP API.
763
- All of its methods return their `fetch` response promise.
764
- ```js
765
- import { Commander } from 'mockaton'
766
-
767
- const myMockatonAddr = 'http://localhost:4040'
768
- const mockaton = new Commander(myMockatonAddr)
769
- ```
770
-
771
- <details>
772
- <summary><b>See Commander Documentation</b></summary>
773
-
774
- ### Select a mock file for a route
775
- ```js
776
- await mockaton.select('api/foo.200.GET.json')
777
- ```
778
-
779
- ### Toggle 500
780
- - Selects the first found 500, which could be the autogenerated one.
781
- - Or, selects the default file.
782
- ```js
783
- await mockaton.toggle500('GET', '/api/foo')
784
- ```
785
-
786
- ### Select all mocks that have a particular comment
787
- ```js
788
- await mockaton.bulkSelectByComment('(demo-a)')
789
- ```
790
- Parentheses are optional, so you can pass a partial match. For example,
791
- passing `'demo-'` (without the final `a`) works too. On routes
792
- with many partial matches, their first mock in alphabetical order wins.
793
-
794
- <br/>
795
-
796
- ### Set route is delayed flag
797
- ```js
798
- await mockaton.setRouteIsDelayed('GET', '/api/foo', true)
799
- // or
800
- await mockaton.setStaticRouteIsDelayed('/api/foo', true)
801
- ```
802
- <br/>
803
-
804
- ### Set static route status
805
- ```js
806
- await mockaton.setStaticRouteStatus('/api/foo', 404)
807
- ```
808
-
809
- ### Set route is proxied flag
810
- ```js
811
- await mockaton.setRouteIsProxied('GET', '/api/foo', true)
812
- ```
813
-
814
- <br/>
815
-
816
- ### Select a cookie
817
- In `config.cookies`, each key is the label used for selecting it.
818
- ```js
819
- await mockaton.selectCookie('My Normal User')
820
- ```
821
-
822
- <br/>
823
-
824
- ### Set fallback proxy server address
825
- ```js
826
- await mockaton.setProxyFallback('http://example.com')
827
- ```
828
- Pass an empty string to disable it.
829
-
830
- ### Set save proxied responses as mocks flag
831
- ```js
832
- await mockaton.setCollectProxied(true)
833
- ```
834
-
835
- <br/>
836
-
837
- ### Set global delay value
838
- ```js
839
- await mockaton.setGlobalDelsy(1200) // ms
840
- ```
841
-
842
- <br/>
843
-
844
-
845
- ### Set CORS allowed
846
- ```js
847
- await mockaton.setCorsAllowed(true)
848
- ```
849
-
850
- <br/>
851
-
852
-
853
- ### Reset
854
- Re-initialize the collection. The selected mocks, cookies, and delays go back to
855
- default, but the `proxyFallback`, `collectProxied`, and `corsAllowed` are not affected.
856
- ```js
857
- await mockaton.reset()
858
- ```
859
- </details>
860
-
861
-
862
- <br/>
863
-
864
- ## Alternatives worth learning as well
865
-
866
- <details>
867
- <summary>Learn more…</summary>
868
-
869
- ### Proxy-like
870
- These are similar to Mockaton in the sense that you can modify the
871
- mock response without loosing or risking your frontend code state. For
872
- example, if you are polling, and you want to test the state change.
873
-
874
- - Chrome DevTools allows for [overriding responses](https://developer.chrome.com/docs/devtools/overrides).
875
- - Reverse Proxies such as [Burp](https://portswigger.net/burp) are also handy for overriding responses. Not easy but
876
- very powerful.
877
-
878
- ### Client Side
879
- In contrast to Mockaton, which is an HTTP Server, these
880
- programs hijack your browser’s HTTP client (or Node’s).
881
- - [Mock Server Worker (MSW)](https://mswjs.io)
882
- - [Nock](https://github.com/nock/nock)
883
- - [Fetch Mock](https://github.com/wheresrhys/fetch-mock)
884
- - [Mentoss](https://github.com/humanwhocodes/mentoss)
885
-
886
- ### Server Side
887
- - [Wire Mock](https://github.com/wiremock/wiremock)
888
- - [Mock](https://github.com/dhuan/mock)
889
- - [Swagger](https://swagger.io/)
890
- - [Mockoon](https://mockoon.com)
891
-
892
- </details>
893
-
894
- <br/>
895
- <br/>
896
66
 
67
+ ## [Changelog ↗](https://mockaton.com/changelog)
897
68
 
898
- ![](mockaton-mocks/api/user/avatar.GET.200.png)
69
+ ## License
70
+ MIT