# xhshow-js

<div align="center">

小红书请求签名生成库的 TypeScript 实现，支持 `GET`/`POST` 请求的 `x-s` 和 `x-s-common` 签名，并提供相关辅助工具。

本项目基于 [xhshow](https://github.com/Cloxl/xhshow) 的 Python 实现移植。

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16.0.0-green)](https://nodejs.org/)

</div>

---

## 📋 目录

- [特性](#特性)
- [安装](#安装)
- [快速开始](#快速开始)
- [API 文档](#api-文档)
- [使用示例](#使用示例)
- [项目结构](#项目结构)
- [开发](#开发)
- [测试](#测试)
- [贡献](#贡献)
- [许可证](#许可证)

---

## ✨ 特性

- 🎯 **完整功能**：支持 `x-s`、`x-s-common`、`x-t`、`x-b3-traceid`、`x-xray-traceid` 等所有必要签名
- 📦 **TypeScript 原生**：完整的类型定义，提供优秀的开发体验
- 🚀 **双模块支持**：同时支持 ESM 和 CommonJS
- 🔐 **加密支持**：内置 RC4、MD5、CRC32 等加密算法
- 🎨 **浏览器指纹**：自动生成真实的浏览器指纹信息
- 🧪 **完整测试**：单元测试覆盖率 > 80%
- 📝 **详细文档**：中英文双语文档和示例

---

## 📦 安装

使用 npm:

```bash
npm install xhshow-js
```

使用 pnpm:

```bash
pnpm add xhshow-js
```

使用 yarn:

```bash
yarn add xhshow-js
```

---

## 🚀 快速开始

### 基础用法

```typescript
import { Client } from 'xhshow-js';

// 创建客户端实例
const client = new Client();

// 准备请求参数
const a1Value = 'your_a1_cookie_value'; // 从 Cookie 中获取
const method = 'GET';
const uri = '/api/sns/web/v1/user_posted';
const payload = {
  num: 30,
  cursor: '',
  user_id: '123',
};

// 生成 x-s 签名
const xs = client.signXS(method, uri, a1Value, 'xhs-pc-web', payload);
console.log('x-s:', xs);

// 生成其他必要的头部
const xt = client.getXT();
console.log('x-t:', xt);

const b3TraceId = client.getB3TraceId();
console.log('x-b3-traceid:', b3TraceId);

const xrayTraceId = client.getXrayTraceId();
console.log('x-xray-traceid:', xrayTraceId);

// 生成 x-s-common 签名
const cookies = {
  a1: a1Value,
  web_session: 'your_web_session_value',
};
const xsCommon = client.signXSCommon(cookies);
console.log('x-s-common:', xsCommon);
```

### POST 请求示例

```typescript
const method = 'POST';
const uri = '/api/sns/web/v1/comment/post';
const payload = {
  note_id: '64ec1234567890',
  content: '不错',
  at_users: [],
};

const xs = client.signXS(method, uri, a1Value, 'xhs-pc-web', payload);
```

---

## 📚 API 文档

### Client 类

主客户端类，提供所有签名生成功能。

#### 构造函数

```typescript
constructor();
```

创建一个新的客户端实例。

#### 方法

##### `signXS(method, uri, a1Value, xsecAppId?, payload?, timestamp?): string`

生成 `x-s` 签名。

**参数：**

- `method: string` - HTTP 方法（`'GET'` 或 `'POST'`）
- `uri: string` - 请求 URI（如 `/api/sns/web/v1/user_posted`）
- `a1Value: string` - Cookie 中的 `a1` 值
- `xsecAppId?: string` - 应用标识符，默认为 `'xhs-pc-web'`
- `payload?: RequestPayload` - 请求参数（GET 为查询参数，POST 为请求体）
- `timestamp?: number` - 可选的时间戳（毫秒），默认使用当前时间

**返回：** `string` - 生成的 `x-s` 签名

##### `signXSCommon(cookies): string`

生成 `x-s-common` 签名。

**参数：**

- `cookies: CookieDict` - Cookie 字典，必须包含 `a1` 字段

**返回：** `string` - 生成的 `x-s-common` 签名

##### `getXT(timestamp?): number`

获取 `x-t` 头部值（毫秒级时间戳）。

**参数：**

- `timestamp?: number` - 可选的时间戳（秒），默认使用当前时间

**返回：** `number` - 毫秒级时间戳

##### `getB3TraceId(): string`

生成 `x-b3-traceid`。

**返回：** `string` - 16 字符的十六进制字符串

##### `getXrayTraceId(timestamp?, seq?): string`

生成 `x-xray-traceid`。

**参数：**

- `timestamp?: number` - 可选的时间戳（毫秒）
- `seq?: number` - 可选的序列号

**返回：** `string` - 32 字符的十六进制字符串

##### `decodeXS(xsSignature): SignatureData`

解密 `x-s` 签名。

**参数：**

- `xsSignature: string` - 完整的 `x-s` 签名（包含 `XYS_` 前缀）

**返回：** `SignatureData` - 解密后的签名数据结构

##### `decodeX3(x3Signature): Uint8Array`

解密 `x3` 签名。

**参数：**

- `x3Signature: string` - `x3` 签名字符串

**返回：** `Uint8Array` - 解密后的字节数组

##### `parseX3Payload(payload): X3Payload`

解析 `x3` payload。

**参数：**

- `payload: Uint8Array` - 解密后的 `x3` 数据

**返回：** `X3Payload` - 解析后的 payload 结构

### 工具函数

```typescript
// Cookie 生成
generateA1(): string
registerId(): string
generateRandomString(length: number): string
getLoadTs(): string

// TraceId 生成
generateB3TraceId(): string
generateXrayTraceId(timestamp?: number, seq?: number): string

// Base64 编码/解码
encodeCustomBase64(data: Uint8Array): string
decodeCustomBase64(data: string): Uint8Array
encodeX3Base64(data: Uint8Array): string
decodeX3Base64(data: string): Uint8Array

// 随机数生成
generateRandomInt(): number
generateRandomByteInRange(minVal: number, maxVal: number): number
```

---

## 💻 使用示例

### 完整的请求示例

```typescript
import { Client } from 'xhshow-js';

const client = new Client();

// 1. 准备 Cookie
const cookies = {
  a1: 'efda9b010000220000009d04000022000',
  web_session: 'your_web_session_value',
};

// 2. GET 请求
const getUri = '/api/sns/web/v1/user_posted';
const getParams = { num: 30, user_id: '123' };

const headers = {
  'x-s': client.signXS('GET', getUri, cookies.a1, 'xhs-pc-web', getParams),
  'x-t': client.getXT().toString(),
  'x-b3-traceid': client.getB3TraceId(),
  'x-xray-traceid': client.getXrayTraceId(),
  'x-s-common': client.signXSCommon(cookies),
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
};

// 使用 headers 发送请求
console.log('Request headers:', headers);
```

### 签名验证和调试

```typescript
// 生成签名
const xs = client.signXS('GET', '/api/test', 'test_a1_value');

// 解密签名以验证
const decoded = client.decodeXS(xs);
console.log('签名结构:', decoded);

// 解密 x3
if (decoded.x3) {
  const x3Decoded = client.decodeX3(decoded.x3);
  const payload = client.parseX3Payload(x3Decoded);
  console.log('Payload 详情:', payload);
}
```

更多示例请参见 [examples](./examples) 目录。

---

## 📁 项目结构

```
xhshow-js/
├── src/
│   ├── client.ts           # 主客户端类
│   ├── config.ts           # 配置常量
│   ├── xs-common.ts        # xs-common 签名器
│   ├── types/
│   │   └── index.ts        # TypeScript 类型定义
│   ├── utils/
│   │   ├── index.ts        # 工具函数
│   │   └── cookie.ts       # Cookie 生成
│   ├── crypto/
│   │   └── index.ts        # 加密函数
│   └── fingerprint/
│       ├── data.ts         # 指纹数据配置
│       ├── helpers.ts      # 指纹辅助函数
│       └── generator.ts    # 指纹生成器
├── tests/                  # 测试文件
├── examples/               # 使用示例
├── dist/                   # 构建输出
├── package.json
├── tsconfig.json
└── README.md
```

---

## 🛠️ 开发

### 环境要求

- Node.js >= 16.0.0
- pnpm (推荐) 或 npm

### 安装依赖

```bash
pnpm install
```

### 构建

```bash
pnpm build
```

### 开发模式（监视文件变化）

```bash
pnpm dev
```

### 代码格式化

```bash
pnpm format
```

### 类型检查

```bash
pnpm typecheck
```

---

## 🧪 测试

运行所有测试：

```bash
pnpm test
```

运行测试并生成覆盖率报告：

```bash
pnpm test:coverage
```

运行示例：

```bash
# 基础示例
npx tsx examples/basic.ts

# 高级示例
npx tsx examples/advanced.ts
```

---

## 🤝 贡献

欢迎贡献！请遵循以下步骤：

1. Fork 本仓库
2. 创建您的特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交您的更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 开启一个 Pull Request

---

## 📄 许可证

本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。

---

## 🙏 致谢

- 特别感谢 [Cloxl](https://github.com/Cloxl) 开源的 [xhshow](https://github.com/Cloxl/xhshow) 项目
- 感谢所有贡献者的支持

---

## ⚠️ 免责声明

本项目仅供学习和研究使用，请勿用于非法用途。使用本项目所产生的一切后果由使用者自行承担。

---

## 📮 联系方式

如有问题或建议，请提交 [Issue](https://github.com/yourusername/xhshow-js/issues)。

---

**Star ⭐ 本项目如果它对您有帮助！**
