mockaton 0.9.8 → 0.9.9

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/MockDispatcher.js CHANGED
@@ -5,7 +5,7 @@ import { DF } from './ApiConstants.js'
5
5
  import { cookie } from './cookie.js'
6
6
  import { Config } from './Config.js'
7
7
  import { mimeFor } from './utils/mime.js'
8
- import * as MockBrokerCollection from './mockBrokersCollection.js'
8
+ import * as mockBrokerCollection from './mockBrokersCollection.js'
9
9
  import { parseJSON, JsonBodyParserError } from './utils/http-request.js'
10
10
  import { sendInternalServerError, sendNotFound, sendFile, sendBadRequest } from './utils/http-response.js'
11
11
 
@@ -17,14 +17,14 @@ export async function dispatchMock(req, response) {
17
17
  return
18
18
  }
19
19
 
20
- const mockBroker = MockBrokerCollection.findMatchingBroker(req.method, req.url)
21
- if (!mockBroker) {
20
+ const broker = mockBrokerCollection.getBrokerForUrl(req.method, req.url)
21
+ if (!broker) {
22
22
  sendNotFound(response)
23
23
  return
24
24
  }
25
25
 
26
26
  try {
27
- const { file, status, delay, currentTransform } = mockBroker
27
+ const { file, status, delay, currentTransform } = broker
28
28
  console.log('\n', req.url, '→\n ', file)
29
29
 
30
30
  response.statusCode = status
@@ -33,7 +33,7 @@ export async function dispatchMock(req, response) {
33
33
  response.setHeader('set-cookie', cookie.getCurrent())
34
34
 
35
35
  let mockAsText = readMock(file)
36
- if (mockBroker.currentTransform) {
36
+ if (broker.currentTransform) {
37
37
  const body = await requestBodyForTransform(req, mockAsText)
38
38
  const transformFunc = await importTransformFunc(currentTransform)
39
39
  mockAsText = transformFunc(mockAsText, body, Config)
package/Mockaton.js CHANGED
@@ -4,14 +4,14 @@ import { createServer } from 'node:http'
4
4
  import { DP } from './ApiConstants.js'
5
5
  import { Config, setup } from './Config.js'
6
6
  import { dispatchMock } from './MockDispatcher.js'
7
- import * as MockBrokerCollection from './mockBrokersCollection.js'
7
+ import * as mockBrokerCollection from './mockBrokersCollection.js'
8
8
  import { dispatchStatic, isStatic } from './StaticDispatcher.js'
9
9
  import { apiPatchRequests, apiGetRequests } from './Api.js'
10
10
 
11
11
 
12
12
  export function Mockaton(options) {
13
13
  setup(options)
14
- MockBrokerCollection.init()
14
+ mockBrokerCollection.init()
15
15
 
16
16
  return createServer(async (req, response) => {
17
17
  const { url, method } = req
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Mockaton
2
2
  _Mockaton_ is a mock server for developing and testing frontends.
3
3
 
4
- It scans `Config.mocksDir` for files following a specific
5
- file name convention, which is similar to the URL paths. For
4
+ It scans `Config.mocksDir` for files following a specific directory
5
+ and file name convention, which is similar to the URL paths. For
6
6
  example, the following file will be served for `/api/user/1234`
7
7
  ```
8
- api/
9
- api/user/
10
- api/user/[user-id].GET.200.json
8
+ -- api/
9
+ |-- user/
10
+ |-- [user-id].GET.200.json
11
11
  ```
12
12
 
13
13
  By the way, [this browser
@@ -122,23 +122,27 @@ The `Config.allowedExt` regex defaults to: `/\.(json|txt|md|mjs)$/`
122
122
 
123
123
 
124
124
  ### Dynamic Parameters
125
- Anything within square brackets. For example, `api/user/[id]/[age].GET.200.json`
125
+ Anything within square brackets. For example,
126
+ <pre>
127
+ api/user/<b>[id]</b>/<b>[age]</b>.GET.200.json
128
+ </pre>
126
129
 
127
130
  ### Comments
128
- Comments are anything within parentheses, including them, and they are
129
- ignored for URL purposes. In other words, comments have no effect on the
130
- URL mask. For example, these two are for `/api/foo`
131
- ```
132
- api/foo(my comment).GET.200.json(foo)
131
+ Comments are anything within parentheses, including them.
132
+ They are ignored for URL purposes, so they have no effect
133
+ on the URL mask. For example, these two are for `/api/foo`
134
+ <pre>
135
+ api/foo<b>(my comment)</b>.GET.200.json<b>(foo)</b>
133
136
  api/foo.GET.200.json
134
- ```
137
+ </pre>
135
138
 
136
139
  ### Query String Params
137
- ```
138
- api/video?limit=[limit].GET.200.json
139
- ```
140
- The query string behaves like comments in the sense it’s only used for documenting
141
- the URL API contract. In other words, the query string is ignored when routing to it.
140
+ <pre>
141
+ api/video<b>?limit=[limit]</b>.GET.200.json
142
+ </pre>
143
+
144
+ The query string is ignored when routing to it. It’s
145
+ only used for documenting the URL API contract.
142
146
 
143
147
  BTW, in Windows, filenames containing "?" are [not
144
148
  permitted](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file),
@@ -199,7 +203,7 @@ PATCH /mockaton/edit
199
203
  ```
200
204
  PATCH /mockaton/bulk-select
201
205
  {
202
- "comment": "demo-a"
206
+ "comment": "(demo-a)"
203
207
  }
204
208
  ```
205
209
  ---
@@ -20,43 +20,54 @@ import { MockBroker } from './MockBroker.js'
20
20
  let collection = {}
21
21
 
22
22
  export function init() {
23
+ collection = {}
23
24
  cookie.init(Config.cookies)
24
25
 
25
- collection = {}
26
- for (const file of listMocksDirRecursively()) {
26
+ const files = readdirSync(Config.mocksDir, { recursive: true })
27
+ .filter(f => Config.allowedExt.test(f) && lstatSync(join(Config.mocksDir, f)).isFile())
28
+ .sort()
29
+
30
+ for (const file of files) {
27
31
  const { error, method, urlMask } = Route.parseFilename(file)
28
- if (error) // skip
32
+ if (error) {
29
33
  console.error(error, file)
30
- else {
31
- collection[method] ??= {}
32
- if (!(urlMask in collection[method]))
33
- collection[method][urlMask] = new MockBroker(file)
34
- else
35
- collection[method][urlMask].register(file)
34
+ continue
36
35
  }
36
+ collection[method] ??= {}
37
+ if (!(urlMask in collection[method]))
38
+ collection[method][urlMask] = new MockBroker(file)
39
+ else
40
+ collection[method][urlMask].register(file)
37
41
  }
38
42
  forEachBroker(broker => broker.ensureItHas500())
39
43
  }
40
44
 
45
+ function forEachBroker(fn) {
46
+ for (const brokers of Object.values(collection))
47
+ Object.values(brokers).forEach(fn)
48
+ }
49
+
50
+
41
51
  export const getAll = () => collection
52
+
42
53
  export const getBrokerByFilename = file => {
43
54
  const { method, urlMask } = Route.parseFilename(file)
44
55
  return collection[method][urlMask]
45
56
  }
46
57
 
47
-
48
58
  // Searching the routes in reverse order so dynamic params (e.g.
49
59
  // /user/[id]) don’t take precedence over exact paths (e.g.
50
60
  // /user/name). That’s because "[]" chars are lower than alphanumeric ones.
51
61
  // BTW, `urlMasks` always start with "/", so there’s no need to
52
62
  // worry about the primacy of array-like keys when iterating.
53
- export function findMatchingBroker(method, url) {
63
+ export function getBrokerForUrl(method, url) {
54
64
  const brokers = Object.values(collection[method])
55
65
  for (let i = brokers.length - 1; i >= 0; i--)
56
66
  if (brokers[i].urlMaskMatches(url))
57
67
  return brokers[i]
58
68
  }
59
69
 
70
+
60
71
  export function extractAllComments() {
61
72
  const comments = new Set()
62
73
  forEachBroker(broker => {
@@ -70,14 +81,4 @@ export function setMocksMatchingComment(comment) {
70
81
  forEachBroker(broker => broker.setByMatchingComment(comment))
71
82
  }
72
83
 
73
- function listMocksDirRecursively() {
74
- return readdirSync(Config.mocksDir, { recursive: true })
75
- .filter(f => Config.allowedExt.test(f) && lstatSync(join(Config.mocksDir, f)).isFile())
76
- .sort()
77
- }
78
-
79
- function forEachBroker(fn) {
80
- for (const brokers of Object.values(collection))
81
- Object.values(brokers).forEach(fn)
82
- }
83
84
 
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": "0.9.8",
5
+ "version": "0.9.9",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",