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

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

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

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

fxy060608's avatar
fxy060608 已提交
18 19 20 21
function mergeInterceptorHook(
  interceptors: Interceptors,
  interceptor: Interceptor
) {
22
  Object.keys(interceptor).forEach((hook) => {
fxy060608's avatar
fxy060608 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
    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
  }
39
  Object.keys(interceptor).forEach((hook) => {
fxy060608's avatar
fxy060608 已提交
40
    if (isFunction(interceptor[hook as HOOKS])) {
41 42 43 44
      removeHook(
        interceptors[hook as HOOKS],
        interceptor[hook as HOOKS] as Function
      )
fxy060608's avatar
fxy060608 已提交
45 46 47 48 49 50 51 52 53 54 55 56
    }
  })
}

function mergeHook(
  parentVal: Function[] | undefined,
  childVal: Function[] | Function | undefined
) {
  const res = childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : isArray(childVal)
57 58
      ? childVal
      : [childVal]
fxy060608's avatar
fxy060608 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    : 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 已提交
83
export const addInterceptor = defineSyncApi(
84
  'addInterceptor',
fxy060608's avatar
fxy060608 已提交
85 86 87 88 89 90 91 92 93 94 95 96
  (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 已提交
97

fxy060608's avatar
fxy060608 已提交
98
export const removeInterceptor = defineSyncApi(
99
  'removeInterceptor',
fxy060608's avatar
fxy060608 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
  (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
)

export const promiseInterceptor = {
  returnValue(res: unknown) {
    if (!isPromise(res)) {
      return res
fxy060608's avatar
fxy060608 已提交
118
    }
fxy060608's avatar
fxy060608 已提交
119
    return res
120
      .then((res) => {
fxy060608's avatar
fxy060608 已提交
121 122
        return res[1]
      })
123
      .catch((res) => {
fxy060608's avatar
fxy060608 已提交
124 125
        return res[0]
      })
126
  },
fxy060608's avatar
fxy060608 已提交
127
}