npm package: @kriszu/request
Description: ## 安装
Author: Kriszu
Latest version: 1.0.1

# @kriszu/request

## 安装

```shell
npm i @kriszu/request
```


-   使用插件

```typescript
import axios from 'axios'
import { useAxiosPlugin, mock, loading } from '@kriszu/request'

// 1. 定义axios实例 或 使用项目现有的axios实例
export const request = axios.create({
    /* ... */
})

// 2. 添加插件支持

useAxiosPlugin(axios) // axios 默认实例, 添加插件支持
useAxiosPlugin(request) // axios 一般实例, 添加插件支持

// 3. 使用插件

useAxiosPlugin(axios)
    // 添加 mock 插件
    .use(mock())

// 4. 请求过程中, 使用插件扩展参数

request.post('/api', {}, { mock: true }) // 指定接口请求时, 向mock服务器发起请求

// 5. 如果需要支持 `request()` 方式调用, 需要通过 `wrap()` 方法覆盖原实例
const request2 = useAxiosPlugin(request)
    .use(mock()) // 添加插件
    .wrap() // wrap 函数包装 axios 实例
```

-   创建自定义插件

```typescript
import axios from 'axios'
import { useAxiosPlugin, IPlugin } from '@kriszu/request'

/**
 * 定义插件
 *
 * @param {options} 插件参数
 * @returns IPlugin
 */
const plug = (options: unknown): IPlugin => {
    // @ 定义url路径过滤器
    const filter = createUrlFilter(options.includes, options.excludes)
    return {
        name: '插件名',
        enforce:'pre',
        beforeRegister:()=>{}
        ....
    }
}
// 类型
/** 插件接口 */
export interface IPlugin {
  /** 插件名 */
  name: string

  /** 插件内部执行顺序 */
  enforce?: 'pre' | 'post'

  /**
   * 插件注册前置事件
   *
   * @description 可以在此检查 axios 实例是否可以支持当前插件的使用, 如果不能够支持, 应抛出异常.
   */
  beforeRegister?: (axios: AxiosInstanceExtension) => void
  /**
   * 在 `axios.request` 调用前触发钩子
   */
  preRequest?: ILifecycleHook<AxiosRequestConfig>
  /**
   * `axios.interceptors.request` 钩子, 在拦截器内修改请求
   */
  transform?: ILifecycleHook<InternalAxiosRequestConfig>
  /**
   *  响应后触发钩子
   */
  postResponse?: ILifecycleHook<AxiosResponse>
  /**
   * 捕获异常钩子
   *
   * @description 这是一个特殊钩子, 将阻塞异常反馈, 并在钩子函数完成后, 返回正常结果. 如果需要抛出异常, 那么应通过 `throw Error` 方式, 抛出异常信息.
  */
  onException?: ILifecycleHook<Error | AxiosError | any>
  /**
   * 请求完成后置钩子
   */
  onCompleted?:
  | ((options: IHooksShareOptions, controller: AbortChainController) => void | Promise<void>)
  | {
    enable: (options: IHooksShareOptions) => boolean
    handler: (options: IHooksShareOptions, controller: AbortChainController) => void | Promise<void>
  }
}
// 使用
useAxiosPlugin(axios).plugin(plug({}))
```

## 插件

| plugin                          | 名称             | 描述                                                                                   |
| ------------------------------- | ---------------- | -------------------------------------------------------------------------------------- |
| [debounce]           | 防抖             | 在一段时间内发起的重复请求, 后执行的请求将等待上次请求完成后再执行                     |
| [throttle]           | 节流             | 在一段时间内发起的重复请求, 后执行的请求将被抛弃                                       |
| [merge]              | 重复请求合并     | 在一段时间内发起的重复请求, 仅请求一次, 并将请求结果分别返回给不同的发起者             |
| [retry]              | 失败重试         | 当请求失败(出错)后, 重试 n 次, 当全部失败时, 再抛出异常                                |
| [cancel]               | 取消(中止)请求   | 提供 `cancelAll()` 方法, 中止当前在进行的所有请求                                      |
| [transform]         | 转换请求/响应    | 替代`axios.interceptors`的使用, 用于统一管理 axios 请求过程                            |
| [cache]                 | 响应缓存         | 存储请求响应内容, 在下次请求时返回 (需要在缓存时效内)                                  |
| [mock]                   | 模拟(调试用)     | 提供全局或单个接口请求 mock 能力                                                       |
| [loading]             | 全局 loading     | 提供全局 loading 统一控制能力, 减少每个加载方法都需要独立 loading 控制的工作量         |
| [logger]               | 日志             | 自定义请求过程日志打印                                                                 |