mockaton 9.4.2 → 9.5.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
@@ -485,11 +485,12 @@ At any rate, you can trigger any command besides opening a browser.
485
485
 
486
486
  <br/>
487
487
 
488
- ### `logLevel?: 'quiet' | 'normal'`
488
+ ### `logLevel?: 'quiet' | 'normal' | 'verbose'`
489
489
  Defaults to `'normal'`.
490
490
 
491
491
  - `quiet`: only errors (stderr)
492
- - `normal`: info, access, warnings, and errors
492
+ - `normal`: info, mock access, warnings, and errors
493
+ - `verbose`: normal + API access
493
494
 
494
495
  </details>
495
496
 
package/index.d.ts CHANGED
@@ -17,7 +17,7 @@ interface Config {
17
17
  host?: string,
18
18
  port?: number
19
19
 
20
- logLevel?: 'normal' | 'quiet'
20
+ logLevel?: 'normal' | 'verbose' | 'quiet'
21
21
 
22
22
  delay?: number
23
23
  delayJitter?: number
package/lcov.info CHANGED
@@ -2202,7 +2202,7 @@ DA:75,3
2202
2202
  LH:69
2203
2203
  LF:75
2204
2204
  end_of_record
2205
- SF:src/utils/log.js
2205
+ SF:src/utils/logger.js
2206
2206
  FN:2,<instance_members_initializer>
2207
2207
  FN:4,setLevel
2208
2208
  FN:8,info
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mockaton",
3
3
  "description": "HTTP Mock Server",
4
4
  "type": "module",
5
- "version": "9.4.2",
5
+ "version": "9.5.0",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
@@ -2,7 +2,7 @@ import { join } from 'node:path'
2
2
  import { readFileSync } from 'node:fs'
3
3
  import { pathToFileURL } from 'node:url'
4
4
 
5
- import { log } from './utils/log.js'
5
+ import { logger } from './utils/logger.js'
6
6
  import { proxy } from './ProxyRelay.js'
7
7
  import { cookie } from './cookie.js'
8
8
  import { mimeFor } from './utils/mime.js'
@@ -25,7 +25,7 @@ export async function dispatchMock(req, response) {
25
25
  return
26
26
  }
27
27
 
28
- log.access(req.url, broker.file)
28
+ logger.accessMock(req.url, broker.file)
29
29
  response.statusCode = broker.status
30
30
 
31
31
  if (cookie.getCurrent())
@@ -46,11 +46,6 @@ export async function dispatchMock(req, response) {
46
46
  catch (error) {
47
47
  if (error?.code === 'ENOENT') // mock-file has been deleted
48
48
  sendNotFound(response)
49
- else if (error?.code === 'ERR_UNKNOWN_FILE_EXTENSION') {
50
- if (error.toString().includes('Unknown file extension ".ts'))
51
- log.warn('\nLooks like you need a TypeScript compiler\n')
52
- sendInternalServerError(response, error)
53
- }
54
49
  else
55
50
  sendInternalServerError(response, error)
56
51
  }
package/src/Mockaton.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createServer } from 'node:http'
2
2
 
3
- import { log } from './utils/log.js'
3
+ import { logger } from './utils/logger.js'
4
4
  import { API } from './ApiConstants.js'
5
5
  import { config, setup } from './config.js'
6
6
  import { dispatchMock } from './MockDispatcher.js'
@@ -27,8 +27,8 @@ export function Mockaton(options) {
27
27
  server.listen(config.port, config.host, function () {
28
28
  const { address, port } = this.address()
29
29
  const url = `http://${address}:${port}`
30
- log.info('Listening', url)
31
- log.info('Dashboard', url + API.dashboard)
30
+ logger.info('Listening', url)
31
+ logger.info('Dashboard', url + API.dashboard)
32
32
  config.onReady(url + API.dashboard)
33
33
  })
34
34
 
@@ -37,7 +37,7 @@ export function Mockaton(options) {
37
37
 
38
38
 
39
39
  async function onRequest(req, response) {
40
- response.on('error', log.warn)
40
+ response.on('error', logger.warn)
41
41
 
42
42
  try {
43
43
  response.setHeader('Server', 'Mockaton')
@@ -1,7 +1,7 @@
1
1
  import { join } from 'node:path'
2
2
  import { readFileSync } from 'node:fs'
3
3
 
4
- import { log } from './utils/log.js'
4
+ import { logger } from './utils/logger.js'
5
5
  import { mimeFor } from './utils/mime.js'
6
6
  import { brokerByRoute } from './staticCollection.js'
7
7
  import { config, calcDelay } from './config.js'
@@ -13,12 +13,12 @@ export async function dispatchStatic(req, response) {
13
13
 
14
14
  setTimeout(async () => {
15
15
  if (!broker || broker.status === 404) { // TESTME
16
- log.access(req.url, 'static404')
16
+ logger.accessMock(req.url, 'static404')
17
17
  sendNotFound(response)
18
18
  return
19
19
  }
20
20
 
21
- log.access(req.url, 'static200')
21
+ logger.accessMock(req.url, 'static200')
22
22
 
23
23
  const file = join(config.staticDir, broker.route)
24
24
  if (req.headers.range)
package/src/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { join, isAbsolute } from 'node:path'
2
2
 
3
- import { log } from './utils/log.js'
3
+ import { logger } from './utils/logger.js'
4
4
  import { isDirectory } from './utils/fs.js'
5
5
  import { openInBrowser } from './utils/openInBrowser.js'
6
6
  import { jsToJsonPlugin } from './MockDispatcher.js'
@@ -23,7 +23,7 @@ const schema = {
23
23
  host: ['127.0.0.1', is(String)],
24
24
  port: [0, port => Number.isInteger(port) && port >= 0 && port < 2 ** 16], // 0 means auto-assigned
25
25
 
26
- logLevel: ['normal', val => ['normal', 'quiet'].includes(val)],
26
+ logLevel: ['normal', val => ['normal', 'quiet', 'verbose'].includes(val)],
27
27
 
28
28
  delay: [1200, ms => Number.isInteger(ms) && ms >= 0],
29
29
  delayJitter: [0, percent => percent >= 0 && percent <= 3],
@@ -80,7 +80,7 @@ export function setup(options) {
80
80
 
81
81
  Object.assign(config, options)
82
82
  validate(config, ConfigValidator)
83
- log.setLevel(config.logLevel)
83
+ logger.setLevel(config.logLevel)
84
84
  }
85
85
 
86
86
 
@@ -1,6 +1,6 @@
1
1
  import { basename } from 'node:path'
2
2
 
3
- import { log } from './utils/log.js'
3
+ import { logger } from './utils/logger.js'
4
4
  import { cookie } from './cookie.js'
5
5
  import { MockBroker } from './MockBroker.js'
6
6
  import { listFilesRecursively } from './utils/fs.js'
@@ -68,7 +68,7 @@ export function registerMock(file, isFromWatcher = false) {
68
68
  function filenameIsValid(file) {
69
69
  const error = validateFilename(file)
70
70
  if (error)
71
- log.warn(error, file)
71
+ logger.warn(error, file)
72
72
  return !error
73
73
  }
74
74
 
package/src/utils/fs.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { join, dirname, sep, posix } from 'node:path'
2
2
  import { lstatSync, readdirSync, writeFileSync, mkdirSync } from 'node:fs'
3
- import { log } from './log.js'
3
+ import { logger } from './logger.js'
4
4
 
5
5
 
6
6
  export const isFile = path => lstatSync(path, { throwIfNoEntry: false })?.isFile()
@@ -25,6 +25,6 @@ export const write = (path, body) => {
25
25
  writeFileSync(path, body)
26
26
  }
27
27
  catch (err) {
28
- log.warn('Write access denied', err)
28
+ logger.warn('Write access denied', err)
29
29
  }
30
30
  }
@@ -1,47 +1,54 @@
1
1
  import fs, { readFileSync } from 'node:fs'
2
- import { log } from './log.js'
2
+ import { logger } from './logger.js'
3
3
  import { mimeFor } from './mime.js'
4
4
  import { HEADER_FOR_502 } from '../ApiConstants.js'
5
5
 
6
6
 
7
7
  export function sendOK(response) {
8
- response.end()
9
- }
10
-
11
- export function sendNoContent(response) {
12
- response.statusCode = 204
8
+ logger.access(response)
13
9
  response.end()
14
10
  }
15
11
 
16
12
  export function sendJSON(response, payload) {
13
+ logger.access(response)
17
14
  response.setHeader('Content-Type', 'application/json')
18
15
  response.end(JSON.stringify(payload))
19
16
  }
20
17
 
21
18
  export function sendFile(response, file) {
19
+ logger.access(response)
22
20
  response.setHeader('Content-Type', mimeFor(file))
23
21
  response.end(readFileSync(file, 'utf8'))
24
22
  }
25
23
 
24
+ export function sendNoContent(response) {
25
+ response.statusCode = 204
26
+ logger.access(response)
27
+ response.end()
28
+ }
29
+
30
+
26
31
  export function sendNotFound(response) {
27
32
  response.statusCode = 404
33
+ logger.access(response)
28
34
  response.end()
29
35
  }
30
36
 
31
37
  export function sendUnprocessableContent(response, error) {
32
- log.warn(error)
38
+ logger.warn(error)
33
39
  response.statusCode = 422
34
40
  response.end(error)
35
41
  }
36
42
 
43
+
37
44
  export function sendInternalServerError(response, error) {
38
- log.error(error?.message || error, error?.stack || undefined)
45
+ logger.error(error?.message || error, error?.stack || undefined)
39
46
  response.statusCode = 500
40
47
  response.end()
41
48
  }
42
49
 
43
50
  export function sendBadGateway(response, error) {
44
- log.warn('Fallback Proxy Error:', error.cause.message)
51
+ logger.warn('Fallback Proxy Error:', error.cause.message)
45
52
  response.statusCode = 502
46
53
  response.setHeader(HEADER_FOR_502, 1)
47
54
  response.end()
@@ -0,0 +1,42 @@
1
+ export const logger = new class {
2
+ #level = 'normal'
3
+
4
+ setLevel(level) {
5
+ this.#level = level
6
+ }
7
+
8
+ info(...msg) {
9
+ if (this.#level !== 'quiet')
10
+ console.info(this.#msg('INFO', ...msg))
11
+ }
12
+
13
+ accessMock(url, ...msg) {
14
+ if (this.#level !== 'quiet')
15
+ console.log(this.#msg('MOCK', this.#sanitizeURL(url), ...msg))
16
+ }
17
+
18
+ access(response) {
19
+ if (this.#level === 'verbose')
20
+ console.log(this.#msg(
21
+ 'ACCESS',
22
+ response.req.method,
23
+ response.statusCode,
24
+ this.#sanitizeURL(response.req.url)))
25
+ }
26
+
27
+ warn(...msg) {
28
+ console.warn(this.#msg('WARN', ...msg))
29
+ }
30
+
31
+ error(...msg) {
32
+ console.error(this.#msg('ERROR', ...msg))
33
+ }
34
+
35
+ #msg(...msg) {
36
+ return [new Date().toISOString(), ...msg].join('::')
37
+ }
38
+
39
+ #sanitizeURL(url) {
40
+ return decodeURIComponent(url).replace(/[\x00-\x1F\x7F\x9B]/g, '')
41
+ }
42
+ }
package/src/utils/log.js DELETED
@@ -1,34 +0,0 @@
1
- export const log = new class {
2
- #level = 'normal'
3
-
4
- setLevel(level) {
5
- this.#level = level
6
- }
7
-
8
- info(...msg) {
9
- if (this.#level !== 'quiet')
10
- console.info([this.#date, 'INFO', ...msg].join('::'))
11
- }
12
-
13
- access(url, ...msg) {
14
- if (this.#level !== 'quiet')
15
- console.log([this.#date, 'ACCESS', this.#sanitizeURL(url), ...msg].join('::'))
16
- }
17
-
18
- warn(...msg) {
19
- console.warn([this.#date, 'WARN', ...msg].join('::'))
20
- }
21
-
22
- error(...msg) {
23
- console.error([this.#date, 'ERROR', ...msg].join('::'))
24
- }
25
-
26
-
27
- get #date() {
28
- return new Date().toISOString()
29
- }
30
-
31
- #sanitizeURL(url) {
32
- return decodeURIComponent(url).replace(/[\x00-\x1F\x7F\x9B]/g, '')
33
- }
34
- }