From e5ea0ef5c6eddc3d20b835742ce4a7a327ec9645 Mon Sep 17 00:00:00 2001 From: StEve Young <2747745470@qq.com> Date: Wed, 25 Sep 2019 08:13:59 -0500 Subject: [PATCH] feat: beforeFn returns Promise<{header:{a:'b'}}> for axios's headers (#42) --- docs/config/common.md | 14 +++++++++++++- examples/apis-web/fake-get.js | 15 +++++++++++++++ examples/apis-web/index.d.ts | 3 ++- package.json | 4 ++-- src/adapters/wx.js | 2 ++ src/index.js | 9 ++++++--- test/__tests__/axios.test.js | 15 +++++++++++++++ 7 files changed, 55 insertions(+), 7 deletions(-) diff --git a/docs/config/common.md b/docs/config/common.md index f8fc725..80108c6 100644 --- a/docs/config/common.md +++ b/docs/config/common.md @@ -99,7 +99,19 @@ export default { 详情参阅:[中间件进阶](../guide/middleware.md) ## beforeFn 发起请求前钩子函数 -在请求发起前执行的函数(例如小程序可以通过返回 `header` 传递 `cookie`),因为是通过 `beforeFn().then(...)` 调用,所以注意要返回 Promise。 +在请求发起前执行的函数,因为是通过 `beforeFn().then(...)` 调用,所以注意要返回 Promise。 + +例如小程序端可以通过返回 `header` 传递 `cookie`,web 端使用 axios 时也可以用来修改 `header`。 + +> 虽然 axios 配置是 `headers` 但为了和小程序端保持一致就都用 `header` + +```js +export default { + beforeFn: () => Promise.resolve({ + header: { cookie: '1' }, + }), +} +``` ## afterFn 收到响应后的钩子函数 在收到响应后执行的函数,可以不用返回 `Promise` diff --git a/examples/apis-web/fake-get.js b/examples/apis-web/fake-get.js index eebb44e..b2f9f18 100644 --- a/examples/apis-web/fake-get.js +++ b/examples/apis-web/fake-get.js @@ -139,5 +139,20 @@ export default { reqType: ('axios'), mock: ({ mockCode }) => ({ code: mockCode, data: {} }), }, + /** + * beforeFnCookie + */ + { + name: 'beforeFnCookie', + path: 'beforeFn-cookie', + /** + * @returns {Promise} + */ + beforeFn: () => Promise.resolve({ + header: { cookie: '123' }, + }), + /** @type { import('../../src/').ReqType } */ + reqType: ('axios'), + }, ], } diff --git a/examples/apis-web/index.d.ts b/examples/apis-web/index.d.ts index 43a2147..52f0a09 100644 --- a/examples/apis-web/index.d.ts +++ b/examples/apis-web/index.d.ts @@ -21,6 +21,7 @@ export const fakeGetApi: { 'afterData': ReqFnWithAnyParams 'mockFnData': ReqFnWithAnyParams 'noAfterData': ReqFnWithAnyParams + 'beforeFnCookie': ReqFnWithAnyParams 'mockObjectData': ReqFnWithAnyParams 'empty-array-params': ReqFnWithAnyParams 'ap': ReqFn & { @@ -53,4 +54,4 @@ export const fakePostApi: { options?: RuntimeOptions ): Promise } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 60c78a4..db5cfdb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tua-api", - "version": "1.3.5", + "version": "1.4.0", "description": "🏗 A common tool helps converting configs to api functions", "main": "dist/TuaApi.cjs.js", "module": "dist/TuaApi.esm.js", @@ -67,7 +67,7 @@ "koa-compose": "^4.1.0" }, "devDependencies": { - "@babel/core": "^7.6.0", + "@babel/core": "^7.6.2", "@babel/plugin-external-helpers": "^7.2.0", "@babel/plugin-proposal-decorators": "^7.6.0", "@babel/plugin-proposal-object-rest-spread": "^7.5.5", diff --git a/src/adapters/wx.js b/src/adapters/wx.js index a752f2d..07fbf10 100644 --- a/src/adapters/wx.js +++ b/src/adapters/wx.js @@ -43,6 +43,8 @@ export const getWxPromise = ({ complete: () => { // 同步隐藏 loading isShowLoading && hideLoadingFn() + /* istanbul ignore next */ + rest.complete && rest.complete() }, }) } diff --git a/src/index.js b/src/index.js index 49d70f0..c58698c 100644 --- a/src/index.js +++ b/src/index.js @@ -99,6 +99,7 @@ class TuaApi { * @param {string} options.fullUrl 完整接口地址 * @param {string} options.reqType 使用什么工具发(axios/jsonp/wx) * @param {object} options.reqParams 请求参数 + * @param {object} options.header 请求的 header * @param {string} options.callbackName 使用 jsonp 时的回调函数名 * @param {object} options.axiosOptions 透传 axios 配置参数 * @param {object} options.jsonpOptions 透传 fetch-jsonp 配置参数 @@ -107,6 +108,7 @@ class TuaApi { _reqFn ({ url, mock, + header, method, fullUrl, reqType, @@ -131,15 +133,16 @@ class TuaApi { method = method.toLowerCase() if (reqType === 'wx') { - return getWxPromise({ url, fullUrl, data, method, ...rest }) + return getWxPromise({ url, fullUrl, data, method, header, ...rest }) } if (reqType === 'axios') { const params = { + ...axiosOptions, url: method === 'get' ? fullUrl : url, data: method === 'get' ? {} : data, method, - ...axiosOptions, + headers: header, } return getAxiosPromise(params) @@ -282,7 +285,7 @@ class TuaApi { // 执行完 beforeFn 后执行的函数 const beforeFnCb = (rArgs = {}) => { - // 兼容小程序传递请求头(建议还是放在中间件中) + // 传递请求头 if (rArgs.header) { ctx.req.reqFnParams.header = rArgs.header } diff --git a/test/__tests__/axios.test.js b/test/__tests__/axios.test.js index de02142..321a75c 100644 --- a/test/__tests__/axios.test.js +++ b/test/__tests__/axios.test.js @@ -18,6 +18,7 @@ const reqOHUrl = 'http://example-test.com/fake-post/own-host' const reqTAUrl = 'http://example-base.com/fake-get/req-type-axios?asyncCp=asyncCp' const reqEAPUrl = 'http://example-base.com/fake-post/empty-array-params' const reqMFDUrl = 'http://example-base.com/fake-get/mock-function-data' +const reqBFCUrl = 'http://example-base.com/fake-get/beforeFn-cookie' describe('middleware', () => { test('change host before request', async () => { @@ -30,6 +31,20 @@ describe('middleware', () => { }) }) +describe('beforeFn cookie', () => { + beforeEach(() => { + // @ts-ignore + mock.resetHistory() + }) + + test('set cookie by beforeFn', async () => { + mock.onGet(reqBFCUrl).reply(200, {}) + await fakeGetApi.beforeFnCookie() + + expect(mock.history.get[0].headers.cookie).toBe('123') + }) +}) + describe('mock data', () => { test('mock function data', async () => { mock.onGet(reqMFDUrl).reply(200, {})