mockaton 13.4.1 → 13.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 +1 -1
- package/package.json +1 -1
- package/src/client/ApiCommander.js +2 -0
- package/src/client/ApiConstants.js +19 -11
- package/src/server/Api.js +3 -3
- package/src/server/Mockaton.test.js +14 -2
- package/src/server/ProxyRelay.js +2 -1
- package/www/src/assets/openapi.json +27 -19
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ export default {
|
|
|
79
79
|
|
|
80
80
|
<br/>
|
|
81
81
|
|
|
82
|
-
Similarly, you can handle logic with [
|
|
82
|
+
Similarly, you can handle logic with [Function Mocks](https://mockaton.com/function-mocks):
|
|
83
83
|
|
|
84
84
|
<code>my_mocks_dir/<b>api/company/[companyId]/user/[userId]</b>.GET.200.ts</code>
|
|
85
85
|
```ts
|
package/package.json
CHANGED
|
@@ -4,25 +4,33 @@ const MOUNT = '/mockaton'
|
|
|
4
4
|
|
|
5
5
|
export const API = {
|
|
6
6
|
dashboard: MOUNT,
|
|
7
|
+
|
|
8
|
+
reset: MOUNT + '/reset',
|
|
9
|
+
|
|
10
|
+
select: MOUNT + '/select',
|
|
7
11
|
bulkSelect: MOUNT + '/bulk-select-by-comment',
|
|
8
|
-
|
|
9
|
-
cookies: MOUNT + '/cookies',
|
|
10
|
-
cors: MOUNT + '/cors',
|
|
12
|
+
|
|
11
13
|
delay: MOUNT + '/delay',
|
|
14
|
+
proxied: MOUNT + '/proxied',
|
|
15
|
+
toggleStatus: MOUNT + '/toggle-status',
|
|
16
|
+
|
|
17
|
+
cors: MOUNT + '/cors',
|
|
18
|
+
cookies: MOUNT + '/cookies',
|
|
12
19
|
fallback: MOUNT + '/fallback',
|
|
20
|
+
collectProxied: MOUNT + '/collect-proxied',
|
|
13
21
|
globalDelay: MOUNT + '/global-delay',
|
|
14
22
|
globalDelayJitter: MOUNT + '/global-delay-jitter',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
|
|
24
|
+
writeMock: MOUNT + '/write-mock',
|
|
25
|
+
deleteMock: MOUNT + '/delete-mock',
|
|
26
|
+
watchMocks: MOUNT + '/watch-mocks',
|
|
27
|
+
|
|
18
28
|
state: MOUNT + '/state',
|
|
19
|
-
syncVersion: MOUNT + '/sync-version',
|
|
20
29
|
throws: MOUNT + '/throws',
|
|
21
|
-
|
|
30
|
+
syncVersion: MOUNT + '/sync-version',
|
|
22
31
|
watchHotReload: MOUNT + '/watch-hot-reload',
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
deleteMock: MOUNT + '/delete-mock',
|
|
32
|
+
|
|
33
|
+
openAPI: MOUNT + '/openapi'
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
export const DEFAULT_MOCK_COMMENT = '(default)'
|
package/src/server/Api.js
CHANGED
|
@@ -7,6 +7,7 @@ import { join } from 'node:path'
|
|
|
7
7
|
import { readdirSync } from 'node:fs'
|
|
8
8
|
import { write, rm, isFile, resolveIn } from './utils/fs.js'
|
|
9
9
|
|
|
10
|
+
import openapi from '../../www/src/assets/openapi.json' with { type: 'json' }
|
|
10
11
|
import pkgJSON from '../../package.json' with { type: 'json' }
|
|
11
12
|
|
|
12
13
|
import { sseClientHotReload } from './utils/WatcherDevClient.js'
|
|
@@ -24,7 +25,6 @@ export const CLIENT_DIR = join(import.meta.dirname, '../client')
|
|
|
24
25
|
const DASHBOARD_ASSETS = readdirSync(CLIENT_DIR, { recursive: true })
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
|
|
28
28
|
export const apiGetReqs = new Map([
|
|
29
29
|
[API.dashboard, serveDashboard],
|
|
30
30
|
...DASHBOARD_ASSETS.map(f => [API.dashboard + '/' + f, serveStatic(f)]),
|
|
@@ -33,7 +33,8 @@ export const apiGetReqs = new Map([
|
|
|
33
33
|
[API.syncVersion, sseClientSyncVersion],
|
|
34
34
|
|
|
35
35
|
[API.watchHotReload, onDevWatch],
|
|
36
|
-
[API.throws, () => { throw new Error('Test500') }]
|
|
36
|
+
[API.throws, () => { throw new Error('Test500') }],
|
|
37
|
+
[API.openAPI, (_, response) => response.json(openapi)]
|
|
37
38
|
])
|
|
38
39
|
|
|
39
40
|
|
|
@@ -96,7 +97,6 @@ function onDevWatch(req, response) {
|
|
|
96
97
|
else
|
|
97
98
|
response.notFound()
|
|
98
99
|
}
|
|
99
|
-
|
|
100
100
|
/** # PATCH */
|
|
101
101
|
|
|
102
102
|
function reset(_, response) {
|
|
@@ -74,7 +74,7 @@ function request(path, options = {}) {
|
|
|
74
74
|
class Fixture {
|
|
75
75
|
constructor(file, body = '') {
|
|
76
76
|
this.file = file
|
|
77
|
-
this.body = body || `Body for ${file}`
|
|
77
|
+
this.body = body || `Body for: ${file}`
|
|
78
78
|
const t = parseFilename(file)
|
|
79
79
|
this.urlMask = t.urlMask
|
|
80
80
|
this.method = t.method
|
|
@@ -227,6 +227,14 @@ describe('Dashboard', () => {
|
|
|
227
227
|
})
|
|
228
228
|
|
|
229
229
|
|
|
230
|
+
describe('OpenAPI', () => {
|
|
231
|
+
test('serves the json spec', async () => {
|
|
232
|
+
const r = await request(API.openAPI)
|
|
233
|
+
match(await r.text(), new RegExp('"openapi":'))
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
|
|
230
238
|
describe('Cookie', () => {
|
|
231
239
|
test('422 when trying to select non-existing cookie', async () => {
|
|
232
240
|
const r = await api.selectCookie('non-existing-cookie-key')
|
|
@@ -336,7 +344,8 @@ describe('Proxy Fallback', () => {
|
|
|
336
344
|
response.writeHead(423, {
|
|
337
345
|
'custom_header': 'my_custom_header',
|
|
338
346
|
'content-type': mimeFor('.json'),
|
|
339
|
-
'set-cookie': CUSTOM_COOKIES
|
|
347
|
+
'set-cookie': CUSTOM_COOKIES,
|
|
348
|
+
'cache-control': 'public'
|
|
340
349
|
})
|
|
341
350
|
response.end(JSON.stringify(BODY_PAYLOAD))
|
|
342
351
|
})
|
|
@@ -360,6 +369,9 @@ describe('Proxy Fallback', () => {
|
|
|
360
369
|
equal(r1.headers.get('set-cookie'), CUSTOM_COOKIES.join(', '))
|
|
361
370
|
equal(r2.headers.get('set-cookie'), CUSTOM_COOKIES.join(', '))
|
|
362
371
|
|
|
372
|
+
equal(r1.headers.get('cache-control'), 'no-cache') // unsets cache
|
|
373
|
+
equal(r2.headers.get('cache-control'), 'no-cache')
|
|
374
|
+
|
|
363
375
|
deepEqual(await r2.json(), BODY_PAYLOAD)
|
|
364
376
|
deepEqual(await r1.json(), BODY_PAYLOAD)
|
|
365
377
|
|
package/src/server/ProxyRelay.js
CHANGED
|
@@ -34,7 +34,8 @@ export async function proxy(req, response, delay) {
|
|
|
34
34
|
|
|
35
35
|
response.writeHead(proxyResponse.status, {
|
|
36
36
|
...Object.fromEntries(proxyResponse.headers),
|
|
37
|
-
'
|
|
37
|
+
'set-cookie': proxyResponse.headers.getSetCookie(), // parses multiple into an array
|
|
38
|
+
'cache-control': 'no-cache'
|
|
38
39
|
})
|
|
39
40
|
const body = await proxyResponse.text()
|
|
40
41
|
setTimeout(() => response.end(body), delay) // TESTME
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"openapi": "3.
|
|
2
|
+
"openapi": "3.2.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Mockaton Control API",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.1"
|
|
6
6
|
},
|
|
7
7
|
"servers": [
|
|
8
8
|
{
|
|
@@ -10,6 +10,26 @@
|
|
|
10
10
|
}
|
|
11
11
|
],
|
|
12
12
|
"paths": {
|
|
13
|
+
"/mockaton/openapi": {
|
|
14
|
+
"get": {
|
|
15
|
+
"summary": "Get this OpenAPI spec",
|
|
16
|
+
"x-js-client-example": "await mockaton.getOpenAPI()",
|
|
17
|
+
"responses": {
|
|
18
|
+
"200": {
|
|
19
|
+
"description": "OpenAPI spec",
|
|
20
|
+
"content": {
|
|
21
|
+
"application/json": {
|
|
22
|
+
"schema": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
13
33
|
"/mockaton/state": {
|
|
14
34
|
"get": {
|
|
15
35
|
"summary": "Get complete Mockaton state",
|
|
@@ -488,29 +508,17 @@
|
|
|
488
508
|
},
|
|
489
509
|
"/mockaton/sync-version": {
|
|
490
510
|
"get": {
|
|
491
|
-
"summary": "Get sync version
|
|
511
|
+
"summary": "Get sync version as SSE",
|
|
492
512
|
"description": "A counter that’s incremented when a new mock is added, removed, or renamed. Also, when the internal state changes, e.g., when changing the mock file for a route.",
|
|
493
513
|
"x-js-client-example": "await mockaton.getSyncVersion()",
|
|
494
|
-
"parameters": [
|
|
495
|
-
{
|
|
496
|
-
"name": "sync_version",
|
|
497
|
-
"in": "header",
|
|
498
|
-
"required": false,
|
|
499
|
-
"example": -1,
|
|
500
|
-
"schema": {
|
|
501
|
-
"type": "number"
|
|
502
|
-
},
|
|
503
|
-
"description": "When not present, or when the version mismatches it responds right away. Otherwise, it long polls. Times out in 8s."
|
|
504
|
-
}
|
|
505
|
-
],
|
|
506
514
|
"responses": {
|
|
507
515
|
"200": {
|
|
508
|
-
"description": "
|
|
516
|
+
"description": "Stream of sync version updates (SSE)",
|
|
509
517
|
"content": {
|
|
510
|
-
"
|
|
518
|
+
"text/event-stream": {
|
|
511
519
|
"schema": {
|
|
512
|
-
"type": "
|
|
513
|
-
"description": "Incremental
|
|
520
|
+
"type": "integer",
|
|
521
|
+
"description": "Incremental sync version emitted per event"
|
|
514
522
|
}
|
|
515
523
|
}
|
|
516
524
|
}
|