From 79656046377f501da796d1be9752522a2203d69b Mon Sep 17 00:00:00 2001 From: vben Date: Wed, 28 Oct 2020 14:52:14 +0800 Subject: [PATCH] fix: Fix local development post request proxy to https --- package.json | 2 +- src/createMockServer.ts | 42 +++++++----- src/koaBodyparse.ts | 137 ++++++++++++++++++++++++++++++++++++++++ src/mockServerPlugin.ts | 6 +- 4 files changed, 166 insertions(+), 21 deletions(-) create mode 100644 src/koaBodyparse.ts diff --git a/package.json b/package.json index 56dc22d..6eb6bfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vite-plugin-mock", - "version": "1.0.4", + "version": "1.0.6", "description": "A mock plugin for vite", "main": "dist/index.js", "files": [ diff --git a/src/createMockServer.ts b/src/createMockServer.ts index dedfeea..0f5d2b8 100644 --- a/src/createMockServer.ts +++ b/src/createMockServer.ts @@ -10,6 +10,8 @@ import { isArray, isFunction, sleep, isRegExp } from './utils'; import { loadConfigFromBundledFile } from './loadConfigFromBundledFile'; import { rollup } from 'rollup'; import esbuildPlugin from 'rollup-plugin-esbuild'; +// @ts-ignore +import bodyParser from './koaBodyparse'; const pathResolve = require('@rollup/plugin-node-resolve'); let mockData: MockMethod[] = []; @@ -37,24 +39,30 @@ export function getMockData() { } // request match -export async function requestMiddle(ctx: ParameterizedContext, next: any) { - const path = ctx.path; - const req = mockData.find((item) => item.url === path); - if (req) { - const { response, timeout } = req; - if (timeout) { - await sleep(timeout); - } - const { body, query } = ctx.request; - const mockRes = isFunction(response) ? response({ body, query }) : response; - console.log(`${chalk.green('[vite:mock-server]:request invoke: ' + ` ${chalk.cyan(path)} `)}`); - ctx.type = 'json'; - ctx.status = 200; +export function requestMiddle(app: any) { + return async (ctx: ParameterizedContext, next: any) => { + const path = ctx.path; + const req = mockData.find((item) => item.url === path); + if (req) { + const { response, timeout } = req; + if (timeout) { + await sleep(timeout); + } + const { query } = ctx.request; + const bodyParserFn = bodyParser(app); + const body = await bodyParserFn(ctx); + const mockRes = isFunction(response) ? response({ body, query }) : response; + console.log( + `${chalk.green('[vite:mock-server]:request invoke: ' + ` ${chalk.cyan(path)} `)}` + ); + ctx.type = 'json'; + ctx.status = 200; - ctx.body = Mock.mock(mockRes); - return; - } - await next(); + ctx.body = Mock.mock(mockRes); + return; + } + await next(); + }; } // create watch mock diff --git a/src/koaBodyparse.ts b/src/koaBodyparse.ts new file mode 100644 index 0000000..f1b9ce4 --- /dev/null +++ b/src/koaBodyparse.ts @@ -0,0 +1,137 @@ +/** ! + * koa-body-parser - index.js + * Copyright(c) 2014 + * MIT Licensed + * + * Authors: + * dead_horse (http://deadhorse.me) + * fengmk2 (http://fengmk2.com) + */ + +'use strict'; + +/** + * Module dependencies. + */ +// @ts-ignore +import parse from 'co-body'; +// @ts-ignore +import copy from 'copy-to'; + +/** + * @param [Object] opts + * - {String} jsonLimit default '1mb' + * - {String} formLimit default '56kb' + * - {string} encoding default 'utf-8' + * - {Object} extendTypes + */ + +module.exports = function (opts: any) { + opts = opts || {}; + const { detectJSON } = opts; + const { onerror } = opts; + + const enableTypes = opts.enableTypes || ['json', 'form']; + const enableForm = checkEnable(enableTypes, 'form'); + const enableJson = checkEnable(enableTypes, 'json'); + const enableText = checkEnable(enableTypes, 'text'); + const enableXml = checkEnable(enableTypes, 'xml'); + + opts.detectJSON = undefined; + opts.onerror = undefined; // eslint-disable-line unicorn/prefer-add-event-listener + + // force co-body return raw body + opts.returnRawBody = true; + + // default json types + const jsonTypes = [ + 'application/json', + 'application/json-patch+json', + 'application/vnd.api+json', + 'application/csp-report', + ]; + + // default form types + const formTypes = ['application/x-www-form-urlencoded']; + + // default text types + const textTypes = ['text/plain']; + + // default xml types + const xmlTypes = ['text/xml', 'application/xml']; + + const jsonOpts = formatOptions(opts, 'json'); + const formOpts = formatOptions(opts, 'form'); + const textOpts = formatOptions(opts, 'text'); + const xmlOpts = formatOptions(opts, 'xml'); + + const extendTypes = opts.extendTypes || {}; + + extendType(jsonTypes, extendTypes.json); + extendType(formTypes, extendTypes.form); + extendType(textTypes, extendTypes.text); + extendType(xmlTypes, extendTypes.xml); + + // eslint-disable-next-line func-names + return async function bodyParser(ctx: any) { + if (ctx.request.body !== undefined || ctx.disableBodyParser) return; // eslint-disable-line no-return-await + try { + const res = await parseBody(ctx); + return 'parsed' in res ? res.parsed : {}; + + // ctx.request.body = 'parsed' in res ? res.parsed : {}; + // if (ctx.request.rawBody === undefined) ctx.request.rawBody = res.raw; + } catch (err) { + if (onerror) { + onerror(err, ctx); + } else { + throw err; + } + } + + // await next(); + }; + + async function parseBody(ctx: any) { + if (enableJson && ((detectJSON && detectJSON(ctx)) || ctx.request.is(jsonTypes))) { + return await parse.json(ctx, jsonOpts); // eslint-disable-line no-return-await + } + + if (enableForm && ctx.request.is(formTypes)) { + return await parse.form(ctx, formOpts); // eslint-disable-line no-return-await + } + + if (enableText && ctx.request.is(textTypes)) { + return (await parse.text(ctx, textOpts)) || ''; + } + + if (enableXml && ctx.request.is(xmlTypes)) { + return (await parse.text(ctx, xmlOpts)) || ''; + } + + return {}; + } +}; + +function formatOptions(opts: any, type: any) { + const res: any = {}; + copy(opts).to(res); + res.limit = opts[type + 'Limit']; + return res; +} + +function extendType(original: any, extend: any) { + if (extend) { + if (!Array.isArray(extend)) { + extend = [extend]; + } + + extend.forEach(function (extend: any) { + original.push(extend); + }); + } +} + +function checkEnable(types: any, type: any) { + return types.includes(type); +} diff --git a/src/mockServerPlugin.ts b/src/mockServerPlugin.ts index d032d09..91c004b 100644 --- a/src/mockServerPlugin.ts +++ b/src/mockServerPlugin.ts @@ -2,12 +2,12 @@ import { ServerPlugin } from 'vite'; import { createMockServer, requestMiddle } from './createMockServer'; import { CreateMock } from './types'; -import bodyParser from 'koa-bodyparser'; +// import bodyParser from 'koa-bodyparser'; export const createMockServerPlugin = (opt: CreateMock): ServerPlugin => { return ({ app }) => { - app.use(bodyParser()); + // app.use(bodyParser()); createMockServer(opt); - app.use(requestMiddle); + app.use(requestMiddle(app)); }; };