npm package: @irim/bin-tool
Description: node bin tools
Author: Pluto
Latest version: 1.2.0

# bin-tool

![version](https://img.shields.io/npm/v/@irim/bin-tool)
![license](https://img.shields.io/npm/l/@irim/bin-tool)
![downloads](https://img.shields.io/npm/dw/@irim/bin-tool)

node bin 的一些必要的工具方法集

## Getting Started

- `$ npm install @irim/bin-tool --save`

## API

### utils.ts 基础方法

#### 1. `logger(...args)` 同 console.log

#### 2. `print(type, msg)` print console log

```ts
/**
 * @param type 日志类型
 * @param msg 日志内容
 */
function print(type: 'debug'|'info'|'success'|'warn'|'error', msg: string): void;
```

#### 3. `printJSON(json)` 打印一个简单的 JSON

#### 4. `parseProperties(file)` 解析 .properties 文件，返回一个 JSON

```ts
/**
 * @param file 文件地址
 */
export async function parseProperties(file: string): Promise<any>;
```

#### 5. `getProgressStr(recent, total, label)` 返回一个进度条 string

```ts
/**
 * @param recent 当前进度
 * @param total 总量
 * @param label 前缀文字
 */
function getProgressStr(recent: number, total?: number, label?: string): string;
```

#### 6. `sleep(millseconds): Promise<void>` 睡眠 xx 毫秒

#### 7. `parseValue(data, key)` 从对象中解析出 key 的值

#### 8. `templateRender(tpl, data): string` 简单的模板渲染，使用 `{{xxx}}` 表示变量


### files.ts 文件相关的方法

#### 1. `fileIterator(...)` 遍历文件目录，执行 callback

```ts
/**
 * @param src 目录路径
 * @param fileCallback 执行到文件时的回调
 * @param dirCallback 执行到目录时的回调
 * @param exclude 忽略的文件
 */
function fileIterator(
  src: string,
  fileCallback: (filePath: string, fileRelativePath: string) => any,
  dirCallback?: (dirRelativePath: string) => any,
  exclude?: RegExp,
): Promise<any>;
```

#### 2. `dirSyncIterator(...)` 遍历文件目录，同步到目标目录，并对每一个文件执行 callback

```ts
/**
 * @param source 源文件目录
 * @param target 目标目录
 * @param callback
 * @param exclude 忽略的文件规则
 */
function dirSyncIterator(
  source: string,
  target: string,
  callback: (sourceFile: string, targetFile: string) => any,
  exclude?: RegExp
): Promise<any>;
```

#### 3. `getFileCount(src, exclude)` 统计目录中的文件数量

```ts
/**
 * @param src 目录路径
 * @param exclude 忽略的文件
 */
function getFileCount(src: string, exclude?: RegExp): Promise<number>
```

#### 4. `copyDir(options)` 复制文件目录

```ts
interface OptionShape {
  /** 文件来源目录 */
  src: string;
  /** 目标目录 */
  dist: string;
  /** 文件内容替换规则  */
  replacer?: { holder: RegExp; value: string }[];
  /** 忽略的文件 */
  exclude?: RegExp;
  /** 只读文件（不读取&替换的文件） */
  readonlyFile?: RegExp;
  /** 文件名替换方法 */
  fileNameTransfer?: (name: string) => string;
  /** 文件内容格式化方法 */
  contentFormatter?: (content: string, src: string) => Promise<string>;
}

const defaultOptions: OptionShape = {
  exclude: /node_modules\/|build\/|\.DS_Store\/|\.idea\/|\.paiconfig|\.git\/|\.bak/,
  readonlyFile: /\.(png|jpe?g|gif|svg|obj|mtl|geojson|gltf|mp4|min\.js|min\.css)$/,
  fileNameTransfer: (name: string) => name.replace(/^__/, '.').replace(/^_/, ''),
};

async function copyDir(options: OptionShape): Promise<any>
```

#### 5. `clearDir(options)` 清除文件目录

```ts
export interface ClearOptions {
  /** 要清除的目录 */
  src: string;
  /** 是否有二次确认 */
  confirm?: boolean;
  /** 二次确认文案 */
  confirmText?: string;
  /** 忽略的文件 */
  exclude?: RegExp;
}

const defaultClearOptions: ClearOptions = {
  confirm: true,
  confirmText: '请确认要清空的目录: {{src}}',
};

async function copyDir(options: OptionShape): Promise<any>
```

#### 6. `findInFolder(src, callback, options)` 查找内容符合条件的文件

```ts
export async function findInFolder(
  // 文件目录
  src: string,
  // 文件校验规则，传入参数是文件的内容
  callback: (filePath: string, content: string) => boolean,
  options: {
    /** 是否找到所有文件，默认 false，即找到第 1 个就返回 */
    all?: boolean;
    /** 如果指定了 include，则只处理匹配的文件 */
    include?: RegExp;
    /** 匹配规则的文件跳过 */
    exclude?: RegExp;
    /** 文件大小限制(byte)，超过大小的文件不遍历 */
    limit?: number;
    /** 读取文件的编码，默认是 utf-8 */
    encoding?: BufferEncoding;
  } = {}
): Promise<{
  filePath: string;
  fileRelativePath: string;
  fileSize: number;
}[]>
```

### inquirer 相关的方法封装

#### 1. `confirm(message, defaultValue)` node 控制台二次确认

```ts
/**
 * @param message 提示信息
 * @param defaultValue 默认值
 * @example
 * const isUpdate = await confirm('请确认是否要升级？');
 */
function confirm(message: string, defaultValue = false): Promise<boolean>;
```

#### 2. `prompt(...)` node 控制台用户输入

```ts
/**
 * @param message 提示信息
 * @param defaultValue 默认值
 * @example
 * const username = await prompt('请输入用户名：');
 */
function prompt(message: string, defaultValue = ''): Promise<string>;
```

### 3. `select(...)` node 控制台用户选择

```ts
/**
 * @param message 提示信息
 * @param options 选项
 * @param defaultValue 默认值或默认的选项 index
 * @example
 * const value = await select('请选择性别: ', ['男', '女']);
 */
function select(
  message: string,
  options: SelectOptions[] | string[],
  defaultValue: string | number
): Promise<string>;
```

### 4. `holding(tips: string)` 中断操作，等待用户回车继续

```ts
await holding('确认后，请按回车继续...');
```

## CHANGELOG

<!-- - **version**: change logs -->
- **1.0.0** 发布最初版本，完成基本功能集
- **1.1.0** 修改 `getProgressStr` 参数，新增 `clearDir`, `parseValue`, `templateRender` 等方法
- **1.1.2** 新增 `input`, `password`, `holding` 交互方法
- **1.2.0** 新增 `findInFolder` 方法

## TODO 

- add jest framework and test case.

## LICENSE

BSD-3-Clause License

## Contact Us

[Pluto](mailto:huarse@gmail.com)