# @planarcat/js-toolkit

一个现代化的 JavaScript/TypeScript 实用工具库，提供类型安全、高性能的常用函数。

## 特性

- 🚀 **类型安全**: 完整的 TypeScript 支持，提供完整的类型定义
- 📦 **轻量级**: 零依赖，体积小巧
- 🎯 **高性能**: 优化的算法实现
- 🔧 **现代化**: 使用最新的 JavaScript/TypeScript 特性
- 📚 **学习性质**: 代码清晰，适合学习和参考

## 安装

```bash
# 使用 npm
npm install @planarcat/js-toolkit

# 使用 yarn
yarn add @planarcat/js-toolkit

# 使用 pnpm
pnpm add @planarcat/js-toolkit
```

## 快速开始

### 日期格式化

```typescript
import { formatDate } from '@planarcat/js-toolkit';

// 基本使用
console.log(formatDate(new Date()));
// 输出: "2023-12-25 14:30:45"

// 自定义格式
console.log(formatDate('2023-12-25', 'YYYY年MM月DD日'));
// 输出: "2023年12月25日"

// 使用 dd 标记显示周几
console.log(formatDate(new Date(), 'dd HH:mm'));
// 输出: "周一 14:30"

// 英文环境
console.log(formatDate(new Date(), 'dd HH:mm', { locale: 'en-US' }));
// 输出: "Monday 14:30"
```

### 函数防抖

```typescript
import { debounce } from '@planarcat/js-toolkit';

// 创建防抖函数
const debouncedFn = debounce(
  () => {
    console.log('函数执行了！');
  },
  { delay: 500 },
);

// 多次调用，只会执行最后一次
debouncedFn();
debouncedFn();
debouncedFn();
// 500ms 后执行一次
```

### 数字格式化

```typescript
import {
  toFormattedNumber,
  toFormattedNumberString,
  DecimalPlacesOptions,
} from '@planarcat/js-toolkit';

// 基本使用
console.log(toFormattedNumber(1234.5678));
// 输出: 1234.5678

// 保留两位小数
console.log(toFormattedNumber(1234.5678, { decimalPlaces: 2 }));
// 输出: 1234.57

// 使用 RETAIN_ALL 常量保留所有小数位
console.log(
  toFormattedNumber(1234.5678, {
    decimalPlaces: DecimalPlacesOptions.RETAIN_ALL,
  }),
);
// 输出: 1234.5678

// 处理字符串
console.log(toFormattedNumber('123.45abc'));
// 输出: 123.45

// 处理数组
console.log(toFormattedNumber([123.456, '456.789']));
// 输出: [123.456, 456.789]

// 处理深层数组
console.log(
  toFormattedNumber([
    [1, '1.23'],
    ['45.67', [89.01, 'abc']],
  ]),
);
// 输出: [[1, 1.23], [45.67, [89.01, NaN]]]

// 数字转格式化字符串
console.log(toFormattedNumberString(1234.5678, { decimalPlaces: 2 }));
// 输出: "1234.57"

// 使用 RETAIN_ALL 常量保留所有小数位
console.log(
  toFormattedNumberString(1234.5678, {
    decimalPlaces: DecimalPlacesOptions.RETAIN_ALL,
  }),
);
// 输出: "1234.5678"

// 保留两位小数，不够时补0
console.log(toFormattedNumberString(123.4, { decimalPlaces: 2 }));
// 输出: "123.40"

// 带前缀后缀
console.log(
  toFormattedNumberString(1234.5678, { prefix: '$', suffix: ' USD' }),
);
// 输出: "$1234.5678 USD"

// 本地化格式
console.log(toFormattedNumberString(1234567.89, { localized: true }));
// 输出: "1,234,567.89"

// 自定义NaN和0显示
console.log(toFormattedNumberString(null, { nanValue: 'N/A' }));
// 输出: "N/A"
console.log(toFormattedNumberString(0, { zeroValue: '-' }));
// 输出: "-"

// 预处理函数
console.log(
  toFormattedNumberString(0.1234, {
    preProcessor: (original, num) => num * 100,
    suffix: '%',
  }),
);
// 输出: "12.34%"

// 函数类型前缀
console.log(
  toFormattedNumberString(123.456, {
    prefix: (original, num, formatted) => `$${Math.floor(num)}`,
  }),
);
// 输出: "$123123.456"

// 函数类型后缀
console.log(
  toFormattedNumberString(123.456, {
    suffix: (original, num, formatted) => `/${num.toFixed(0)}`,
  }),
);
// 输出: "123.456/123"

// 处理数组
console.log(
  toFormattedNumberString([123.456, '789.012'], { decimalPlaces: 2 }),
);
// 输出: ["123.46", "789.01"]
```

## API 文档

详细的 API 文档请查看 [docs/](docs/) 目录下的模块文档：

- [日期格式化](docs/functions/formatDate.md)
- [函数防抖](docs/functions/debounce.md)
- [数字格式化](docs/functions/toFormattedNumber.md)
- [类型定义](docs/interfaces/)

### 生成文档

```bash
# 生成 API 文档
pnpm run docs

# 监听模式生成文档
pnpm run docs:watch
```

## 开发

### 项目结构

```
src/
├── date/
│   └── formatDate.ts      # 日期格式化函数
├── function/
│   └── debounce.ts        # 函数防抖功能
├── object/
│   ├── toFormattedNumber.ts  # 数字格式化函数
│   └── toFormattedNumberString.ts  # 格式化数字字符串函数
├── types/
│   ├── date.ts            # 日期相关类型定义
│   ├── function.ts        # 防抖相关类型定义
│   ├── object.ts          # 数字格式化相关类型定义
│   └── index.ts           # 类型导出
├── utils/
│   └── constants.ts       # 常量定义
└── index.ts               # 主入口文件
```

### 开发命令

```bash
# 安装依赖
pnpm install

# 构建项目
pnpm run build

# 运行测试
pnpm test

# 运行测试（监听模式）
pnpm run test:watch

# 代码检查
pnpm run lint

# 代码格式化
pnpm run format

# 清理构建文件
pnpm run clean
```

### 测试

项目使用 Jest 进行单元测试，测试文件位于 `__tests__/` 目录。

```bash
# 运行所有测试
pnpm test

# 生成测试覆盖率报告
pnpm run test:coverage
```

### 发布

项目使用 GitHub Actions 和 Trusted Publishing 进行自动发布。

#### 发布流程

1. **更新版本号**：使用 `bump-version.js` 脚本更新版本号
   ```bash
   # 可选参数：patch (默认), minor, major, prerelease
   pnpm run bump:patch
   ```

2. **推送代码和标签**：
   ```bash
   git push && git push --tags
   ```

3. **自动发布**：GitHub Actions 将自动触发发布流程：
   - 执行质量检查
   - 构建项目
   - 使用 Trusted Publishing 发布到 npm
   - 创建 GitHub Release

#### 发布配置

- **Trusted Publishing**：通过 OIDC 令牌进行身份验证，无需持久化的 npm 令牌
- **自动触发**：仅在标签推送时触发发布
- **安全可靠**：使用 GitHub Actions 安全上下文

## 贡献

欢迎贡献代码！请遵循以下步骤：

1. Fork 本仓库
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 创建 Pull Request

## 许可证

本项目基于 MIT 许可证开源 - 查看 [LICENSE](LICENSE) 文件了解详情。

## 作者

- **planarcat** - [GitHub](https://github.com/planarcat)

## 更新日志

### v1.7.13

- ✨ 重构了 `decimalPlaces` 参数类型，使用 `DecimalPlacesOptions` 联合类型
- ✨ 新增 `DecimalPlacesOptions` 对象，包含 `RETAIN_ALL` 常量用于保留所有小数位
- ✨ 优化了类型定义，提高了类型安全性
- ✨ 更新了文档，添加了 `DecimalPlacesOptions` 的使用示例

### v1.7.12

- ✨ 修复了构建错误，解决了合并声明问题

### v1.7.1

- ✨ 修复了 `formatDate` 函数中 Unix 时间戳计算问题，确保基于 UTC 时间
- ✨ 统一了 regular 和 compile 两种模式下的时间戳计算逻辑
- ✨ 修复了测试用例中的时间戳期望值，确保跨时区测试通过
- ✨ 优化了项目依赖管理，迁移到 pnpm 包管理器
- ✨ 新增了自动化发布流程，支持 GitHub Actions 自动发布到 npm
- ✨ 添加了 API 文档自动部署到 GitHub Pages 的功能

### v1.7.0

- ✨ 优化日期格式化功能，移除了 `dddd` 和 `ddd` 标记
- ✨ 使用 `dd` 标记显示完整星期名称（周一、Monday）
- ✨ 新增自定义周名称映射功能，支持：
  - 数组格式：`['星期日', '星期一', ...]`
  - 完整映射：`{ zh: ['周日', ...], en: ['Sun', ...] }`
- ✨ 支持自动模式检测，根据调用频率自动切换普通/编译模式
- ✨ 优化编译模式性能，使用 LRU 缓存存储编译后的格式化函数
- ✨ 修复了模板字符串嵌套错误和类型安全问题

### v1.6.0

- ✨ 增强了日期格式化功能，支持更多格式化标记
- ✨ 新增月份相关标记：`MMMM`（完整月份名称）、`MMM`（月份缩写）
- ✨ 新增日期相关标记：`DDD`（一年中的第几天）、`Do`（带序数词的日期）
- ✨ 新增时间相关标记：`S`（单个毫秒）
- ✨ 新增星期相关标记：`dddd`（完整星期名称）、`ddd`（星期缩写）
- ✨ 新增时间戳相关标记：`X`（Unix时间戳秒）、`x`（Unix时间戳毫秒）
- ✨ 优化了文档结构，添加了完整的格式化标记参考
- ✨ 完善了测试用例，覆盖所有新功能

### v1.5.6

- ✨ 优化了 `toFormattedNumberString` 函数的内部实现，将内部函数提取到外部
- ✨ 统一了变量命名规范，根据转化进度命名：converted、preProcessed、formatted
- ✨ 新增测试用例，验证预处理函数和后缀函数的组合使用
- ✨ 提高了代码的可读性和可维护性

### v1.5.5

- ✨ 修复了测试文件中的未使用变量警告
- ✨ 优化了代码注释，删除了重复的不必要说明
- ✨ 提高了代码的简洁性和可维护性

### v1.5.3

- ✨ 增强了 `toFormattedNumberString` 函数，为 `preProcessor`、`prefix` 和 `suffix` 函数更新了参数顺序
- ✨ `preProcessor` 现在接收两个参数：原始对象和转化后的 number
- ✨ `prefix` 如果是函数，现在接收三个参数：原始对象、转化后的 number、格式化后的字符串
- ✨ `suffix` 如果是函数，现在接收三个参数：原始对象、转化后的 number、格式化后的字符串
- ✨ 增强了测试用例，验证新功能
- ✨ 更新了文档，明确说明每个函数参数的用途

### v1.5.2

- ✨ 更新了函数返回值类型说明，明确区分数组和非数组输入的返回值
- ✨ 生成了最新的 API 文档

### v1.5.1

- ✨ 更新了 README 文档，修复了参数名称
- ✨ 生成了最新的 API 文档

### v1.5.0

- ✨ 为 `toFormattedNumberString` 函数的前缀后缀添加函数类型支持
- ✨ 修复 0 值、NaN 值和无数字字符串的前缀后缀处理问题
- ✨ 完善文档和测试用例，确保覆盖所有功能
- ✨ 优化项目规则文件结构，采用分层管理

### v1.4.0

- ✨ 优化数字格式化功能，无数字字符串返回 `0` 而不是 `NaN`
- ✨ 改进 `toFormattedNumberString` 函数，无数字字符串直接返回 `zeroValue`
- ✨ 完善文档和测试用例
- ✨ 优化深层数组处理逻辑

### v1.3.0

- ✨ 添加数字格式化功能 `toFormattedNumber`
- ✨ 支持处理任意输入类型（number、string、array、deep array）
- ✨ 支持自定义小数位数和 NaN 显示
- ✨ 支持深层数组递归处理
- ✨ 完善的类型定义和 JSDoc 注释
- ✨ 新增 object 分类目录结构

### v1.2.0

- ✨ 优化日期格式化功能，支持使用 `dd` 标记直接显示周几
- ✨ 改进文档系统，使用 TypeDoc 自动生成模块化文档
- ✨ 优化代码结构和类型定义

### v1.1.0

- ✨ 添加函数防抖功能 `debounce`
- ✨ 支持防抖取消功能 `cancel`
- ✨ 完善类型定义
- ✨ 添加防抖函数测试用例

### v1.0.0

- ✨ 初始版本发布
- ✨ 实现日期格式化功能 `formatDate`
- ✨ 完整的 TypeScript 类型支持
- ✨ 单元测试覆盖
- ✨ 构建和发布配置
