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