npm package: @snack-kit/lib
Description: Enterprise-grade utility library
Latest version: 0.10.0

# @snack-kit/lib

企业级通用工具库，提供 HTTP 客户端、调试面板、通用工具函数等模块，全栈 TypeScript，支持 ESM / CJS / UMD 三种格式。

## 安装

```bash
npm install @snack-kit/lib
```

## 模块

| 入口 | 说明 |
|------|------|
| `@snack-kit/lib` | 聚合入口，导出全部模块 |
| `@snack-kit/lib/http` | HTTP 客户端、Context 路由映射 |
| `@snack-kit/lib/debugger` | 开发调试面板 |
| `@snack-kit/lib/utils` | 通用工具函数 |

---

## HTTP 模块

### 快速开始

```ts
import { Get, Post, Context } from '@snack-kit/lib/http'

// 加载路由映射（生产环境无需传参，自动使用当前 Origin）
await Context.load()

// 发起请求
const { data, error } = await Get<{ name: string }>('/api/user/1', { ctx: 'user-svc' })
if (error) console.error(error.message)
else console.log(data?.name)
```

### 请求方法

所有方法均支持**两种调用形式**：

```ts
// 位置参数形式
Get(url, config?)
Post(url, data?, config?)
Put(url, data?, config?)
Patch(url, data?, config?)
Del(url, config?)

// 配置对象形式（method 已预置，无需传入）
Get({ url, ...config })
Post({ url, data, ...config })
```

**示例：**

```ts
import { Get, Post, Del } from '@snack-kit/lib/http'

// GET
const { data } = await Get('/api/users', { ctx: 'user-svc' })

// POST - 位置参数
await Post('/api/user', { name: 'Alice' }, { ctx: 'user-svc' })

// POST - 配置对象
await Post({ url: '/api/user', data: { name: 'Alice' }, ctx: 'user-svc' })

// DELETE
await Del('/api/user/1')
```

### Context 路由映射

```ts
import { Context } from '@snack-kit/lib/http'

// 生产环境：无参调用，自动以当前页面 Origin 为网关请求 /ngw/context
await Context.load()

// 指定网关地址
await Context.load('http://172.16.32.155:20000')

// 本地注入（测试 / Mock 场景）
await Context.load({ 'user-svc': 'http://user.api.com' })

Context.get('user-svc')  // 'http://user.api.com'
Context.info             // { version, domain, client, lang }
Context.loaded           // true
```

### 请求取消

```ts
import { Get, Cancel, CancelAll } from '@snack-kit/lib/http'

let cancelId = ''
Get('/api/list', { onCancelId: (id) => { cancelId = id } })

Cancel(cancelId)  // 取消单个请求
CancelAll()       // 取消所有进行中的请求
```

### 直接使用 axios

http 模块同时导出了原始 axios 实例及其常用类型，无需单独安装 `axios`：

```ts
import { axios } from '@snack-kit/lib/http'
import type { AxiosRequestConfig, AxiosResponse, AxiosInstance, AxiosError } from '@snack-kit/lib/http'

// 直接使用 axios 实例
const res = await axios.get('https://api.example.com/data')
```

---

## Debugger 模块

在开发环境挂载调试面板，支持切换网关、选择目标服务，并自动加载对应的路由映射。

```ts
import { Debugger } from '@snack-kit/lib/debugger'

// 仅在非生产环境加载
if (import.meta.env.DEV) {
  // 配置对象形式（可设置 timeout 等选项）
  await Debugger.init({
    gateways: [
      'http://dev-gateway.example.com',
      'http://test-gateway.example.com',
    ],
    timeout: 5000,
  })

  // 数组简写形式（等价写法）
  await Debugger.init([
    'http://dev-gateway.example.com',
    'http://test-gateway.example.com',
  ])
}

// 生产环境正常调用，Debugger 未激活时自动以 Origin 加载
await Context.load()
```

> 调用 `Debugger.init()` 后，`Context.load()` 无参调用会自动跳过，由调试面板接管加载时机。

---

## Utils 模块

### 类型检测

```ts
import { IsNumber, IsString, IsArray, IsObject, IsNull, IsEqual } from '@snack-kit/lib/utils'

IsNumber('42')          // true
IsObject([])            // false（数组不算对象）
IsNull(undefined)       // true
IsEqual({ a: 1 }, { a: 1 }) // true
```

### 输入校验

```ts
import { IsEmail, IsPhone, IsUrl, IsIpv4, REGEX } from '@snack-kit/lib/utils'

IsEmail('user@example.com')   // true
IsPhone('13812345678')        // true
IsUrl('https://example.com')  // true
REGEX.color.test('#fff')      // true
```

### 数组工具

```ts
import { Unique, UniqueByKey, Minus } from '@snack-kit/lib/utils'

Unique([1, 2, 1, 3])  // [1, 2, 3]
UniqueByKey([{ id: 1 }, { id: 1 }, { id: 2 }], 'id')  // [{ id: 1 }, { id: 2 }]
Minus([1, 2, 3], [2, 3])  // [1]
```

### 对象工具

```ts
import { DeepClone, CleanObject, Pick, Omit } from '@snack-kit/lib/utils'

DeepClone({ a: { b: 1 } })                  // 深拷贝新对象
CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }
Pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])      // { a: 1, c: 3 }
Omit({ a: 1, b: 2, c: 3 }, ['b'])           // { a: 1, c: 3 }
```

### 函数工具

```ts
import { Debounce, Throttle, Delay } from '@snack-kit/lib/utils'

const handleInput = Debounce((val: string) => search(val), 500)
const handleScroll = Throttle(() => updatePosition(), 100)
await Delay(1000)  // 等待 1 秒
```

### 字符串 / URL 工具

```ts
import { UUID, GetURLParam, GetURLParams, ObjectToQuery, QueryToObject } from '@snack-kit/lib/utils'

UUID()  // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
GetURLParam('page', 'https://example.com?page=2')  // '2'
GetURLParams('https://example.com?a=1&b=2')        // { a: '1', b: '2' }
ObjectToQuery({ page: 1, size: 10 })               // '?page=1&size=10'
QueryToObject('?a=1&b=2')                          // { a: '1', b: '2' }
```

### 时间工具

```ts
import { FormatDate, GetDateOffset, GetDayRange } from '@snack-kit/lib/utils'

FormatDate(new Date(), 'yyyy-MM-dd')         // '2026-03-02'
GetDateOffset(new Date(), -7, 'yyyy-MM-dd')  // 7 天前的日期
GetDayRange(new Date())  // { start: 1740844800000, end: 1740931199999 }
```

---

## 开发脚本

| 命令 | 说明 |
|------|------|
| `npm run build` | 构建生产包（ESM + CJS + UMD + 类型声明） |
| `npm run build:watch` | 监听模式构建 |
| `npm run test` | 运行单元测试 |
| `npm run test:coverage` | 运行测试并生成覆盖率报告 |
| `npm run docs` | 生成 API 文档 |
| `npm run lint` | TypeScript 类型检查 |
| `npm run release` | 构建并发布到 npm |

## API 文档

执行 `npm run docs` 后在 `docs/api/index.html` 查看完整 API 文档。

## License

MIT

---

## Changelog

### 0.10.0

- **[debugger]** 修复调试面板收起时仍存在透明遮挡层的问题，收起状态下不再拦截页面交互
- **[debugger]** 调试浮动按钮支持拖拽移动位置，避免遮挡页面内容

### 0.9.0

- **[http]** 新增 WebSocket 封装：`Ws(url | config, event)` 创建连接，`WsClose(id)` 关闭指定连接，`WsCloseAll()` 关闭所有连接
- **[http]** 新增 WS 相关类型：`WsRequestConfig`、`WsEventName`、`WsEventCallback<T>`
- **[http]** `Ws` 支持 `ctx` 自动从 Context 获取 host 拼接地址，自动将 `http(s)://` 转换为 `ws(s)://`
- **[http]** `Ws` message 事件自动尝试 JSON 解析，支持泛型 `<T>` 类型推导

### 0.8.0

- **[utils]** 新增 `CopyToClipboard(str): Promise<boolean>`，优先使用 `navigator.clipboard.writeText()`，自动降级为 `execCommand`
- **[utils]** 新增 `REGEXPRULES` 完整正则规则集，覆盖数字/英文/中文、身份证、邮箱、电话、URL、IP、时间、颜色等分类

### 0.7.0

- **[debugger]** `Debugger.init()` 新增数组简写入参形式，直接传入网关 URL 数组等价于 `{ gateways: [...] }`

### 0.6.0

- **[http]** `Context` 内部使用独立 axios 实例，隔离外部拦截器对上下文加载请求的污染
- **[debugger]** `Debugger` 内部使用独立 axios 实例，隔离外部拦截器对调试面板请求的污染

### 0.5.0

- **[utils]** 新增 `utils` 模块，包含以下子模块（详见 0.2.0 条目）
- **[http]** 新增配置对象入参形式、`HttpMethodConfig` 类型、原始 `axios` 导出（详见 0.4.0 条目）

### 0.4.0

- **[http]** `Get` / `Post` / `Put` / `Patch` / `Del` 新增配置对象入参形式，`method` 由方法预置无需重复传入
- **[http]** 新增导出类型 `HttpMethodConfig`（`Omit<HttpRequestConfig, 'method'>`）
- **[http]** 导出原始 `axios` 实例及 `AxiosRequestConfig` / `AxiosResponse` / `AxiosInstance` / `AxiosError` 类型，无需单独安装 `axios`

### 0.3.0

- **[http]** `Context.load()` 参数改为可选：
  - 无参 + Debugger 已激活 → 跳过，由调试面板接管加载
  - 无参 + Debugger 未激活 → 自动以当前页面 `Origin` 为网关请求 `/ngw/context`
- **[http]** 导出 `DEBUGGER_ACTIVE_KEY` 常量，供 Debugger 模块写入全局标志位
- **[debugger]** `Debugger.init()` 执行时向 `globalThis` 写入激活标志位
- **[debugger]** 导出 `DEBUGGER_ACTIVE_KEY`

### 0.2.0

- **[utils]** 新增 `utils` 模块，包含以下子模块：
  - `detect`：类型检测（`IsNumber` / `IsString` / `IsArray` / `IsObject` / `IsNull` / `IsEqual` 等）
  - `validate`：输入校验与常用正则（`IsEmail` / `IsPhone` / `IsUrl` / `IsIpv4` / `REGEX` 等）
  - `array`：数组工具（`Unique` / `UniqueByKey` / `Minus`）
  - `object`：对象工具（`DeepClone` / `CleanObject` / `Pick` / `Omit`）
  - `func`：函数工具（`Debounce` / `Throttle` / `Delay`）
  - `string`：字符串工具（`UUID` / `GetURLParam` / `GetURLParams` / `ObjectToQuery` / `QueryToObject`）
  - `time`：时间工具（`FormatDate` / `GetDateOffset` / `GetDayRange`）
- **[utils]** 所有方法 JSDoc 标注浏览器兼容性范围
- **[build]** `tsup.config.ts` 与 `package.json` 新增 `utils` 独立打包入口与导出字段

### 0.1.0

- 初始版本
- **[http]** HTTP 客户端模块：`Request` / `Get` / `Post` / `Put` / `Patch` / `Del`
- **[http]** Context 路由映射：`Context` / `Origin` / `Ctx`
- **[http]** 请求取消：`Cancel` / `CancelAll`
- **[debugger]** 开发调试面板：`Debugger.init()`