interceptor.ts 3.1 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import { isArray, isFunction, isPromise, isPlainObject } from '@vue/shared'
fxy060608's avatar
fxy060608 已提交
2 3

import {
fxy060608's avatar
fxy060608 已提交
4
  HOOKS,
fxy060608's avatar
fxy060608 已提交
5 6 7 8 9 10
  Interceptor,
  scopedInterceptors,
  globalInterceptors,
  Interceptors,
} from '../../helpers/interceptor'

fxy060608's avatar
fxy060608 已提交
11
import { defineSyncApi } from '../../helpers/api'
fxy060608's avatar
fxy060608 已提交
12 13

import {
fxy060608's avatar
fxy060608 已提交
14 15
  API_ADD_INTERCEPTOR,
  API_REMOVE_INTERCEPTOR,
fxy060608's avatar
fxy060608 已提交
16
  AddInterceptorProtocol,
17
  RemoveInterceptorProtocol,
fxy060608's avatar
fxy060608 已提交
18 19
} from '../../protocols/base/interceptor'

fxy060608's avatar
fxy060608 已提交
20 21 22 23
function mergeInterceptorHook(
  interceptors: Interceptors,
  interceptor: Interceptor
) {
24
  Object.keys(interceptor).forEach((hook) => {
fxy060608's avatar
fxy060608 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
    if (isFunction(interceptor[hook as HOOKS])) {
      interceptors[hook as HOOKS] = mergeHook(
        interceptors[hook as HOOKS],
        interceptor[hook as HOOKS]
      )
    }
  })
}

function removeInterceptorHook(
  interceptors: Interceptors,
  interceptor: Interceptor
) {
  if (!interceptors || !interceptor) {
    return
  }
41
  Object.keys(interceptor).forEach((hook) => {
fxy060608's avatar
fxy060608 已提交
42
    if (isFunction(interceptor[hook as HOOKS])) {
43 44 45 46
      removeHook(
        interceptors[hook as HOOKS],
        interceptor[hook as HOOKS] as Function
      )
fxy060608's avatar
fxy060608 已提交
47 48 49 50 51 52 53 54 55 56 57 58
    }
  })
}

function mergeHook(
  parentVal: Function[] | undefined,
  childVal: Function[] | Function | undefined
) {
  const res = childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : isArray(childVal)
59 60
      ? childVal
      : [childVal]
fxy060608's avatar
fxy060608 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
    : parentVal
  return res ? dedupeHooks(res) : res
}

function dedupeHooks(hooks: Function[]) {
  const res: Function[] = []
  for (let i = 0; i < hooks.length; i++) {
    if (res.indexOf(hooks[i]) === -1) {
      res.push(hooks[i])
    }
  }
  return res
}

function removeHook(hooks: Function[] | undefined, hook: Function) {
  if (!hooks) {
    return
  }
  const index = hooks.indexOf(hook)
  if (index !== -1) {
    hooks.splice(index, 1)
  }
}

fxy060608's avatar
fxy060608 已提交
85
export const addInterceptor = defineSyncApi(
fxy060608's avatar
fxy060608 已提交
86
  API_ADD_INTERCEPTOR,
fxy060608's avatar
fxy060608 已提交
87 88 89 90 91 92 93 94 95 96 97 98
  (method: string | Interceptor, interceptor: Interceptor | undefined) => {
    if (typeof method === 'string' && isPlainObject(interceptor)) {
      mergeInterceptorHook(
        scopedInterceptors[method] || (scopedInterceptors[method] = {}),
        interceptor
      )
    } else if (isPlainObject(method)) {
      mergeInterceptorHook(globalInterceptors, method as Interceptor)
    }
  },
  AddInterceptorProtocol
)
fxy060608's avatar
fxy060608 已提交
99

fxy060608's avatar
fxy060608 已提交
100
export const removeInterceptor = defineSyncApi(
fxy060608's avatar
fxy060608 已提交
101
  API_REMOVE_INTERCEPTOR,
fxy060608's avatar
fxy060608 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115
  (method: string | Interceptor, interceptor: Interceptor | undefined) => {
    if (typeof method === 'string') {
      if (isPlainObject(interceptor)) {
        removeInterceptorHook(scopedInterceptors[method], interceptor)
      } else {
        delete scopedInterceptors[method]
      }
    } else if (isPlainObject(method)) {
      removeInterceptorHook(globalInterceptors, method)
    }
  },
  RemoveInterceptorProtocol
)

D
DCloud_LXH 已提交
116
const promiseInterceptor = {
fxy060608's avatar
fxy060608 已提交
117 118 119
  returnValue(res: unknown) {
    if (!isPromise(res)) {
      return res
fxy060608's avatar
fxy060608 已提交
120
    }
D
DCloud_LXH 已提交
121 122 123 124 125 126 127
    return new Promise((resolve, reject) => {
      res.then((res) => {
        if (res[0]) {
          reject(res[0])
        } else {
          resolve(res[1])
        }
fxy060608's avatar
fxy060608 已提交
128
      })
D
DCloud_LXH 已提交
129
    })
130
  },
fxy060608's avatar
fxy060608 已提交
131
}
D
DCloud_LXH 已提交
132 133 134 135

export const interceptors = {
  promiseInterceptor,
}