Skip to content

Commit

Permalink
feat: add rawResponse option to MockMethod (#17)
Browse files Browse the repository at this point in the history
With rawResponse we can parse arbitrary requests and return arbitrary
responses, instead of being limited to application/json.

Fixes #16.
  • Loading branch information
zmwangx committed Apr 6, 2021
1 parent 276005a commit 24775f9
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 14 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,22 @@ export default [
},
},
},
{
url: '/api/text',
method: 'post',
rawResponse: async (req, res) => {
let reqbody = '';
await new Promise((resolve) => {
req.on('data', (chunk) => {
reqbody += chunk;
});
req.on('end', () => resolve(undefined));
});
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 200;
res.end(`hello, ${reqbody}`);
},
},
] as MockMethod[];
```

Expand All @@ -232,8 +248,10 @@ export default [
timeout?: number;
// default: 200
statusCode?:number;
// response data
response: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
// response data (JSON)
response?: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
// response (non-JSON)
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
}

```
Expand Down
22 changes: 20 additions & 2 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,22 @@ export default [
},
},
},
{
url: '/api/text',
method: 'post',
rawResponse: async (req, res) => {
let reqbody = '';
await new Promise((resolve) => {
req.on('data', (chunk) => {
reqbody += chunk;
});
req.on('end', () => resolve(undefined));
});
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 200;
res.end(`hello, ${reqbody}`);
},
},
] as MockMethod[];
```

Expand All @@ -215,8 +231,10 @@ export default [
timeout?: number;
// 状态吗
statusCode?:number;
// 响应数据
response: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
// 响应数据(JSON)
response?: ((opt: { [key: string]: string; body: Record<string,any>; query: Record<string,any>, headers: Record<string, any>; }) => any) | any;
// 响应(非JSON)
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
}

```
Expand Down
20 changes: 12 additions & 8 deletions src/createMockServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export async function requestMiddleware(opt: ViteMockOptions) {
});

if (matchRequest) {
const { response, timeout, statusCode, url } = matchRequest;
const { response, rawResponse, timeout, statusCode, url } = matchRequest;

if (timeout) {
await sleep(timeout);
Expand All @@ -74,13 +74,17 @@ export async function requestMiddleware(opt: ViteMockOptions) {
}
}

const body = await parseJson(req);
const mockResponse = isFunction(response)
? response({ body, query, headers: req.headers })
: response;
res.setHeader('Content-Type', 'application/json');
res.statusCode = statusCode || 200;
res.end(JSON.stringify(Mock.mock(mockResponse)));
if (isFunction(rawResponse)) {
await rawResponse(req, res);
} else {
const body = await parseJson(req);
const mockResponse = isFunction(response)
? response({ body, query, headers: req.headers })
: response;
res.setHeader('Content-Type', 'application/json');
res.statusCode = statusCode || 200;
res.end(JSON.stringify(Mock.mock(mockResponse)));
}

logger && loggerOutput('request invoke', req.url!);
return;
Expand Down
5 changes: 4 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { IncomingMessage, ServerResponse } from 'node:http';

export interface ViteMockOptions {
mockPath?: string;
configPath?: string;
Expand All @@ -20,7 +22,8 @@ export declare interface MockMethod {
method?: MethodType;
timeout?: number;
statusCode?: number;
response: ((opt: { body: Recordable; query: Recordable; headers: Recordable }) => any) | any;
response?: ((opt: { body: Recordable; query: Recordable; headers: Recordable }) => any) | any;
rawResponse?: (req: IncomingMessage, res: ServerResponse) => void;
}

export interface NodeModuleWithCompile extends NodeModule {
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function is(val: unknown, type: string) {

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

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

0 comments on commit 24775f9

Please sign in to comment.