npm package: @banana020/ast-plugin-system
Description: AST插件系统 - 支持JavaScript/TypeScript代码转换，包含十六进制转换、代码清理等功能
Author: banana020
Latest version: 1.0.7

# AST 插件系统

一个基于 Babel 的 AST（抽象语法树）插件系统，用于代码转换和分析。

## 项目结构

```
ast/
├── src/
│   ├── plugins/           # 插件目录
│   │   └── del-extra      # delExtra 插件
│   ├── types/             # 类型定义
│   │   └── index.ts
│   └── utils/             # 工具函数
│       └── index.ts
├── tests/                 # 测试文件
│   └── del-extra.test.ts
├── examples/              # 示例代码
│   └── del-extra-example.ts
├── index.ts               # 主入口文件
├── package.json
└── tsconfig.json
```

## 安装依赖

```bash
bun install
```

## 可用插件

### delExtra

一个强大的代码清理和转换插件，功能包括：

1. **删除 extra 属性**：清理 Babel 解析器添加的额外属性，使 AST 更加干净
2. **十六进制字符串转换**：将十六进制编码的字符串转换为人类可读的普通字符串
   - 例：`"\x49\x63\x4b\x72"` → `"IcKr"`
3. **十六进制数字转换**：将十六进制数字转换为十进制格式
   - 例：`0x123` → `291`

**典型用例**：
```javascript
// 输入代码
const data = ["\x49\x63\x4b\x72\x77\x70\x2f\x44\x6c\x67\x3d\x3d", 0x123];

// 转换后
const data = ["IcKrwp/Dlg==", 291];
```

## 使用方法

### 基本用法

```typescript
import { delExtra, transformCode } from './index';

const code = `const x = 42;`;
const result = transformCode(code, delExtra);
console.log(result.code);
```

### 十六进制转换示例

```typescript
// 十六进制字符串转换
const hexStringCode = `const encoded = "\\x48\\x65\\x6c\\x6c\\x6f";`;
const result1 = transformCode(hexStringCode, delExtra);
console.log(result1.code); // const encoded = "Hello";

// 十六进制数字转换
const hexNumberCode = `const numbers = [0x123, 0xFF];`;
const result2 = transformCode(hexNumberCode, delExtra);
console.log(result2.code); // const numbers = [291, 255];

// 复合转换
const complexCode = `const data = ["\\x49\\x63\\x4b\\x72", 0x123];`;
const result3 = transformCode(complexCode, delExtra);
console.log(result3.code); // const data = ["IcKr", 291];
```

### 分步骤使用

```typescript
import { parseCode, applyPlugin, generateCode, delExtra } from './index';

// 1. 解析代码
const ast = parseCode('const x = 42;');

// 2. 应用插件
applyPlugin(ast, delExtra);

// 3. 生成代码
const result = generateCode(ast);
console.log(result.code);
```

## 🚀 文件转换工作流程

### 快速开始

```bash
# 1. 设置项目结构
bun run setup

# 2. 将需要转换的文件放入 input/ 目录
cp your-file.js input/

# 3. 执行批量转换（不会覆盖已有文件）
bun run transform

# 4. 查看转换结果差异
bun run diff your-file.js

# 5. 在VSCode中对比文件（推荐）
# 打开 input/your-file.js 和 output/your-file+N.js
# 右键 → "选择进行比较" → "与已选项比较"
```

### 📁 目录结构

```
ast/
├── input/              # 原始文件目录（Git忽略 ❌）
├── output/             # 转换后文件目录（Git忽略 ❌）
│   ├── README.md       # 说明文档（保留）
│   ├── example.js      # 第一次转换结果
│   ├── example+1.js    # 第二次转换结果
│   └── example+2.js    # 第三次转换结果（最新）
├── src/plugins/        # 插件目录
├── tests/              # 测试目录
├── examples/           # 示例代码
├── ast.config.ts       # 转换配置文件
└── ...
```

### ✨ 版本化输出特性

- **不覆盖原有文件**：每次转换都会生成新文件（`filename+1.js`, `filename+2.js`...）
- **自动版本递增**：智能检测已有文件，自动选择下一个可用版本号
- **VSCode友好对比**：完美适配VSCode的文件对比功能
- **保持转换历史**：可以同时保留多个版本进行对比
- **灵活重置名称**：可以将版本化文件重置回原始名称

### 🔧 可用命令

#### 核心转换命令
```bash
# 使用默认配置批量转换
bun run transform

# 使用特定配置转换
bun run transform:js          # 仅处理JS文件
bun run transform:delextra    # 仅应用delExtra插件
bun run transform:flatten     # 扁平化输出结构

# 对比转换前后差异
bun run diff <filename>       # 自动对比最新版本
```

#### 开发和测试命令
```bash
# 运行主程序
bun run index.ts

# 运行测试
bun test

# 监听模式运行测试
bun test --watch

# 运行 delExtra 示例
bun run example:del-extra

# 开发模式（监听文件变化）
bun run dev

# 初始化项目结构
bun run setup

# 清理输出文件
bun run clean             # 清理所有输出文件
bun run clean:dup         # 只删除旧版本，保留最新
bun run clean:reset       # 重置为原始文件名
```

## 测试

项目包含完整的测试套件，测试各种场景：

- 基本代码转换和 extra 属性删除
- 复杂表达式处理
- JSX 代码支持
- TypeScript 代码支持
- **十六进制字符串转换**
- **十六进制数字转换** 
- **混合转换场景**
- 错误处理和边界情况

运行测试：

```bash
bun test
```

## 🎯 推荐的工作流程

### 版本化转换工作流程

```bash
# 1. 放入原始文件
cp obfuscated.js input/

# 2. 第一次转换
bun run transform
# 生成: output/obfuscated.js

# 3. 优化插件后再次转换
# 修改配置或插件...
bun run transform  
# 生成: output/obfuscated+1.js

# 4. 继续优化...
bun run transform
# 生成: output/obfuscated+2.js

# 5. 对比不同版本
bun run diff obfuscated.js  # 对比原文件和最新版本

# 6. 在VSCode中对比多个版本
# 同时打开 obfuscated.js, obfuscated+1.js, obfuscated+2.js
# 使用VSCode的多文件对比功能

# 7. 清理管理
bun run clean:dup     # 只保留最新版本
bun run clean:reset   # 重置为原始文件名(example.js)
```

### Git管理策略

由于 `input/` 和 `output/` 都被Git忽略，您可以：

1. **专注于插件开发**：只提交插件代码和配置变更
2. **避免历史污染**：转换结果不会污染Git历史
3. **本地版本管理**：使用文件版本号进行本地对比
4. **灵活选择**：需要时可以手动添加重要的转换结果到Git

### 自定义转换配置

编辑 `ast.config.ts` 来自定义转换行为：

```typescript
export const myCustomConfig: TransformConfig = {
  inputDir: './input',
  outputDir: './output',
  plugins: [
    {
      name: 'delExtra',
      description: '删除extra属性并转换十六进制值',
      version: '1.0.0', 
      plugin: delExtra,
    },
    // 添加更多插件...
  ],
  include: ['**/*.js', '**/*.ts'],
  exclude: ['**/*.test.*'],
  preserveStructure: true,
};
```

## 🔌 开发新插件

1. 在 `src/plugins/` 目录下创建新的插件文件
2. 实现 `ASTPlugin` 接口
3. 在 `tests/` 目录下添加对应的测试文件
4. 在 `examples/` 目录下添加使用示例
5. 在 `ast.config.ts` 中注册插件

### 插件模板

```typescript
import { type NodePath } from '@babel/traverse';
import { type Node } from '@babel/types';
import { type ASTPlugin } from '../types/index.js';

export const myPlugin: ASTPlugin = (path: NodePath<Node>, options?: any): void => {
  // 插件逻辑
};
```

## 技术栈

- **Runtime**: Bun
- **Language**: TypeScript
- **AST Parser**: Babel
- **Testing**: Bun Test

## 许可证

Private