mockaton 12.7.2 → 13.0.1
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 +53 -17
- package/index.d.ts +2 -13
- package/package.json +4 -9
- package/src/client/ApiCommander.js +3 -7
- package/src/client/ApiConstants.js +1 -4
- package/src/client/Filename.js +20 -20
- package/src/client/app-header.js +6 -6
- package/src/client/app-payload-viewer.js +47 -16
- package/src/client/app-store.js +11 -64
- package/src/client/app-store.test.js +15 -1
- package/src/client/app.css +51 -38
- package/src/client/app.js +28 -100
- package/src/client/{app-icons.js → graphics.js} +1 -1
- package/src/client/watcherDev.js +7 -7
- package/src/server/Api.js +4 -38
- package/src/server/MockBroker.js +16 -13
- package/src/server/MockDispatcher.js +18 -4
- package/src/server/Mockaton.js +1 -8
- package/src/server/Mockaton.test.config.js +1 -3
- package/src/server/Mockaton.test.js +65 -181
- package/src/server/Watcher.js +0 -32
- package/src/server/cli.js +9 -13
- package/src/server/cli.test.js +4 -5
- package/src/server/config.js +0 -7
- package/src/server/mockBrokersCollection.js +11 -13
- package/src/server/StaticDispatcher.js +0 -36
- package/src/server/staticCollection.js +0 -56
package/src/server/cli.test.js
CHANGED
|
@@ -12,7 +12,7 @@ const cli = (...args) => spawnSync(rel('cli.js'), args, { encoding: 'utf8' })
|
|
|
12
12
|
describe('CLI', () => {
|
|
13
13
|
test('invalid flag', () => {
|
|
14
14
|
const { stderr, status } = cli('--invalid-flag')
|
|
15
|
-
equal(stderr.
|
|
15
|
+
equal(stderr.startsWith(`Unknown option '--invalid-flag'`), true)
|
|
16
16
|
equal(status, 1)
|
|
17
17
|
})
|
|
18
18
|
|
|
@@ -24,9 +24,8 @@ describe('CLI', () => {
|
|
|
24
24
|
|
|
25
25
|
test('invalid port', () => {
|
|
26
26
|
const { stderr, status } = cli(
|
|
27
|
-
|
|
28
|
-
'--port', 'not-a-number'
|
|
29
|
-
)
|
|
27
|
+
rel('../../mockaton-mocks'),
|
|
28
|
+
'--port', 'not-a-number')
|
|
30
29
|
equal(stderr.trim(), `port="not-a-number" is invalid`)
|
|
31
30
|
equal(status, 1)
|
|
32
31
|
})
|
|
@@ -39,7 +38,7 @@ describe('CLI', () => {
|
|
|
39
38
|
|
|
40
39
|
test('-h outputs usage message', () => {
|
|
41
40
|
const { stdout, status } = cli('-h')
|
|
42
|
-
equal(stdout.split('\n')[0], 'Usage: mockaton [options]')
|
|
41
|
+
equal(stdout.split('\n')[0], 'Usage: mockaton [mocks-dir] [options]')
|
|
43
42
|
equal(status, 0)
|
|
44
43
|
})
|
|
45
44
|
|
package/src/server/config.js
CHANGED
|
@@ -7,7 +7,6 @@ import { openInBrowser } from './utils/openInBrowser.js'
|
|
|
7
7
|
import { optional, is, validate } from './utils/validate.js'
|
|
8
8
|
import { validateCorsAllowedMethods, validateCorsAllowedOrigins } from './utils/http-cors.js'
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
import { jsToJsonPlugin } from './MockDispatcherPlugins.js'
|
|
12
11
|
|
|
13
12
|
|
|
@@ -19,7 +18,6 @@ import { jsToJsonPlugin } from './MockDispatcherPlugins.js'
|
|
|
19
18
|
* }} */
|
|
20
19
|
const schema = {
|
|
21
20
|
mocksDir: [resolve('mockaton-mocks'), isDirectory],
|
|
22
|
-
staticDir: [resolve('mockaton-static-mocks'), optional(isDirectory)],
|
|
23
21
|
ignore: [/(\.DS_Store|~)$/, is(RegExp)],
|
|
24
22
|
watcherEnabled: [true, is(Boolean)],
|
|
25
23
|
watcherDebounceMs: [80, ms => Number.isInteger(ms) && ms >= 0],
|
|
@@ -78,11 +76,6 @@ export function setup(opts) {
|
|
|
78
76
|
if (opts.mocksDir)
|
|
79
77
|
opts.mocksDir = resolve(opts.mocksDir)
|
|
80
78
|
|
|
81
|
-
if (opts.staticDir)
|
|
82
|
-
opts.staticDir = resolve(opts.staticDir)
|
|
83
|
-
else if (!isDirectory(defaults.staticDir))
|
|
84
|
-
opts.staticDir = ''
|
|
85
|
-
|
|
86
79
|
Object.assign(config, opts)
|
|
87
80
|
validate(config, ConfigValidator)
|
|
88
81
|
logger.setLevel(config.logLevel)
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { basename } from 'node:path'
|
|
2
2
|
|
|
3
|
-
import { logger } from './utils/logger.js'
|
|
4
|
-
import { listFilesRecursively } from './utils/fs.js'
|
|
5
|
-
|
|
6
3
|
import { cookie } from './cookie.js'
|
|
7
4
|
import { MockBroker } from './MockBroker.js'
|
|
5
|
+
import { parseFilename } from '../client/Filename.js'
|
|
6
|
+
import { listFilesRecursively } from './utils/fs.js'
|
|
8
7
|
import { config, isFileAllowed } from './config.js'
|
|
9
|
-
import { parseFilename, validateFilename } from '../client/Filename.js'
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
/**
|
|
@@ -42,8 +40,7 @@ export function init() {
|
|
|
42
40
|
/** @returns {boolean} registered */
|
|
43
41
|
export function registerMock(file, isFromWatcher = false) {
|
|
44
42
|
if (brokerByFilename(file)?.hasMock(file)
|
|
45
|
-
|| !isFileAllowed(basename(file))
|
|
46
|
-
|| !filenameIsValid(file))
|
|
43
|
+
|| !isFileAllowed(basename(file)))
|
|
47
44
|
return false
|
|
48
45
|
|
|
49
46
|
const { method, urlMask } = parseFilename(file)
|
|
@@ -62,13 +59,6 @@ export function registerMock(file, isFromWatcher = false) {
|
|
|
62
59
|
return true
|
|
63
60
|
}
|
|
64
61
|
|
|
65
|
-
function filenameIsValid(file) {
|
|
66
|
-
const error = validateFilename(file)
|
|
67
|
-
if (error)
|
|
68
|
-
logger.warn(error, file)
|
|
69
|
-
return !error
|
|
70
|
-
}
|
|
71
|
-
|
|
72
62
|
export function unregisterMock(file) {
|
|
73
63
|
const broker = brokerByFilename(file)
|
|
74
64
|
const hasNoMoreMocks = broker?.unregister(file)
|
|
@@ -99,6 +89,14 @@ export function brokerByRoute(method, url) {
|
|
|
99
89
|
for (let i = brokers.length - 1; i >= 0; i--)
|
|
100
90
|
if (brokers[i].urlMaskMatches(url))
|
|
101
91
|
return brokers[i]
|
|
92
|
+
|
|
93
|
+
// TODO Verify
|
|
94
|
+
if (method === 'GET') {
|
|
95
|
+
const indexUrl = url.endsWith('/') ? url + 'index.html' : url + '/index.html'
|
|
96
|
+
for (let i = brokers.length - 1; i >= 0; i--)
|
|
97
|
+
if (brokers[i].urlMaskMatches(indexUrl))
|
|
98
|
+
return brokers[i]
|
|
99
|
+
}
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
export function extractAllComments() {
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path'
|
|
2
|
-
import { readFileSync } from 'node:fs'
|
|
3
|
-
|
|
4
|
-
import { isFile } from './utils/fs.js'
|
|
5
|
-
import { logger } from './utils/logger.js'
|
|
6
|
-
import { mimeFor } from './utils/mime.js'
|
|
7
|
-
|
|
8
|
-
import { brokerByRoute } from './staticCollection.js'
|
|
9
|
-
import { config, calcDelay } from './config.js'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// TODO HEAD
|
|
13
|
-
export async function dispatchStatic(req, response) {
|
|
14
|
-
const broker = brokerByRoute(req.url)
|
|
15
|
-
|
|
16
|
-
setTimeout(async () => {
|
|
17
|
-
if (!broker || broker.status === 404) {
|
|
18
|
-
response.mockNotFound()
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const file = join(config.staticDir, broker.route)
|
|
23
|
-
if (!isFile(file)) {
|
|
24
|
-
response.mockNotFound()
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
logger.accessMock(req.url, 'static200')
|
|
29
|
-
if (req.headers.range)
|
|
30
|
-
await response.partialContent(req.headers.range, file)
|
|
31
|
-
else {
|
|
32
|
-
response.setHeader('Content-Type', mimeFor(file))
|
|
33
|
-
response.end(readFileSync(file))
|
|
34
|
-
}
|
|
35
|
-
}, Number(broker.delayed && calcDelay()))
|
|
36
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { join, basename } from 'node:path'
|
|
2
|
-
import { listFilesRecursively } from './utils/fs.js'
|
|
3
|
-
import { config, isFileAllowed } from './config.js'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class StaticBroker {
|
|
7
|
-
constructor(route) {
|
|
8
|
-
this.route = route
|
|
9
|
-
this.delayed = false
|
|
10
|
-
this.status = 200 // 200 or 404
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
setDelayed(value) { this.delayed = value }
|
|
14
|
-
setStatus(value) { this.status = value }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** @type {{ [route:string]: StaticBroker }} */
|
|
18
|
-
let collection = {}
|
|
19
|
-
|
|
20
|
-
export const all = () => collection
|
|
21
|
-
|
|
22
|
-
export function init() {
|
|
23
|
-
collection = {}
|
|
24
|
-
listFilesRecursively(config.staticDir)
|
|
25
|
-
.sort()
|
|
26
|
-
.forEach(registerMock)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/** @returns {boolean} registered */
|
|
31
|
-
export function registerMock(relativeFile) {
|
|
32
|
-
if (!isFileAllowed(basename(relativeFile)))
|
|
33
|
-
return false
|
|
34
|
-
|
|
35
|
-
const route = '/' + relativeFile
|
|
36
|
-
if (brokerByRoute(route))
|
|
37
|
-
return false
|
|
38
|
-
|
|
39
|
-
collection[route] = new StaticBroker(route)
|
|
40
|
-
return true
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
export function unregisterMock(relativeFile) {
|
|
45
|
-
delete collection['/' + relativeFile]
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/** @returns {StaticBroker | undefined} */
|
|
50
|
-
export function brokerByRoute(route) {
|
|
51
|
-
return collection[route] || collection[join(route, 'index.html')]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|