# json2dart-generator

JSON 转 Dart Model 类命令行工具。将目录中的 JSON 文件批量转换为 Dart 数据类，支持嵌套类型推导、空安全、数字类型控制、Mock 数据生成等能力。

---

## 安装

```bash
npm install json2dart-generator -g
```

## 快速开始

```bash
# 将 .json_models/ 下的 JSON 转换为 lib/models/ 下的 Dart 文件
json2dart --dir .json_models -o lib/models --nullsafety

# 启用 Mock 数据生成
json2dart --dir .json_models -o lib/models --nullsafety --mock
```

## 命令行选项

| 选项 | 默认值 | 说明 |
|---|---|---|
| `-d, --dir <dir>` | `.json_models/` | JSON 源文件目录路径 |
| `-o, --output <dir>` | `lib/models` | Dart 文件输出目录 |
| `-s, --suffix <value>` | `""` | 类名后缀，如 `Entity` |
| `-e, --excludes <value...>` | `[]` | 排除的文件(夹)，可指定多个 |
| `--numparse` | `false` | 使用 `num` 替换 `double/int` |
| `--nullsafety` | `false` | 生成空安全 Dart 代码 |
| `--mock` | `false` | 生成 Mock 数据类和 dio拦截器 |

## 特性

- **自动命名** — 文件名即类名；可通过 JSON 键 `__className` 自定义类名
- **驼峰转换** — 蛇形字段名自动转驼峰；遇 Dart 关键字时加 `the` 前缀
- **类型推导** — 嵌套对象自动生成子类；空值字段按 `dynamic` 处理并输出警告
- **类型安全** — 支持 `--nullsafety` 空安全模式和 `--numparse` 数字类型控制
- **Mock 数据** — 开启 `--mock` 后额外生成 `mock.dart` 和 `mock_handler.dart`，提供开箱即用的随机数据与 Dio 拦截器

## 输入输出示例

### 输入：`test.json`

```json
{
  "id": "467366309705273344",
  "parentId": "0",
  "name": "简体中文",
  "value": "CN",
  "codes": ["cn", "zh_cn", "zhCN"],
  "data": {
    "dicCode": "cn",
    "defaultValue": "简体中文",
    "groupId": "489361103152003",
    "dicLevel": 9.1,
    "dicValue2": "",
    "appId": "469798084878991360",
    "showOrder": 1,
    "dicName": "简体中文"
  }
}
```

### 输出：`test.dart`

```dart
class Test {
  String? id;
  String? parentId;
  String? name;
  String? value;
  List<String?>? codes;
  TestData? data;

  Test({this.id, this.parentId, this.name, this.value, this.codes, this.data});
  Test.fromJson(Map<String, dynamic> json) {
    id = json['id']?.toString();
    parentId = json['parentId']?.toString();
    name = json['name']?.toString();
    value = json['value']?.toString();
    codes = (json['codes'] != null && json['codes'] is List)
        ? json['codes'].map((e) => e?.toString())?.toList()
        : null;
    data = (json['data'] != null && json['data'] is Map<String, dynamic>)
        ? TestData.fromJson(json['data'])
        : null;
  }
  Map<String, dynamic> toJson() => {
        'id': id,
        'parentId': parentId,
        'name': name,
        'value': value,
        'codes': codes?.map((e) => e)?.toList(),
        'data': data?.toJson(),
      };
}

class TestData {
  String? dicCode;
  String? defaultValue;
  String? groupId;
  double? dicLevel;
  String? dicValue2;
  String? appId;
  int? showOrder;
  String? dicName;

  TestData({this.dicCode, this.defaultValue, this.groupId, this.dicLevel, this.dicValue2, this.appId, this.showOrder, this.dicName});
  TestData.fromJson(Map<String, dynamic> json) {
    dicCode = json['dicCode']?.toString();
    defaultValue = json['defaultValue']?.toString();
    groupId = json['groupId']?.toString();
    dicLevel = double.tryParse(json['dicLevel']?.toString() ?? '');
    dicValue2 = json['dicValue2']?.toString();
    appId = json['appId']?.toString();
    showOrder = int.tryParse(json['showOrder']?.toString() ?? '');
    dicName = json['dicName']?.toString();
  }
  Map<String, dynamic> toJson() => {
        'dicCode': dicCode,
        'defaultValue': defaultValue,
        'groupId': groupId,
        'dicLevel': dicLevel,
        'dicValue2': dicValue2,
        'appId': appId,
        'showOrder': showOrder,
        'dicName': dicName,
      };
}
```

## Mock 数据生成

启用 `--mock` 后，工具会额外生成两个文件：

### `mock.dart`

`Mock` 类为每个 JSON 文件生成对应的数据工厂方法：

```dart
// 获取单条随机数据
final data = Mock.test();

// 获取多条数据
final list = Mock.list(10, () => Mock.test());
```

### `mock_handler.dart`

`MockHandler` 是基于 Dio 的请求拦截器，注册后自动拦截请求并返回 Mock 数据：

```dart
// 绑定到 Dio 实例
final dio = Dio();
dio.interceptors.add(MockHandler());

// 注册 Mock 规则
MockHandler.register(RegExp('/api/.*'), (options) async {
  return Mock.test();
});
```
