Skip to content

Commit 24775f9

Browse files
authored
feat: add rawResponse option to MockMethod (#17)
With rawResponse we can parse arbitrary requests and return arbitrary responses, instead of being limited to application/json. Fixes #16.
1 parent 276005a commit 24775f9

File tree

5 files changed

+57
-14
lines changed

5 files changed

+57
-14
lines changed

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,22 @@ export default [
217217
},
218218
},
219219
},
220+
{
221+
url: '/api/text',
222+
method: 'post',
223+
rawResponse: async (req, res) => {
224+
let reqbody = '';
225+
await new Promise((resolve) => {
226+
req.on('data', (chunk) => {
227+
reqbody += chunk;
228+
});
229+
req.on('end', () => resolve(undefined));
230+
});
231+
res.setHeader('Content-Type', 'text/plain');
232+
res.statusCode = 200;
233+
res.end(`hello, ${reqbody}`);
234+
},
235+
},
220236
] as MockMethod[];
221237
```
222238

@@ -232,8 +248,10 @@ export default [
232248
timeout?: number;
233249
// default: 200
234250
statusCode?:number;
235-
// response data
236-
response: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
251+
// response data (JSON)
252+
response?: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
253+
// response (non-JSON)
254+
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
237255
}
238256

239257
```

README.zh_CN.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,22 @@ export default [
200200
},
201201
},
202202
},
203+
{
204+
url: '/api/text',
205+
method: 'post',
206+
rawResponse: async (req, res) => {
207+
let reqbody = '';
208+
await new Promise((resolve) => {
209+
req.on('data', (chunk) => {
210+
reqbody += chunk;
211+
});
212+
req.on('end', () => resolve(undefined));
213+
});
214+
res.setHeader('Content-Type', 'text/plain');
215+
res.statusCode = 200;
216+
res.end(`hello, ${reqbody}`);
217+
},
218+
},
203219
] as MockMethod[];
204220
```
205221

@@ -215,8 +231,10 @@ export default [
215231
timeout?: number;
216232
// 状态吗
217233
statusCode?:number;
218-
// 响应数据
219-
response: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
234+
// 响应数据(JSON)
235+
response?: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
236+
// 响应(非JSON)
237+
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
220238
}
221239

222240
```

src/createMockServer.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export async function requestMiddleware(opt: ViteMockOptions) {
5959
});
6060

6161
if (matchRequest) {
62-
const { response, timeout, statusCode, url } = matchRequest;
62+
const { response, rawResponse, timeout, statusCode, url } = matchRequest;
6363

6464
if (timeout) {
6565
await sleep(timeout);
@@ -74,13 +74,17 @@ export async function requestMiddleware(opt: ViteMockOptions) {
7474
}
7575
}
7676

77-
const body = await parseJson(req);
78-
const mockResponse = isFunction(response)
79-
? response({ body, query, headers: req.headers })
80-
: response;
81-
res.setHeader('Content-Type', 'application/json');
82-
res.statusCode = statusCode || 200;
83-
res.end(JSON.stringify(Mock.mock(mockResponse)));
77+
if (isFunction(rawResponse)) {
78+
await rawResponse(req, res);
79+
} else {
80+
const body = await parseJson(req);
81+
const mockResponse = isFunction(response)
82+
? response({ body, query, headers: req.headers })
83+
: response;
84+
res.setHeader('Content-Type', 'application/json');
85+
res.statusCode = statusCode || 200;
86+
res.end(JSON.stringify(Mock.mock(mockResponse)));
87+
}
8488

8589
logger && loggerOutput('request invoke', req.url!);
8690
return;

src/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { IncomingMessage, ServerResponse } from 'node:http';
2+
13
export interface ViteMockOptions {
24
mockPath?: string;
35
configPath?: string;
@@ -20,7 +22,8 @@ export declare interface MockMethod {
2022
method?: MethodType;
2123
timeout?: number;
2224
statusCode?: number;
23-
response: ((opt: { body: Recordable; query: Recordable; headers: Recordable }) => any) | any;
25+
response?: ((opt: { body: Recordable; query: Recordable; headers: Recordable }) => any) | any;
26+
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
2427
}
2528

2629
export interface NodeModuleWithCompile extends NodeModule {

src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function is(val: unknown, type: string) {
66

77
// eslint-disable-next-line
88
export function isFunction<T = Function>(val: unknown): val is T {
9-
return is(val, 'Function');
9+
return is(val, 'Function') || is(val, 'AsyncFunction');
1010
}
1111

1212
export function isArray(val: any): val is Array<any> {

0 commit comments

Comments
 (0)