mockaton 12.2.2 → 12.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
@@ -8,8 +8,7 @@ for testing difficult to reproduce backend states.
8
8
  [![codecov](https://codecov.io/github/ericfortis/mockaton/graph/badge.svg?token=90NYLMMG1J)](https://codecov.io/github/ericfortis/mockaton)
9
9
 
10
10
 
11
- ## [Documentation ↗](https://mockaton.com)
12
- ## [Changelog ↗](https://mockaton.com/changelog)
11
+ ## [Documentation ↗](https://mockaton.com) | [Changelog ↗](https://mockaton.com/changelog)
13
12
 
14
13
  ## Overview
15
14
  With Mockaton, you don’t need to write code for wiring up your
@@ -22,7 +21,6 @@ For example, for [/api/company/123](#), the filename could be:
22
21
  <code>my-mocks-dir/<b>api/company</b>/[id].GET.200.json</code>
23
22
  </pre>
24
23
 
25
- <br/>
26
24
 
27
25
  ## Dashboard
28
26
 
@@ -32,16 +30,13 @@ For example, for [/api/company/123](#), the filename could be:
32
30
  <img alt="Mockaton Dashboard" src="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp762x762.dark.gold.png">
33
31
  </picture>
34
32
 
35
- On the dashboard you can: select a mock variant for a particular route; 🕓 delay responses;
36
- and cycle an autogenerated `500` error (e.g., for testing retries). Nonetheless,
37
- there’s a [Control API ↗](https://mockaton.com/api), which is handy for setting up tests.
38
-
39
33
  <br/>
40
34
 
41
35
 
42
36
  ## Quick Start (Docker)
43
37
  This will spin up Mockaton with the sample directories
44
- included in this repo mounted on the container ([mockaton-mocks/](./mockaton-mocks) and [mockaton-static-mocks/](./mockaton-static-mocks))
38
+ included in this repo mounted on the container ([mockaton-mocks/](./mockaton-mocks)
39
+ and [mockaton-static-mocks/](./mockaton-static-mocks))
45
40
 
46
41
  ```sh
47
42
  git clone https://github.com/ericfortis/mockaton.git --depth 1
@@ -50,13 +45,7 @@ make docker
50
45
  ```
51
46
  Dashboard: http://localhost:2020/mockaton
52
47
 
53
-
54
48
  Test it:
55
49
  ```shell
56
50
  curl localhost:2020/api/user
57
51
  ```
58
-
59
-
60
-
61
- ## License
62
- MIT
package/index.d.ts CHANGED
@@ -44,7 +44,7 @@ export interface Config {
44
44
  plugins?: [filenameTester: RegExp, plugin: Plugin][]
45
45
 
46
46
  onReady?: (address: string) => void
47
-
47
+
48
48
  hotReload?: boolean // For UI dev purposes only
49
49
  }
50
50
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mockaton",
3
3
  "description": "HTTP Mock Server",
4
4
  "type": "module",
5
- "version": "12.2.2",
5
+ "version": "12.3.0",
6
6
  "exports": {
7
7
  ".": {
8
8
  "import": "./index.js",
@@ -23,7 +23,7 @@ export class Commander {
23
23
 
24
24
  /** @returns {Promise<Response>} */
25
25
  setGlobalDelay = delay => this.#patch(API.globalDelay, delay)
26
-
26
+
27
27
  /** @returns {Promise<Response>} */
28
28
  setGlobalDelayJitter = jitterPct => this.#patch(API.globalDelayJitter, jitterPct)
29
29
 
@@ -1,9 +1,10 @@
1
- /** @KeepSync src/server/ApiConstants.js */
1
+ /** # @SharedWithServer */
2
2
 
3
3
  const MOUNT = '/mockaton'
4
+
4
5
  export const API = {
5
6
  dashboard: MOUNT,
6
-
7
+
7
8
  bulkSelect: MOUNT + '/bulk-select-by-comment',
8
9
  collectProxied: MOUNT + '/collect-proxied',
9
10
  cookies: MOUNT + '/cookies',
@@ -1,4 +1,13 @@
1
- // @KeepSync src/server/Filename.js
1
+ /** # @SharedWithServer */
2
+
3
+ const METHODS = [ // @KeepSync node:http.METHODS
4
+ 'ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE',
5
+ 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE',
6
+ 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS',
7
+ 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT',
8
+ 'QUERY', 'REBIND', 'REPORT', 'SEARCH', 'SOURCE', 'SUBSCRIBE',
9
+ 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE'
10
+ ]
2
11
 
3
12
  const reComments = /\(.*?\)/g // Anything within parentheses
4
13
 
@@ -6,6 +15,25 @@ export function extractComments(file) {
6
15
  return Array.from(file.matchAll(reComments), ([c]) => c)
7
16
  }
8
17
 
18
+ export function includesComment(file, search) {
19
+ return extractComments(file).some(c => c.includes(search))
20
+ }
21
+
22
+
23
+ export function validateFilename(file) {
24
+ const tokens = file.replace(reComments, '').split('.')
25
+ if (tokens.length < 4)
26
+ return 'Invalid Filename Convention'
27
+
28
+ const { status, method } = parseFilename(file)
29
+ if (!responseStatusIsValid(status))
30
+ return `Invalid HTTP Response Status: "${status}"`
31
+
32
+ if (!METHODS.includes(method))
33
+ return `Unrecognized HTTP Method: "${method}"`
34
+ }
35
+
36
+
9
37
  export function parseFilename(file) {
10
38
  const tokens = file.replace(reComments, '').split('.')
11
39
  return {
@@ -22,3 +50,19 @@ function removeTrailingSlash(url = '') {
22
50
  .replace('/?', '?')
23
51
  .replace('/#', '#')
24
52
  }
53
+
54
+ function responseStatusIsValid(status) {
55
+ return Number.isInteger(status)
56
+ && status >= 100
57
+ && status <= 599
58
+ }
59
+
60
+ export function makeMockFilename(url, method, status, ext) {
61
+ const urlMask = replaceIds(removeTrailingSlash(url))
62
+ return [urlMask, method, status, ext].join('.')
63
+ }
64
+
65
+ const reUuidV4 = /([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/gi
66
+ function replaceIds(filename) {
67
+ return filename.replaceAll(reUuidV4, '[id]')
68
+ }
@@ -82,7 +82,7 @@ export const store = {
82
82
  }
83
83
  catch (error) { store.onError(error) }
84
84
  },
85
-
85
+
86
86
  async setGlobalDelayJitter(value) {
87
87
  try {
88
88
  const response = await api.setGlobalDelayJitter(value)
@@ -160,7 +160,7 @@ export const store = {
160
160
  r.setUrlMaskDittoed(store._dittoCache.get(r.key))
161
161
  return r
162
162
  },
163
-
163
+
164
164
  staticBrokersAsRows() {
165
165
  const rows = Object.values(store.staticBrokers)
166
166
  .map(b => new StaticBrokerRowModel(b))
@@ -196,7 +196,6 @@ export const store = {
196
196
  const response = await api.toggle500(method, urlMask)
197
197
  if (!response.ok) throw response
198
198
  store.setBroker(await response.json())
199
- store.setChosenLink(method, urlMask)
200
199
  store.renderRow(method, urlMask)
201
200
  }
202
201
  catch (error) { store.onError(error) }
@@ -207,7 +206,6 @@ export const store = {
207
206
  const response = await api.setRouteIsProxied(method, urlMask, checked)
208
207
  if (!response.ok) throw response
209
208
  store.setBroker(await response.json())
210
- store.setChosenLink(method, urlMask)
211
209
  store.renderRow(method, urlMask)
212
210
  }
213
211
  catch (error) { store.onError(error) }