mockaton 5.0.2 → 5.0.3

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/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": "5.0.2",
5
+ "version": "5.0.3",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
package/src/Api.js CHANGED
@@ -31,21 +31,12 @@ export const apiPatchRequests = new Map([
31
31
  [API.bulkSelect, bulkUpdateBrokersByCommentTag]
32
32
  ])
33
33
 
34
- function serveDashboard(_, response) {
35
- sendFile(response, join(import.meta.dirname, 'Dashboard.html'))
36
- }
37
- function serveDashboardAsset(req, response) {
38
- sendFile(response, join(import.meta.dirname, req.url))
39
- }
40
- function listCookies(_, response) {
41
- sendJSON(response, cookie.list())
42
- }
43
- function listComments(_, response) {
44
- sendJSON(response, mockBrokersCollection.extractAllComments())
45
- }
46
- function listMockBrokers(_, response) {
47
- sendJSON(response, mockBrokersCollection.getAll())
48
- }
34
+ function serveDashboard(_, response) { sendFile(response, join(import.meta.dirname, 'Dashboard.html')) }
35
+ function serveDashboardAsset(req, response) { sendFile(response, join(import.meta.dirname, req.url)) }
36
+
37
+ function listCookies(_, response) { sendJSON(response, cookie.list()) }
38
+ function listComments(_, response) { sendJSON(response, mockBrokersCollection.extractAllComments()) }
39
+ function listMockBrokers(_, response) { sendJSON(response, mockBrokersCollection.getAll()) }
49
40
 
50
41
 
51
42
  function reinitialize(_, response) {
package/src/Config.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { openInBrowser } from './utils/openInBrowser.js'
2
- import { validate, is, optional, isDirectory } from './utils/validate.js'
2
+ import { validate, is, optional } from './utils/validate.js'
3
+ import { isDirectory } from './utils/fs.js'
3
4
 
4
5
 
5
6
  export const Config = {
package/src/MockBroker.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { join } from 'node:path'
2
- import { existsSync, lstatSync } from 'node:fs'
3
-
4
2
  import { Route } from './Route.js'
5
3
  import { Config } from './Config.js'
4
+ import { isDirectory } from './utils/fs.js'
6
5
  import { DEFAULT_500_COMMENT } from './ApiConstants.js'
7
6
 
8
7
 
@@ -80,8 +79,7 @@ export class MockBroker {
80
79
  #registerTemp500() {
81
80
  const { urlMask, method } = Route.parseFilename(this.mocks[0] || this.documentation)
82
81
  let mask = urlMask
83
- const t = join(Config.mocksDir, urlMask)
84
- if (existsSync(t) && lstatSync(t).isDirectory())
82
+ if (isDirectory(join(Config.mocksDir, urlMask)))
85
83
  mask = urlMask + '/'
86
84
  mask = mask.replace(/^\//, '') // remove initial slash
87
85
  const file = `${mask}${DEFAULT_500_COMMENT}.${method}.500.txt`
@@ -1,28 +1,29 @@
1
1
  import { join } from 'node:path'
2
- import { existsSync as exists, lstatSync as lstat } from 'node:fs'
3
-
4
2
  import { Config } from './Config.js'
5
- import { sendFile, sendPartialContent } from './utils/http-response.js'
3
+ import { isDirectory, isFile } from './utils/fs.js'
4
+ import { sendFile, sendPartialContent, sendNotFound } from './utils/http-response.js'
6
5
 
7
6
 
8
7
  export function isStatic(req) {
9
- return Config.staticDir && exists(resolvePath(req))
8
+ return Config.staticDir && resolvePath(req)
10
9
  }
11
10
 
12
11
  export async function dispatchStatic(req, response) {
13
12
  const file = resolvePath(req)
14
- if (req.headers.range)
13
+ if (!file)
14
+ sendNotFound(response)
15
+ else if (req.headers.range)
15
16
  await sendPartialContent(response, req.headers.range, file)
16
17
  else
17
18
  sendFile(response, file)
18
19
  }
19
20
 
20
21
  function resolvePath(req) {
21
- const candidate = join(Config.staticDir, req.url)
22
- if (exists(candidate))
23
- return lstat(candidate).isDirectory()
24
- ? candidate + '/index.html'
25
- : candidate
22
+ let candidate = join(Config.staticDir, req.url)
23
+ if (isDirectory(candidate))
24
+ candidate += '/index.html'
25
+ if (isFile(candidate))
26
+ return candidate
26
27
  }
27
28
 
28
29
 
@@ -1,9 +1,10 @@
1
1
  import { join } from 'node:path'
2
- import { readdirSync as readDir, lstatSync } from 'node:fs'
2
+ import { readdirSync as readDir } from 'node:fs'
3
3
 
4
4
  import { Route } from './Route.js'
5
5
  import { Config } from './Config.js'
6
6
  import { cookie } from './cookie.js'
7
+ import { isFile } from './utils/fs.js'
7
8
  import { MockBroker } from './MockBroker.js'
8
9
 
9
10
 
@@ -24,7 +25,7 @@ export function init() {
24
25
  cookie.init(Config.cookies)
25
26
 
26
27
  const files = readDir(Config.mocksDir, { recursive: true })
27
- .filter(f => Config.allowedExt.test(f) && lstatSync(join(Config.mocksDir, f)).isFile())
28
+ .filter(f => Config.allowedExt.test(f) && isFile(join(Config.mocksDir, f)))
28
29
  .sort()
29
30
 
30
31
  for (const file of files) {
@@ -0,0 +1,7 @@
1
+ import { lstatSync, readFileSync } from 'node:fs'
2
+
3
+
4
+ export const isFile = path => lstatSync(path, { throwIfNoEntry: false })?.isFile()
5
+ export const isDirectory = path => lstatSync(path, { throwIfNoEntry: false })?.isDirectory()
6
+
7
+ export const read = path => readFileSync(path)
@@ -1,5 +1,6 @@
1
- import fs, { existsSync, readFileSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
  import { mimeFor } from './mime.js'
3
+ import { isFile, read } from './fs.js'
3
4
 
4
5
 
5
6
  export function sendOK(response) {
@@ -7,17 +8,17 @@ export function sendOK(response) {
7
8
  }
8
9
 
9
10
  export function sendJSON(response, payload) {
10
- response.setHeader('content-type', 'application/json')
11
+ response.setHeader('Content-Type', 'application/json')
11
12
  response.end(JSON.stringify(payload))
12
13
  }
13
14
 
14
15
  export function sendFile(response, file) {
15
- if (!existsSync(file))
16
+ if (!isFile(file))
16
17
  sendNotFound(response)
17
18
  else {
18
- response.setHeader('content-type', mimeFor(file))
19
- response.end(readFileSync(file))
20
- }
19
+ response.setHeader('Content-Type', mimeFor(file))
20
+ response.end(read(file))
21
+ }
21
22
  }
22
23
 
23
24
  export async function sendPartialContent(response, range, file) {
@@ -28,14 +29,14 @@ export async function sendPartialContent(response, range, file) {
28
29
 
29
30
  if (start < 0 || start > end || start >= size || end >= size) {
30
31
  response.statusCode = 416 // Range Not Satisfiable
31
- response.setHeader('content-range', `bytes */${size}`)
32
+ response.setHeader('Content-Range', `bytes */${size}`)
32
33
  response.end()
33
34
  }
34
35
  else {
35
36
  response.statusCode = 206 // Partial Content
36
- response.setHeader('accept-ranges', 'bytes')
37
- response.setHeader('content-range', `bytes ${start}-${end}/${size}`)
38
- response.setHeader('content-type', mimeFor(file))
37
+ response.setHeader('Accept-Ranges', 'bytes')
38
+ response.setHeader('Content-Range', `bytes ${start}-${end}/${size}`)
39
+ response.setHeader('Content-Type', mimeFor(file))
39
40
  const reader = fs.createReadStream(file, { start, end })
40
41
  reader.on('open', function () {
41
42
  this.pipe(response)
@@ -1,6 +1,3 @@
1
- import { existsSync as exists, lstatSync } from 'node:fs'
2
-
3
-
4
1
  export function validate(obj, shape) {
5
2
  for (const [field, value] of Object.entries(obj))
6
3
  if (!shape[field](value))
@@ -9,4 +6,3 @@ export function validate(obj, shape) {
9
6
 
10
7
  export const is = ctor => val => val.constructor === ctor
11
8
  export const optional = tester => val => !val || tester(val)
12
- export const isDirectory = dir => exists(dir) && lstatSync(dir).isDirectory()