mockaton 8.3.0 → 8.3.2

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
@@ -51,7 +51,7 @@ import { Mockaton } from 'mockaton'
51
51
 
52
52
  // See the Config section for more options
53
53
  Mockaton({
54
- mocksDir: resolve('my-mocks-dir'),
54
+ mocksDir: resolve('my-mocks-dir'), // must exist
55
55
  port: 2345
56
56
  })
57
57
  ```
@@ -296,9 +296,13 @@ On the other hand, newly saved mocks get overwritten while they are unregistered
296
296
  <details>
297
297
  <summary>Extension Details</summary>
298
298
  <p>
299
- If you see an <code>.unknown</code> extension, that’s because the
300
- <code>Content-Type</code> sent by your backend is either missing or not present
301
- in the predefined list. For the latter, add it to <code>config.extraMimes</code>
299
+ An <code>.empty</code> extension means the <code>Content-Type</code>
300
+ header was not sent by your backend.
301
+ </p>
302
+
303
+ <p>
304
+ An <code>.unknown</code> extension means the <code>Content-Type</code> is not in
305
+ Mockaton’s predefined list. For that, you can add it to <code>config.extraMimes</code>
302
306
  </p>
303
307
  </details>
304
308
 
@@ -494,7 +498,3 @@ await mockaton.reset()
494
498
  <img src="./sample-mocks/api/user/avatar.GET.200.png" width="170"/>
495
499
  <p style="font-size: 18px">“Use Mockaton”</p>
496
500
  </div>
497
-
498
-
499
- ## TODO
500
- - Refactor Tests
package/TODO.md ADDED
@@ -0,0 +1,7 @@
1
+ # TODO
2
+
3
+ - Refactor tests
4
+ - Rename 'Reset' to 'Reload'
5
+ - Add Collect Proxied checkbox to the dashboard
6
+ - Subscribe button for newly added mocks
7
+ - or perhaps registering them automatically without full reset?
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": "8.3.0",
5
+ "version": "8.3.2",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
@@ -5,7 +5,7 @@ import { cookie } from './cookie.js'
5
5
  import { Config } from './Config.js'
6
6
  import { applyPlugins } from './MockDispatcherPlugins.js'
7
7
  import * as mockBrokerCollection from './mockBrokersCollection.js'
8
- import { JsonBodyParserError } from './utils/http-request.js'
8
+ import { BodyReaderError } from './utils/http-request.js'
9
9
  import { sendInternalServerError, sendNotFound, sendBadRequest } from './utils/http-response.js'
10
10
 
11
11
 
@@ -37,7 +37,7 @@ export async function dispatchMock(req, response) {
37
37
  setTimeout(() => response.end(body), broker.delay)
38
38
  }
39
39
  catch (error) {
40
- if (error instanceof JsonBodyParserError)
40
+ if (error instanceof BodyReaderError)
41
41
  sendBadRequest(response, error)
42
42
  else if (error.code === 'ENOENT') // mock-file has been deleted
43
43
  sendNotFound(response)
@@ -9,6 +9,7 @@ import { writeFileSync, mkdtempSync, mkdirSync } from 'node:fs'
9
9
  import { Config } from './Config.js'
10
10
  import { mimeFor } from './utils/mime.js'
11
11
  import { Mockaton } from './Mockaton.js'
12
+ import { readBody } from './utils/http-request.js'
12
13
  import { Commander } from './Commander.js'
13
14
  import { parseFilename } from './Filename.js'
14
15
  import { CorsHeader } from './utils/http-cors.js'
@@ -421,19 +422,28 @@ async function testInvalidFilenamesAreIgnored() {
421
422
 
422
423
  async function testEnableFallbackSoRoutesWithoutMocksGetRelayed() {
423
424
  await describe('Fallback', async () => {
424
- const fallbackServer = createServer((_, response) => {
425
- response.setHeader('custom_header', 'my_custom_header')
426
- response.statusCode = 423
427
- response.end('From_Fallback_Server')
425
+ const fallbackServer = createServer(async (req, response) => {
426
+ response.writeHead(423, {
427
+ 'custom_header': 'my_custom_header',
428
+ 'set-cookie': [
429
+ 'cookieA=A',
430
+ 'cookieB=B'
431
+ ]
432
+ })
433
+ response.end(await readBody(req)) // echoes they req body payload
428
434
  })
429
435
  await promisify(fallbackServer.listen).bind(fallbackServer, 0, '127.0.0.1')()
430
436
 
431
437
  await commander.setProxyFallback(`http://localhost:${fallbackServer.address().port}`)
432
438
  await it('Relays to fallback server', async () => {
433
- const res = await request('/non-existing-mock')
434
- equal(res.headers.get('custom_header'), 'my_custom_header')
439
+ const res = await request('/non-existing-mock', {
440
+ method: 'POST',
441
+ body: 'text_body'
442
+ })
435
443
  equal(res.status, 423)
436
- equal(await res.text(), 'From_Fallback_Server')
444
+ equal(res.headers.get('custom_header'), 'my_custom_header')
445
+ equal(res.headers.get('set-cookie'), ['cookieA=A', 'cookieB=B'].join(', '))
446
+ equal(await res.text(), 'text_body')
437
447
  fallbackServer.close()
438
448
  })
439
449
  })
package/src/ProxyRelay.js CHANGED
@@ -2,16 +2,22 @@ import { join } from 'node:path'
2
2
  import { write } from './utils/fs.js'
3
3
  import { Config } from './Config.js'
4
4
  import { extFor } from './utils/mime.js'
5
+ import { readBody } from './utils/http-request.js'
5
6
  import { makeMockFilename } from './Filename.js'
6
7
 
7
8
 
8
9
  export async function proxy(req, response) {
9
10
  const proxyResponse = await fetch(Config.proxyFallback + req.url, {
10
11
  method: req.method,
11
- headers: req.headers
12
+ headers: req.headers,
13
+ body: req.method === 'GET' || req.method === 'HEAD'
14
+ ? undefined
15
+ : await readBody(req)
12
16
  })
13
- // TODO investigate how to include many repeated headers such as set-cookie
14
- response.writeHead(proxyResponse.status, Object.fromEntries(proxyResponse.headers))
17
+
18
+ const headers = Object.fromEntries(proxyResponse.headers)
19
+ headers['set-cookie'] = proxyResponse.headers.getSetCookie() // parses multiple into an array
20
+ response.writeHead(proxyResponse.status, headers)
15
21
  const body = await proxyResponse.text()
16
22
  response.end(body)
17
23
 
@@ -3,10 +3,11 @@ export const StandardMethods = [
3
3
  'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'
4
4
  ]
5
5
 
6
+ export class BodyReaderError extends Error {}
6
7
 
7
- export class JsonBodyParserError extends Error {}
8
+ export const parseJSON = req => readBody(req, JSON.parse)
8
9
 
9
- export function parseJSON(req) {
10
+ export function readBody(req, parser = a => a) {
10
11
  return new Promise((resolve, reject) => {
11
12
  const MAX_BODY_SIZE = 200 * 1024
12
13
  const expectedLength = req.headers['content-length'] | 0
@@ -29,13 +30,13 @@ export function parseJSON(req) {
29
30
  req.removeListener('end', onEnd)
30
31
  req.removeListener('error', onEnd)
31
32
  if (lengthSoFar !== expectedLength)
32
- reject(new JsonBodyParserError())
33
+ reject(new BodyReaderError())
33
34
  else
34
35
  try {
35
- resolve(JSON.parse(Buffer.concat(body).toString()))
36
+ resolve(parser(Buffer.concat(body).toString()))
36
37
  }
37
38
  catch (_) {
38
- reject(new JsonBodyParserError())
39
+ reject(new BodyReaderError())
39
40
  }
40
41
  }
41
42
  })
package/src/utils/mime.js CHANGED
@@ -89,19 +89,13 @@ const mimes = {
89
89
 
90
90
  export function mimeFor(filename) {
91
91
  const ext = filename.replace(/.*\./, '').toLowerCase()
92
- const mime = Config.extraMimes[ext] || mimes[ext] || ''
93
- if (!mime)
94
- console.info(`Missing MIME for ${filename}`)
95
- return mime
92
+ return Config.extraMimes[ext] || mimes[ext] || ''
96
93
  }
97
94
 
98
95
  export function extFor(mime) {
99
- const ext = findExt(mime)
100
- if (!ext) {
101
- console.info(`Missing extension for ${mime}`)
102
- return EXT_FOR_UNKNOWN_MIME
103
- }
104
- return ext
96
+ return mime
97
+ ? findExt(mime)
98
+ : 'empty'
105
99
  }
106
100
 
107
101
  function findExt(targetMime) {
@@ -111,5 +105,5 @@ function findExt(targetMime) {
111
105
  for (const [ext, mime] of Object.entries(mimes))
112
106
  if (targetMime === mime)
113
107
  return ext
114
- return ''
108
+ return EXT_FOR_UNKNOWN_MIME
115
109
  }