create-api.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. const {
  2. isFn,
  3. isPlainObject
  4. } = require('./utils')
  5. /**
  6. * 实例参数处理,注意:不进行递归处理
  7. * @param {Object} params 初始参数
  8. * @param {Object} rule 规则集
  9. * @returns {Object} 处理后的参数
  10. */
  11. function parseParams (params = {}, rule) {
  12. if (!rule || !params) {
  13. return params
  14. }
  15. const internalKeys = ['_pre', '_purify', '_post']
  16. // 转换之前的处理
  17. if (rule._pre) {
  18. params = rule._pre(params)
  19. }
  20. // 净化参数
  21. let purify = { shouldDelete: new Set([]) }
  22. if (rule._purify) {
  23. const _purify = rule._purify
  24. for (const purifyKey in _purify) {
  25. _purify[purifyKey] = new Set(_purify[purifyKey])
  26. }
  27. purify = Object.assign(purify, _purify)
  28. }
  29. if (isPlainObject(rule)) {
  30. for (const key in rule) {
  31. const parser = rule[key]
  32. if (isFn(parser) && internalKeys.indexOf(key) === -1) {
  33. params[key] = parser(params)
  34. } else if (typeof parser === 'string' && internalKeys.indexOf(key) === -1) {
  35. // 直接转换属性名称的删除旧属性名
  36. params[key] = params[parser]
  37. purify.shouldDelete.add(parser)
  38. }
  39. }
  40. } else if (isFn(rule)) {
  41. params = rule(params)
  42. }
  43. if (purify.shouldDelete) {
  44. for (const item of purify.shouldDelete) {
  45. delete params[item]
  46. }
  47. }
  48. // 转换之后的处理
  49. if (rule._post) {
  50. params = rule._post(params)
  51. }
  52. return params
  53. }
  54. /**
  55. * 返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文
  56. * @param {class} ApiClass 实例类
  57. * @param {Object} options 参数
  58. * @returns {Object} 实例类对象
  59. */
  60. module.exports = function createApi (ApiClass, options) {
  61. const apiInstance = new ApiClass(options)
  62. return new Proxy(apiInstance, {
  63. get: function (obj, prop) {
  64. if (typeof obj[prop] === 'function' && prop.indexOf('_') !== 0 && obj._protocols && obj._protocols[prop]) {
  65. const protocol = obj._protocols[prop]
  66. return async function (params) {
  67. params = parseParams(params, protocol.args)
  68. let result = await obj[prop](params)
  69. result = parseParams(result, protocol.returnValue)
  70. return result
  71. }
  72. } else {
  73. return obj[prop]
  74. }
  75. }
  76. })
  77. }