diff --git a/docs/config/common.md b/docs/config/common.md
index a5ae909..f5fdfd9 100644
--- a/docs/config/common.md
+++ b/docs/config/common.md
@@ -91,6 +91,16 @@ export default {
}
```
+::: tip
+ 后,支持函数模式
+
+```js
+export default {
+ commonParams: (params) => ({ t: Date.now(), foo: params.foo }),
+}
+```
+:::
+
## axiosOptions 透传参数配置
由于 tua-api 是依赖于 `axios` 或是 `fetch-jsop` 来发送请求的。所以势必要提供参数透传的功能。
diff --git a/docs/config/self.md b/docs/config/self.md
index a2ee314..a155c80 100644
--- a/docs/config/self.md
+++ b/docs/config/self.md
@@ -63,6 +63,24 @@ export default {
}
```
+::: tip
+ 后,支持函数模式
+
+```js
+export default {
+ pathList: [
+ {
+ ...
+ params: (params) => ({
+ t: Date.now(),
+ foo: params.foo,
+ }),
+ },
+ ],
+}
+```
+:::
+
## commonParams 覆盖公共参数
有时某个接口正好不需要上一级中 `commonParams` 的参数。那么可以传递 `null` 覆盖上一级中的 `commonParams`。
diff --git a/examples/apis-web/fake-fn.js b/examples/apis-web/fake-fn.js
new file mode 100644
index 0000000..9f41b6e
--- /dev/null
+++ b/examples/apis-web/fake-fn.js
@@ -0,0 +1,32 @@
+export default {
+ // 该参数表示请求的公用服务器地址。
+ baseUrl: 'http://example-base.com/',
+
+ // 请求的中间路径,建议与文件同名,以便后期维护。
+ prefix: 'fake-fn',
+
+ // 所有请求都需要携带的参数
+ commonParams: (args) => ({
+ ...args,
+ c: Math.random(),
+ }),
+
+ reqType: 'axios',
+
+ // 接口地址数组
+ pathList: [
+ /**
+ * fn-params
+ */
+ {
+ name: 'fp',
+ path: 'fn-params',
+ method: 'post',
+ params: ({ param1, param2 }) => ({
+ t: Math.random(),
+ p1: param1,
+ p2: param2,
+ }),
+ },
+ ],
+}
diff --git a/examples/apis-web/fake-post.js b/examples/apis-web/fake-post.js
index 54668b9..bded75d 100644
--- a/examples/apis-web/fake-post.js
+++ b/examples/apis-web/fake-post.js
@@ -19,10 +19,7 @@ export default {
/**
* empty-array-params
*/
- {
- name: 'eap',
- path: 'empty-array-params',
- },
+ { name: 'eap', path: 'empty-array-params' },
/**
* array-params
*/
@@ -84,10 +81,7 @@ export default {
/**
* application/json
*/
- {
- name: 'pj',
- path: 'post-json',
- },
+ { name: 'pj', path: 'post-json' },
/**
* raw-data
*/
diff --git a/examples/apis-web/index.d.ts b/examples/apis-web/index.d.ts
index 05b830f..321ea7c 100644
--- a/examples/apis-web/index.d.ts
+++ b/examples/apis-web/index.d.ts
@@ -58,3 +58,12 @@ export const fakePostApi: {
): Promise
}
}
+
+export const fakeFnApi: {
+ 'fp': ReqFn & {
+ (
+ params: { t?: any },
+ options?: RuntimeOptions
+ ): Promise
+ }
+}
diff --git a/examples/apis-web/index.js b/examples/apis-web/index.js
index 97b55dd..b1d0714 100644
--- a/examples/apis-web/index.js
+++ b/examples/apis-web/index.js
@@ -17,5 +17,6 @@ tuaApi.use(async (ctx, next) => {
// console.log('after: ', ctx)
})
+export const fakeFnApi = tuaApi.getApi(require('./fake-fn').default)
export const fakeGetApi = tuaApi.getApi(require('./fake-get').default)
export const fakePostApi = tuaApi.getApi(require('./fake-post').default)
diff --git a/package.json b/package.json
index 11baace..636583a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tua-api",
- "version": "1.6.1",
+ "version": "1.7.0",
"description": "🏗 A common tool helps converting configs to api functions",
"main": "dist/TuaApi.cjs.js",
"module": "dist/TuaApi.esm.js",
diff --git a/src/index.d.ts b/src/index.d.ts
index 587359b..3612120 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -12,7 +12,7 @@ export type Mock = AnyFunction | any
export type ApiConfig = WxApiConfig | WebApiConfig
-export type ParamsConfig = string[] | ParamsObject
+export type ParamsConfig = string[] | ParamsObject | ((args?: object) => object)
export type Middleware = (ctx: T, next: () => Promise) => Promise
@@ -96,7 +96,7 @@ export interface BaseApiConfig {
beforeFn?: () => Promise
middleware?: Middleware[]
customFetch?: AnyPromiseFunction
- commonParams?: object
+ commonParams?: object | ((args?: object) => object),
axiosOptions?: AxiosOptions
jsonpOptions?: JsonpOptions
useGlobalMiddleware?: boolean
diff --git a/src/index.js b/src/index.js
index 396c0ed..c34d86e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -6,6 +6,7 @@ import {
map,
pipe,
isWx,
+ runFn,
logger,
mergeAll,
apiConfigToReqFnParams,
@@ -145,9 +146,7 @@ class TuaApi {
// mock data
if (mock) {
- const resData = typeof mock === 'function'
- ? mock(data)
- : { ...mock }
+ const resData = { ...runFn(mock, data) }
return Promise.resolve({ data: resData })
}
@@ -255,7 +254,7 @@ class TuaApi {
mock,
name,
path,
- params = {},
+ params: rawParams = {},
prefix,
afterFn = ([x]) => x,
beforeFn = Promise.resolve.bind(Promise),
@@ -308,6 +307,8 @@ class TuaApi {
const apiFn = (args, runtimeOptions = {}) => {
args = args || {}
+ const params = runFn(rawParams, args)
+
// 最终的运行时配置,runtimeOptions 有最高优先级
const runtimeParams = {
type,
@@ -361,7 +362,7 @@ class TuaApi {
apiFn.key = `${prefix}/${apiName}`
apiFn.mock = mock
- apiFn.params = params
+ apiFn.params = rawParams
return { [apiName]: apiFn }
}
diff --git a/src/middlewareFns.js b/src/middlewareFns.js
index 31f7095..2e51c93 100644
--- a/src/middlewareFns.js
+++ b/src/middlewareFns.js
@@ -1,5 +1,6 @@
import { ERROR_STRINGS } from './constants'
import {
+ runFn,
isFormData,
combineUrls,
checkArrayParams,
@@ -59,7 +60,7 @@ const formatReqParamsMiddleware = (ctx, next) => {
const {
args,
params,
- commonParams,
+ commonParams: rawCommonParams,
} = ctx.req
if (typeof args !== 'object') {
@@ -74,10 +75,11 @@ const formatReqParamsMiddleware = (ctx, next) => {
checkArrayParams(ctx.req)
+ const commonParams = runFn(rawCommonParams, args)
// 根据配置生成请求的参数
ctx.req.reqParams = Array.isArray(params)
? { ...commonParams, ...args }
- : { ...getDefaultParamObj(ctx.req), ...args }
+ : { ...getDefaultParamObj({ ...ctx.req, commonParams }), ...args }
return next()
}
diff --git a/src/utils/judge.js b/src/utils/judge.js
index 0274f58..5a3ae22 100644
--- a/src/utils/judge.js
+++ b/src/utils/judge.js
@@ -8,4 +8,10 @@ export const isFormData = (val) => (
(val instanceof FormData)
)
+export const runFn = (fn, ...params) => {
+ if (typeof fn === 'function') return fn(...params)
+
+ return fn
+}
+
export const isUndefined = val => typeof val === 'undefined'
diff --git a/test/__tests__/axios.test.js b/test/__tests__/axios.test.js
index 0b4e909..dae56ce 100644
--- a/test/__tests__/axios.test.js
+++ b/test/__tests__/axios.test.js
@@ -151,7 +151,6 @@ describe('fake post requests', () => {
})
test('form-data', async () => {
- mock.resetHistory()
mock.onPost(reqOHUrl).reply(200, {})
const formData = new FormData()
formData.append('a', 'a')
@@ -169,7 +168,6 @@ describe('fake post requests', () => {
})
test('custom-transformRequest', async () => {
- mock.resetHistory()
mock.onPost(reqCTUrl).reply(200, {})
await fakePostApi.ct()
@@ -180,7 +178,6 @@ describe('fake post requests', () => {
})
test('post-json', async () => {
- mock.resetHistory()
mock.onPost(reqPjUrl).reply(200, {})
await fakePostApi.pj()
diff --git a/test/__tests__/fn.test.js b/test/__tests__/fn.test.js
new file mode 100644
index 0000000..daafbf1
--- /dev/null
+++ b/test/__tests__/fn.test.js
@@ -0,0 +1,31 @@
+import axios from 'axios'
+import MockAdapter from 'axios-mock-adapter'
+
+import fakeFnConfig from '@examples/apis-web/fake-fn'
+import { fakeFnApi } from '@examples/apis-web/'
+
+const mock = new MockAdapter(axios)
+
+const params = { param1: 'steve', param2: 'young' }
+const reqFPUrl = 'http://example-base.com/fake-fn/fn-params'
+
+describe('function params', () => {
+ beforeEach(() => {
+ // @ts-ignore
+ mock.resetHistory()
+ })
+
+ test('should support function type params', async () => {
+ Math.random = jest.fn(() => 'foo')
+ mock.onPost(reqFPUrl).reply(200, {})
+ await fakeFnApi.fp(params)
+
+ const { data } = mock.history.post[0]
+ expect(data).toEqual(JSON.stringify({
+ ...fakeFnConfig.commonParams(params),
+ t: 'foo',
+ p1: params.param1,
+ p2: params.param2,
+ }))
+ });
+});