mockaton 1.0.0 → 2.0.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-dashboard.png +0 -0
- package/README.md +21 -23
- package/Tests.js +20 -22
- package/package.json +1 -1
- package/sample-mocks/api/user/likes.GET.200.js +7 -0
- package/sample-mocks/api/user/loves.GET.200.js +7 -0
- package/src/Api.js +0 -14
- package/src/ApiConstants.js +1 -3
- package/src/Config.js +3 -3
- package/src/Dashboard.css +0 -6
- package/src/Dashboard.js +4 -53
- package/src/MockBroker.js +5 -20
- package/src/MockDispatcher.js +12 -18
- package/src/mockBrokersCollection.js +1 -1
- package/sample-mocks/api/video/list(concat newly uploaded).GET.200.mjs +0 -8
- package/sample-mocks/api/video/list.GET.200.json +0 -11
- package/sample-mocks/api/video/upload(insert newly uploaded).POST.201.mjs +0 -10
- package/sample-mocks/api/video/upload.POST.201.json +0 -3
- /package/sample-mocks/api/{video/list.GET.500.txt → user/likes.GET.500.txt} +0 -0
- /package/sample-mocks/api/{video/upload.POST.500.txt → user/loves.GET.500.txt} +0 -0
package/README-dashboard.png
CHANGED
|
Binary file
|
package/README.md
CHANGED
|
@@ -26,6 +26,26 @@ UI, or programmatically, for instance, for setting up tests.
|
|
|
26
26
|
|
|
27
27
|
The first file in **alphabetical order** becomes the default mock.
|
|
28
28
|
|
|
29
|
+
### Optionally, you can write mocks in JavaScript
|
|
30
|
+
An Object, Array, or String is sent as JSON.
|
|
31
|
+
|
|
32
|
+
`api/user/likes.GET.200.js`
|
|
33
|
+
```js
|
|
34
|
+
export default [
|
|
35
|
+
{ id: 0 }
|
|
36
|
+
]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or, export default a function. There, you
|
|
40
|
+
can override the response status and the default JSON content
|
|
41
|
+
type. But don’t call `response.end()`, just return a string.
|
|
42
|
+
```js
|
|
43
|
+
export default function (req, response) {
|
|
44
|
+
return JSON.stringify({ a: 1 })
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
29
49
|
### Proxying Routes
|
|
30
50
|
`Config.proxyFallback` lets you specify a target
|
|
31
51
|
server for serving routes you don’t have mocks for.
|
|
@@ -75,10 +95,9 @@ interface Config {
|
|
|
75
95
|
port?: number // defaults to 0, which means auto-assigned
|
|
76
96
|
delay?: number // defaults to 1200 (ms)
|
|
77
97
|
cookies?: object
|
|
78
|
-
database?: object // for "Transforms"
|
|
79
98
|
skipOpen?: boolean // Prevents opening the dashboard in a browser
|
|
80
99
|
proxyFallback?: string // e.g. http://localhost:9999 Target for relaying routes without mocks
|
|
81
|
-
allowedExt?: RegExp // /\.(json|txt|md|
|
|
100
|
+
allowedExt?: RegExp // /\.(json|txt|md|js)$/ Just for excluding temporary editor files (e.g. JetBrains appends a ~)
|
|
82
101
|
}
|
|
83
102
|
```
|
|
84
103
|
|
|
@@ -164,19 +183,6 @@ api/foo/[user-id].POST.201.md
|
|
|
164
183
|
api/foo/[user-id].POST.201.json
|
|
165
184
|
```
|
|
166
185
|
|
|
167
|
-
## Transforms (.mjs)
|
|
168
|
-
Using the same filename convention, files ending
|
|
169
|
-
with `.mjs` will process the mock before serving it.
|
|
170
|
-
|
|
171
|
-
For example, this handler will capitalize the mock body and increment a counter.
|
|
172
|
-
```js
|
|
173
|
-
export default function capitalizeAllText(mockAsText, requestBody, config) {
|
|
174
|
-
config.database.myCount ??= 0
|
|
175
|
-
config.database.myCount++
|
|
176
|
-
return mockAsText.toUpperCase()
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
186
|
|
|
181
187
|
## API
|
|
182
188
|
|
|
@@ -223,14 +229,6 @@ Sends a list of the available cookies along with a flag indicated if it’s the
|
|
|
223
229
|
fetch(addr + '/mockaton/cookies')
|
|
224
230
|
```
|
|
225
231
|
|
|
226
|
-
### Select a Transform
|
|
227
|
-
```js
|
|
228
|
-
fetch(addr + '/mockaton/transform', {
|
|
229
|
-
method: 'PATCH',
|
|
230
|
-
body: JSON.stringify('api/video/list(concat newly uploaded).GET.200.mjs')
|
|
231
|
-
})
|
|
232
|
-
```
|
|
233
|
-
|
|
234
232
|
### Update Fallback Proxy
|
|
235
233
|
```js
|
|
236
234
|
fetch(addr + '/mockaton/fallback', {
|
package/Tests.js
CHANGED
|
@@ -96,6 +96,9 @@ write('api/.GET.500.txt', 'keeps non-autogenerated 500')
|
|
|
96
96
|
write('api/alternative(comment-2).GET.200.json', JSON.stringify({ comment: 2 }))
|
|
97
97
|
write('api/my-route(comment-2).GET.200.json', JSON.stringify({ comment: 2 }))
|
|
98
98
|
|
|
99
|
+
// JavaScript to JSON
|
|
100
|
+
write('/api/object.GET.200.js', 'export default { JSON_FROM_JS: true }')
|
|
101
|
+
|
|
99
102
|
writeStatic('index.html', '<h1>Static</h1>')
|
|
100
103
|
writeStatic('assets/app.js', 'const app = 1')
|
|
101
104
|
writeStatic('another-entry/index.html', '<h1>Another</h1>')
|
|
@@ -154,9 +157,11 @@ async function runTests() {
|
|
|
154
157
|
await reset()
|
|
155
158
|
for (const [url, file, body] of fixtures)
|
|
156
159
|
await testMockDispatching(url, file, body)
|
|
160
|
+
|
|
161
|
+
await testMockDispatching('/api/object', 'api/object.GET.200.js', { JSON_FROM_JS: true }, mimeFor('.json'))
|
|
162
|
+
await testJsFunctionMocks()
|
|
157
163
|
|
|
158
164
|
await testItUpdatesUserRole()
|
|
159
|
-
await testTransforms()
|
|
160
165
|
await testStaticFileServing()
|
|
161
166
|
await testInvalidFilenamesAreIgnored()
|
|
162
167
|
await testEnableFallbackSoRoutesWithoutMocksGetRelayed()
|
|
@@ -185,11 +190,11 @@ async function test404() {
|
|
|
185
190
|
})
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
async function testMockDispatching(url, file, expectedBody,
|
|
193
|
+
async function testMockDispatching(url, file, expectedBody, forcedMime = void 0) {
|
|
189
194
|
const { urlMask, method, status } = Route.parseFilename(file)
|
|
190
|
-
const mime = mimeFor(file)
|
|
195
|
+
const mime = forcedMime || mimeFor(file)
|
|
191
196
|
const now = new Date()
|
|
192
|
-
const res = await request(url, { method
|
|
197
|
+
const res = await request(url, { method })
|
|
193
198
|
const body = mime === 'application/json'
|
|
194
199
|
? await res.json()
|
|
195
200
|
: await res.text()
|
|
@@ -300,25 +305,18 @@ async function testItUpdatesUserRole() {
|
|
|
300
305
|
})
|
|
301
306
|
}
|
|
302
307
|
|
|
303
|
-
async function
|
|
304
|
-
await describe('
|
|
305
|
-
write('api/
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
body.push(reqBody[0]);
|
|
310
|
-
body.push(config.mocksDir);
|
|
311
|
-
return JSON.stringify(body);
|
|
308
|
+
async function testJsFunctionMocks() {
|
|
309
|
+
await describe('JS Function Mocks', async () => {
|
|
310
|
+
write('api/js-func.POST.200.js', `
|
|
311
|
+
export default function (req, response) {
|
|
312
|
+
response.setHeader('content-type', 'custom-mime')
|
|
313
|
+
return 'SOME_STRING'
|
|
312
314
|
}`)
|
|
313
|
-
await reset() // for registering the
|
|
314
|
-
await
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
await testMockDispatching('/api/transform',
|
|
319
|
-
'api/transform.POST.200.json',
|
|
320
|
-
['initial', 'another', tmpDir],
|
|
321
|
-
JSON.stringify(['another']))
|
|
315
|
+
await reset() // for registering the file
|
|
316
|
+
await testMockDispatching('/api/js-func',
|
|
317
|
+
'api/js-func.POST.200.js',
|
|
318
|
+
'SOME_STRING',
|
|
319
|
+
'custom-mime')
|
|
322
320
|
})
|
|
323
321
|
}
|
|
324
322
|
|
package/package.json
CHANGED
package/src/Api.js
CHANGED
|
@@ -28,7 +28,6 @@ export const apiPatchRequests = new Map([
|
|
|
28
28
|
[API.edit, updateBroker],
|
|
29
29
|
[API.reset, reinitialize],
|
|
30
30
|
[API.cookies, selectCookie],
|
|
31
|
-
[API.transform, updateBrokerTransform],
|
|
32
31
|
[API.fallback, updateProxyFallback]
|
|
33
32
|
])
|
|
34
33
|
|
|
@@ -92,19 +91,6 @@ async function bulkUpdateBrokersByCommentTag(req, response) {
|
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
async function updateBrokerTransform(req, response) {
|
|
96
|
-
try {
|
|
97
|
-
const file = await parseJSON(req)
|
|
98
|
-
const broker = mockBrokersCollection.getBrokerByFilename(file)
|
|
99
|
-
broker.updateTransform(file)
|
|
100
|
-
sendOK(response)
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
console.error(error)
|
|
104
|
-
sendBadRequest(response)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
94
|
async function updateProxyFallback(req, response) {
|
|
109
95
|
try {
|
|
110
96
|
Config.proxyFallback = await parseJSON(req)
|
package/src/ApiConstants.js
CHANGED
|
@@ -6,13 +6,11 @@ export const API = {
|
|
|
6
6
|
edit: MOUNT + '/edit',
|
|
7
7
|
mocks: MOUNT + '/mocks',
|
|
8
8
|
reset: MOUNT + '/reset',
|
|
9
|
-
transform: MOUNT + '/transform',
|
|
10
9
|
cookies: MOUNT + '/cookies',
|
|
11
10
|
fallback: MOUNT + '/fallback'
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
export const DF = { // Dashboard Fields (XHR)
|
|
15
14
|
delayed: 'delayed',
|
|
16
|
-
file: 'file'
|
|
17
|
-
isForDashboard: 'mock_request_payload'
|
|
15
|
+
file: 'file'
|
|
18
16
|
}
|
package/src/Config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, lstatSync } from 'node:fs'
|
|
1
|
+
import { existsSync as exists, lstatSync } from 'node:fs'
|
|
2
2
|
import { validate, is, optional } from './utils/validate.js'
|
|
3
3
|
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ export const Config = {
|
|
|
12
12
|
database: {},
|
|
13
13
|
skipOpen: false,
|
|
14
14
|
proxyFallback: '', // e.g. http://localhost:9999
|
|
15
|
-
allowedExt: /\.(json|txt|md|
|
|
15
|
+
allowedExt: /\.(json|txt|md|js)$/ // Just for excluding temporary editor files (e.g. JetBrains appends a ~)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export function setup(options) {
|
|
@@ -32,7 +32,7 @@ export function setup(options) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function isDirectory(dir) {
|
|
35
|
-
return
|
|
35
|
+
return exists(dir) && lstatSync(dir).isDirectory()
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
|
package/src/Dashboard.css
CHANGED
|
@@ -135,17 +135,11 @@ main {
|
|
|
135
135
|
.BulkSelectSection {
|
|
136
136
|
margin: 20px 0;
|
|
137
137
|
}
|
|
138
|
-
.TransformsSection {
|
|
139
|
-
padding-top: 30px;
|
|
140
|
-
border-top: 1px solid #ccc;
|
|
141
|
-
margin: 30px 0;
|
|
142
|
-
}
|
|
143
138
|
|
|
144
139
|
.BulkSelectSection select {
|
|
145
140
|
margin-top: 5px;
|
|
146
141
|
}
|
|
147
142
|
|
|
148
|
-
.TransformSelector,
|
|
149
143
|
.MockSelector {
|
|
150
144
|
width: 300px;
|
|
151
145
|
padding: 8px 1px;
|
package/src/Dashboard.js
CHANGED
|
@@ -10,11 +10,9 @@ const Strings = {
|
|
|
10
10
|
empty_response_body: '/* Empty Response Body */',
|
|
11
11
|
fetching: '⌚ Fetching…',
|
|
12
12
|
mock: 'Mock',
|
|
13
|
-
none: 'None',
|
|
14
13
|
reset: 'Reset',
|
|
15
14
|
select_one: 'Select One',
|
|
16
|
-
title: 'Mockaton'
|
|
17
|
-
transforms: 'Transforms'
|
|
15
|
+
title: 'Mockaton'
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
const CSS = {
|
|
@@ -26,8 +24,6 @@ const CSS = {
|
|
|
26
24
|
PayloadViewer: 'PayloadViewer',
|
|
27
25
|
PreviewLink: 'PreviewLink',
|
|
28
26
|
TitleWrap: 'TitleWrap',
|
|
29
|
-
TransformSelector: 'TransformSelector',
|
|
30
|
-
TransformsSection: 'TransformsSection',
|
|
31
27
|
|
|
32
28
|
bold: 'bold',
|
|
33
29
|
chosen: 'chosen',
|
|
@@ -74,10 +70,7 @@ function DevPanel(brokersByMethod, cookies, comments) {
|
|
|
74
70
|
r('div', { className: CSS.PayloadViewer },
|
|
75
71
|
r('pre', { ref: refDocumentation, className: CSS.Documentation }),
|
|
76
72
|
r('h2', { ref: refPayloadFile }, Strings.mock),
|
|
77
|
-
r('pre', { ref: refPayloadViewer }, Strings.click_link_to_preview)))
|
|
78
|
-
r('div', { className: CSS.TransformsSection },
|
|
79
|
-
r('h2', null, Strings.transforms),
|
|
80
|
-
r(Transforms, { brokersByMethod }))))
|
|
73
|
+
r('pre', { ref: refPayloadViewer }, Strings.click_link_to_preview)))))
|
|
81
74
|
}
|
|
82
75
|
|
|
83
76
|
|
|
@@ -142,7 +135,7 @@ function SectionByMethod({ method, brokers }) {
|
|
|
142
135
|
r('th', null, method),
|
|
143
136
|
Object.entries(brokers)
|
|
144
137
|
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
145
|
-
.filter(([, broker]) => broker.mocks.length) // handles Markdown doc
|
|
138
|
+
.filter(([, broker]) => broker.mocks.length) // handles Markdown doc
|
|
146
139
|
.map(([urlMask, broker]) =>
|
|
147
140
|
r('tr', null,
|
|
148
141
|
r('td', null, r(PreviewLink, { method, urlMask, documentation: broker.documentation })),
|
|
@@ -168,8 +161,7 @@ function PreviewLink({ method, urlMask, documentation }) {
|
|
|
168
161
|
|
|
169
162
|
const spinner = setTimeout(() => refPayloadViewer.current.innerText = Strings.fetching, 180)
|
|
170
163
|
const res = await fetch(this.href, {
|
|
171
|
-
method: this.getAttribute('data-method')
|
|
172
|
-
headers: { [DF.isForDashboard]: '1' }
|
|
164
|
+
method: this.getAttribute('data-method')
|
|
173
165
|
})
|
|
174
166
|
document.querySelector(`.${CSS.PreviewLink}.${CSS.chosen}`)?.classList.remove(CSS.chosen)
|
|
175
167
|
this.classList.add(CSS.chosen)
|
|
@@ -246,47 +238,6 @@ function TimerIcon() {
|
|
|
246
238
|
}
|
|
247
239
|
|
|
248
240
|
|
|
249
|
-
function Transforms({ brokersByMethod }) {
|
|
250
|
-
const brokersWithTransforms = []
|
|
251
|
-
for (const brokers of Object.values(brokersByMethod))
|
|
252
|
-
for (const [urlMask, broker] of Object.entries(brokers))
|
|
253
|
-
if (broker.transforms.length)
|
|
254
|
-
brokersWithTransforms.push([urlMask, broker])
|
|
255
|
-
return (
|
|
256
|
-
r('table', null, brokersWithTransforms.map(([urlMask, broker]) =>
|
|
257
|
-
r('tr', null,
|
|
258
|
-
r('td', null, r(PreviewLink, { method: broker.method, urlMask })),
|
|
259
|
-
r('td', null, r(TransformSelector, {
|
|
260
|
-
items: ['', ...broker.transforms],
|
|
261
|
-
selected: broker.currentTransform
|
|
262
|
-
})))
|
|
263
|
-
)))
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function TransformSelector({ items, selected }) {
|
|
267
|
-
const className = defaultIsSelected => cssClass(
|
|
268
|
-
CSS.TransformSelector,
|
|
269
|
-
!defaultIsSelected && CSS.bold)
|
|
270
|
-
return (
|
|
271
|
-
r('select', {
|
|
272
|
-
className: className(selected === items[0]),
|
|
273
|
-
autocomplete: 'off',
|
|
274
|
-
onChange() {
|
|
275
|
-
fetch(API.transform, {
|
|
276
|
-
method: 'PATCH',
|
|
277
|
-
body: JSON.stringify(this.value)
|
|
278
|
-
}).then(() => {
|
|
279
|
-
this.closest('tr').querySelector('a').click()
|
|
280
|
-
this.className = className(this.value === this.options[0].value)
|
|
281
|
-
})
|
|
282
|
-
}
|
|
283
|
-
}, items.map(item =>
|
|
284
|
-
r('option', {
|
|
285
|
-
value: item,
|
|
286
|
-
selected: item === selected
|
|
287
|
-
}, item || Strings.none))))
|
|
288
|
-
}
|
|
289
|
-
|
|
290
241
|
|
|
291
242
|
/* === Utils === */
|
|
292
243
|
function cssClass(...args) {
|
package/src/MockBroker.js
CHANGED
|
@@ -5,9 +5,9 @@ import { Route } from './Route.js'
|
|
|
5
5
|
import { Config } from './Config.js'
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
// MockBroker is a state for a particular route. It knows the available
|
|
9
|
-
// that can be served for the route, the currently selected
|
|
10
|
-
// knows if the route has
|
|
8
|
+
// MockBroker is a state for a particular route. It knows the available
|
|
9
|
+
// mock files that can be served for the route, the currently selected
|
|
10
|
+
// file, and its delay. Also, knows if the route has documentation (md).
|
|
11
11
|
export class MockBroker {
|
|
12
12
|
#route
|
|
13
13
|
|
|
@@ -17,23 +17,18 @@ export class MockBroker {
|
|
|
17
17
|
|
|
18
18
|
this.documentation = '' // .md
|
|
19
19
|
|
|
20
|
-
this.mocks = [] // *.json,txt
|
|
20
|
+
this.mocks = [] // *.json,txt,js
|
|
21
21
|
this.currentMock = {
|
|
22
22
|
file: '',
|
|
23
23
|
delay: 0
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
this.transforms = [] // *.mjs
|
|
27
|
-
this.currentTransform = ''
|
|
28
|
-
|
|
29
26
|
this.register(file)
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
register(file) {
|
|
33
30
|
if (file.endsWith('.md'))
|
|
34
31
|
this.documentation = file
|
|
35
|
-
else if (file.endsWith('.mjs'))
|
|
36
|
-
this.transforms.push(file)
|
|
37
32
|
else {
|
|
38
33
|
if (!this.mocks.length)
|
|
39
34
|
this.currentMock.file = file // The first mock file option for a particular route becomes the default
|
|
@@ -55,26 +50,17 @@ export class MockBroker {
|
|
|
55
50
|
this.currentMock.delay = Number(delayed) * Config.delay
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
updateTransform(filename) {
|
|
59
|
-
this.currentTransform = filename
|
|
60
|
-
}
|
|
61
|
-
|
|
62
53
|
setByMatchingComment(comment) {
|
|
63
54
|
for (const file of this.mocks)
|
|
64
55
|
if (Route.hasInParentheses(file, comment)) {
|
|
65
56
|
this.updateFile(file)
|
|
66
57
|
break
|
|
67
58
|
}
|
|
68
|
-
for (const file of this.transforms)
|
|
69
|
-
if (Route.hasInParentheses(file, comment)) {
|
|
70
|
-
this.updateTransform(file)
|
|
71
|
-
break
|
|
72
|
-
}
|
|
73
59
|
}
|
|
74
60
|
|
|
75
61
|
extractComments() {
|
|
76
62
|
let comments = []
|
|
77
|
-
for (const file of
|
|
63
|
+
for (const file of this.mocks)
|
|
78
64
|
comments = comments.concat(Route.extractComments(file))
|
|
79
65
|
return comments
|
|
80
66
|
}
|
|
@@ -90,7 +76,6 @@ export class MockBroker {
|
|
|
90
76
|
}
|
|
91
77
|
|
|
92
78
|
#write500() {
|
|
93
|
-
// TODO handle route with transforms but without mocks
|
|
94
79
|
const { urlMask, method } = Route.parseFilename(this.mocks[0])
|
|
95
80
|
let mask = urlMask
|
|
96
81
|
const t = join(Config.mocksDir, urlMask)
|
package/src/MockDispatcher.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function dispatchMock(req, response) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
const { file, status, delay
|
|
31
|
+
const { file, status, delay } = broker
|
|
32
32
|
console.log('\n', req.url, '→\n ', file)
|
|
33
33
|
|
|
34
34
|
response.statusCode = status
|
|
@@ -36,13 +36,17 @@ export async function dispatchMock(req, response) {
|
|
|
36
36
|
if (cookie.getCurrent())
|
|
37
37
|
response.setHeader('set-cookie', cookie.getCurrent())
|
|
38
38
|
|
|
39
|
-
let
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
39
|
+
let mockText
|
|
40
|
+
if (file.endsWith('.js')) {
|
|
41
|
+
response.setHeader('content-type', mimeFor('.json'))
|
|
42
|
+
const jsExport = await importDefault(file)
|
|
43
|
+
mockText = typeof jsExport === 'function'
|
|
44
|
+
? jsExport(req, response)
|
|
45
|
+
: JSON.stringify(jsExport)
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
else
|
|
48
|
+
mockText = readMock(file)
|
|
49
|
+
setTimeout(() => response.end(mockText), delay)
|
|
46
50
|
}
|
|
47
51
|
catch (error) {
|
|
48
52
|
console.error(error)
|
|
@@ -55,21 +59,11 @@ export async function dispatchMock(req, response) {
|
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
const nonSafeMethods = ['PATCH', 'POST', 'PUT', 'DELETE', 'CONNECT']
|
|
59
|
-
|
|
60
|
-
async function requestBodyForTransform(req, mockAsText) {
|
|
61
|
-
if (nonSafeMethods.includes(req.method))
|
|
62
|
-
return req.headers[DF.isForDashboard] // TODO unit TESTME
|
|
63
|
-
? JSON.parse(mockAsText)
|
|
64
|
-
: await parseJSON(req)
|
|
65
|
-
return ''
|
|
66
|
-
}
|
|
67
|
-
|
|
68
62
|
function readMock(file) {
|
|
69
63
|
return readFileSync(join(Config.mocksDir, file), 'utf8')
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
async function
|
|
66
|
+
async function importDefault(file) {
|
|
73
67
|
// The date param is just for cache busting
|
|
74
68
|
return (await import(join(Config.mocksDir, file) + '?' + Date.now())).default
|
|
75
69
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// This is an example "transform". It takes the mock for the same route as
|
|
2
|
-
// input, so you can modify it. In this case, it uses the `database` field.
|
|
3
|
-
|
|
4
|
-
export default function concatNewlyUploadedVideos(mockAsText, _, config) {
|
|
5
|
-
const mockList = JSON.parse(mockAsText)
|
|
6
|
-
mockList.videos = mockList.videos.concat(config.database.videos || [])
|
|
7
|
-
return JSON.stringify(mockList, null, 2)
|
|
8
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// An example "transform" for saving a POST request payload into the `config.database`
|
|
2
|
-
|
|
3
|
-
export default function concatNewlyUploadedVideos(mockAsText, requestBody, config) {
|
|
4
|
-
config.database.videos ??= []
|
|
5
|
-
config.database.videos.push({
|
|
6
|
-
createdAt: Date.now(),
|
|
7
|
-
...requestBody
|
|
8
|
-
})
|
|
9
|
-
return JSON.stringify({})
|
|
10
|
-
}
|
|
File without changes
|
|
File without changes
|