From d138f4bfa516e6be4d26dd52141465b3a9fe8430 Mon Sep 17 00:00:00 2001 From: KITAHARA SETSUNA Date: Sun, 25 Aug 2024 19:28:55 +0900 Subject: [PATCH 1/3] feat: allow manipulate req and resp in response handler --- packages/vite-plugin-mock/src/createMockServer.ts | 2 +- packages/vite-plugin-mock/src/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite-plugin-mock/src/createMockServer.ts b/packages/vite-plugin-mock/src/createMockServer.ts index c092734..cff4b94 100644 --- a/packages/vite-plugin-mock/src/createMockServer.ts +++ b/packages/vite-plugin-mock/src/createMockServer.ts @@ -94,7 +94,7 @@ export async function requestMiddleware(opt: ViteMockOptions) { } res.statusCode = statusCode || 200 const mockResponse = isFunction(response) - ? response.bind(self)({ url: req.url as any, body, query, headers: req.headers }) + ? response.bind(self)({ url: req.url as any, body, query, headers: req.headers, req, res }) : response res.end(JSON.stringify(Mock.mock(mockResponse))) } diff --git a/packages/vite-plugin-mock/src/types.ts b/packages/vite-plugin-mock/src/types.ts index 7378772..73c0046 100644 --- a/packages/vite-plugin-mock/src/types.ts +++ b/packages/vite-plugin-mock/src/types.ts @@ -28,7 +28,7 @@ export declare interface MockMethod { response?: | (( this: RespThisType, - opt: { url: Recordable; body: Recordable; query: Recordable; headers: Recordable }, + opt: { url: Recordable; body: Recordable; query: Recordable; headers: Recordable, req: IncomingMessage, res: ServerResponse }, ) => any) | any rawResponse?: (this: RespThisType, req: IncomingMessage, res: ServerResponse) => void From 9300d759192e1bf249b9ae3846f690721803e3bc Mon Sep 17 00:00:00 2001 From: KITAHARA SETSUNA Date: Sun, 25 Aug 2024 20:09:56 +0900 Subject: [PATCH 2/3] feat: add support for multiple response content types --- README.md | 30 ++++++++++++ .../vite-plugin-mock/src/createMockServer.ts | 48 +++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index be2980a..db4e995 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,36 @@ export default [ }, }, }, + // Custom status code and response + { + url: '/api/query', + method: 'get', + response: ({ query, res }) => { + // res.setHeader('X-Hello', 'World') + if (query.name === 'vite') { + res.statusCode = 200 + return { message: 'OK' } + } else { + res.statusCode = 404 + return { message: 'Not Found' } + } + }, + }, + { + url: '/api/plaintext', + method: 'get', + response: () => { + return '200 OK' + }, + }, + // 204 No Content + { + url: '/api/204', + method: 'get', + response: () => { + return + }, + }, { url: '/api/text', method: 'post', diff --git a/packages/vite-plugin-mock/src/createMockServer.ts b/packages/vite-plugin-mock/src/createMockServer.ts index cff4b94..04e44ce 100644 --- a/packages/vite-plugin-mock/src/createMockServer.ts +++ b/packages/vite-plugin-mock/src/createMockServer.ts @@ -87,16 +87,41 @@ export async function requestMiddleware(opt: ViteMockOptions) { await rawResponse.bind(self)(req, res) } else { const body = await parseJson(req) - res.setHeader('Content-Type', 'application/json') if (opt) { res.setHeader('Access-Control-Allow-Credentials', true) res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*') } res.statusCode = statusCode || 200 - const mockResponse = isFunction(response) - ? response.bind(self)({ url: req.url as any, body, query, headers: req.headers, req, res }) - : response - res.end(JSON.stringify(Mock.mock(mockResponse))) + let mockResponse = Mock.mock( + isFunction(response) + ? response.bind(self)({ + url: req.url as any, + body, + query, + headers: req.headers, + req, + res, + }) + : response, + ) + if (typeof mockResponse === 'undefined') { + res.statusCode = 204 + res.end() + return + } + if (!res.statusCode) { + res.statusCode = statusCode || 200 + } + if (!res.getHeader('Content-Type')) { + res.setHeader('Content-Type', guessContentType(mockResponse)) + } + if ( + res.getHeader('Content-Type') === 'application/json' && + typeof mockResponse !== 'string' + ) { + mockResponse = JSON.stringify(mockResponse) + } + res.end(mockResponse) } logger && loggerOutput('request invoke', req.url!) @@ -107,6 +132,19 @@ export async function requestMiddleware(opt: ViteMockOptions) { return middleware } +function guessContentType(body: any) { + if (body instanceof Buffer || body instanceof Uint8Array) { + return 'application/octet-stream' + } + switch (typeof body) { + case 'string': + return 'text/plain' + case 'undefined': + default: + return 'application/json' + } +} + // create watch mock function createWatch(opt: ViteMockOptions, config: ResolvedConfig) { const { configPath, logger, watchFiles } = opt From 90d1d86ce0f78b1e15b100feeb2f56d521fa0b8a Mon Sep 17 00:00:00 2001 From: KITAHARA SETSUNA Date: Sat, 16 Nov 2024 17:17:47 +0900 Subject: [PATCH 3/3] feat: support async response handler --- README.md | 12 ++++++ .../vite-plugin-mock/src/createMockServer.ts | 41 +++++++++---------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index db4e995..d2a5456 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,18 @@ export default [ } }, }, + { + url: '/api/get', + method: 'get', + response: async ({ query }) => { + return { + code: 0, + data: { + name: 'vben', + }, + } + }, + }, { url: '/api/post', method: 'post', diff --git a/packages/vite-plugin-mock/src/createMockServer.ts b/packages/vite-plugin-mock/src/createMockServer.ts index 04e44ce..d9c1fce 100644 --- a/packages/vite-plugin-mock/src/createMockServer.ts +++ b/packages/vite-plugin-mock/src/createMockServer.ts @@ -62,7 +62,7 @@ export async function requestMiddleware(opt: ViteMockOptions) { if (matchRequest) { const isGet = req.method && req.method.toUpperCase() === 'GET' - const { response, rawResponse, timeout, statusCode, url } = matchRequest + const { response: handler, rawResponse, timeout, statusCode, url } = matchRequest if (timeout) { await sleep(timeout) @@ -92,19 +92,21 @@ export async function requestMiddleware(opt: ViteMockOptions) { res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*') } res.statusCode = statusCode || 200 - let mockResponse = Mock.mock( - isFunction(response) - ? response.bind(self)({ - url: req.url as any, - body, - query, - headers: req.headers, - req, - res, - }) - : response, - ) - if (typeof mockResponse === 'undefined') { + let response = isFunction(handler) + ? handler.bind(self)({ + url: req.url as any, + body, + query, + headers: req.headers, + req, + res, + }) + : handler + if (response.then) { + response = await response + } + response = Mock.mock(response) + if (typeof response === 'undefined') { res.statusCode = 204 res.end() return @@ -113,15 +115,12 @@ export async function requestMiddleware(opt: ViteMockOptions) { res.statusCode = statusCode || 200 } if (!res.getHeader('Content-Type')) { - res.setHeader('Content-Type', guessContentType(mockResponse)) + res.setHeader('Content-Type', guessContentType(response)) } - if ( - res.getHeader('Content-Type') === 'application/json' && - typeof mockResponse !== 'string' - ) { - mockResponse = JSON.stringify(mockResponse) + if (res.getHeader('Content-Type') === 'application/json' && typeof response !== 'string') { + response = JSON.stringify(response) } - res.end(mockResponse) + res.end(response) } logger && loggerOutput('request invoke', req.url!)