Release 0.2.0
Complete OpenAPI 3.0/3.1 generation, diagnostics, lifecycle safety, enum and naming mappings, bilingual documentation, examples, and pub.dev release validation.
This commit is contained in:
+350
@@ -0,0 +1,350 @@
|
||||
# koi_swagger_parser
|
||||
|
||||
[English](README.md) | [简体中文](README.zh-CN.md)
|
||||
|
||||
`koi_swagger_parser` 是面向 Dio、Retrofit、Freezed 和
|
||||
json_serializable 项目的 OpenAPI 3.0/3.1 Dart/Flutter 客户端生成器。它将文档
|
||||
加载、`$ref` 解析、校验、中间表示(IR)、渲染和安全的增量写入相互分离。
|
||||
|
||||
生成代码采用面向 Koi 项目的目录结构:
|
||||
|
||||
```text
|
||||
lib/src/
|
||||
api/
|
||||
api_client.dart
|
||||
index.dart
|
||||
v1/
|
||||
index.dart
|
||||
stores_api.dart
|
||||
api_models/
|
||||
api_models.dart
|
||||
request/
|
||||
result/
|
||||
shared/
|
||||
enums/
|
||||
```
|
||||
|
||||
## 功能
|
||||
|
||||
- 本地 JSON/YAML、HTTP(S)、多个根文档,以及本地、相对、file 和远程 `$ref`;
|
||||
- component 引用解析、缓存、循环检测、确定性冲突处理和依赖追踪;
|
||||
- Retrofit API,以及 Freezed/json_serializable 请求、响应、共享、枚举和联合模型;
|
||||
- `enum_mappings`、兼容字段 `enum_key_mappings`、`x-enumNames`、
|
||||
`x-enum-varnames`、`x-enum-values`、描述和可选 unknown enum fallback;
|
||||
- model、property、parameter、operation、schema、type 和 import 映射及冲突诊断;
|
||||
- OpenAPI path、query、header 和 cookie 参数,包括已支持的 style、explode 和
|
||||
`allowReserved` 组合;
|
||||
- JSON、text、multipart、form-urlencoded 和 binary 请求,以及 bytes/stream 下载;
|
||||
- 多个成功响应、204、`2XX`、`default`、错误响应、响应头和可选
|
||||
`HttpResponse<T>` 返回值;
|
||||
- required、nullable、absent 语义,readOnly/writeOnly 投影,
|
||||
`additionalProperties`、`allOf` 和已支持的 `oneOf`/`anyOf`;
|
||||
- server variables 和 security metadata;凭证仍由宿主应用的 Dio interceptor
|
||||
或 provider 注入;
|
||||
- 精确、glob 和正则过滤;
|
||||
- 带文件锁的 manifest、SHA-256 变更检测、安全 stale cleanup、原子写入、
|
||||
dry-run 和可选 build_runner 集成。
|
||||
|
||||
准确边界见[兼容性矩阵](doc/zh-CN/COMPATIBILITY.md)。
|
||||
|
||||
## 环境要求
|
||||
|
||||
- Dart SDK `^3.11.0`;
|
||||
- JSON 或 YAML 格式的 OpenAPI 3.0.x/3.1.x 文档;
|
||||
- 同时生成 API 和模型时,宿主 Dart/Flutter 项目需配置 Retrofit、Freezed 和
|
||||
json_serializable。
|
||||
|
||||
## 安装
|
||||
|
||||
在宿主项目中把生成器添加为开发依赖:
|
||||
|
||||
```bash
|
||||
dart pub add --dev koi_swagger_parser
|
||||
```
|
||||
|
||||
典型生成客户端需要以下宿主运行时依赖:
|
||||
|
||||
```bash
|
||||
dart pub add dio retrofit freezed_annotation json_annotation
|
||||
```
|
||||
|
||||
添加相应代码生成工具:
|
||||
|
||||
```bash
|
||||
dart pub add --dev build_runner retrofit_generator freezed json_serializable
|
||||
```
|
||||
|
||||
Flutter 项目若统一使用 Flutter 管理依赖,可把 `dart pub add` 换成
|
||||
`flutter pub add`。
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 将[完整配置模板](koi_swagger_parser.example.yaml)复制为宿主项目中的
|
||||
`koi_swagger_parser.yaml`。
|
||||
2. 至少设置一个 OpenAPI source 和输出目录:
|
||||
|
||||
```yaml
|
||||
input:
|
||||
swagger_urls:
|
||||
- url: ./openapi.json
|
||||
enabled: true
|
||||
|
||||
output:
|
||||
base_dir: ./lib/src
|
||||
api_dir: ./lib/src/api
|
||||
models_dir: ./lib/src/api_models
|
||||
|
||||
generation:
|
||||
preset:
|
||||
name: koi_flutter
|
||||
api:
|
||||
enabled: true
|
||||
use_retrofit: true
|
||||
response_wrapper:
|
||||
mode: passthrough
|
||||
models:
|
||||
enabled: true
|
||||
class_prefix: Koi
|
||||
|
||||
formatting:
|
||||
run_dart_format: true
|
||||
run_build_runner: true
|
||||
build_runner_mode: build
|
||||
```
|
||||
|
||||
3. 预览变更:
|
||||
|
||||
```bash
|
||||
dart run koi_swagger_parser generate --all --dry-run
|
||||
```
|
||||
|
||||
4. 生成客户端:
|
||||
|
||||
```bash
|
||||
dart run koi_swagger_parser generate --all
|
||||
```
|
||||
|
||||
当 `formatting.run_build_runner` 为 `false` 时,单独执行:
|
||||
|
||||
```bash
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
```
|
||||
|
||||
## CLI 用法
|
||||
|
||||
```text
|
||||
dart run koi_swagger_parser generate [options]
|
||||
|
||||
--all, -a 生成所有已启用资源;为了命令兼容而保留。
|
||||
--config, -c 配置文件路径。
|
||||
--cwd 宿主项目工作目录。
|
||||
--dry-run 完成解析和渲染,但不写入或删除文件。
|
||||
--watch 生成后启动 build_runner watch。
|
||||
--verbose, -v 显示 info 诊断和失败堆栈。
|
||||
```
|
||||
|
||||
加载器按以下顺序在工作目录中查找:
|
||||
|
||||
1. `koi_swagger_parser.yaml`
|
||||
2. `koi_swagger_parser.yml`
|
||||
3. `generator_config.yaml`
|
||||
4. `generator_config.yml`
|
||||
|
||||
当 `--config` 指向当前目录外的文件且未设置 `--cwd` 时,配置文件目录会成为宿主
|
||||
项目工作目录。相对 source 和输出路径始终以配置文件目录解析;`--cwd` 只改变
|
||||
宿主项目命令的运行位置,不改变这些路径语义。
|
||||
|
||||
## Library 用法
|
||||
|
||||
也可以通过 Dart API 使用相同流水线:
|
||||
|
||||
```dart
|
||||
import 'package:koi_swagger_parser/koi_swagger_parser.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
final result = await const KoiSwaggerParser().generate(
|
||||
configPath: 'koi_swagger_parser.yaml',
|
||||
dryRun: true,
|
||||
);
|
||||
|
||||
print('${result.operationsCount} operations');
|
||||
print('${result.modelsCount} models');
|
||||
for (final diagnostic in result.diagnostics) {
|
||||
print(diagnostic.format());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
遇到 error 诊断时会抛出 `KoiDiagnosticException`。自动化应匹配诊断 `code`,
|
||||
而不是 message 文本。详见[诊断参考](doc/zh-CN/DIAGNOSTICS.md)。
|
||||
|
||||
## Enum 映射
|
||||
|
||||
可在配置中把枚举 wire value 映射成稳定的 Dart 成员名:
|
||||
|
||||
```yaml
|
||||
generation:
|
||||
models:
|
||||
enum_unknown_fallback: true
|
||||
enum_mappings:
|
||||
OrderStatus:
|
||||
- value: pending
|
||||
name: waitingForPayment
|
||||
description: 等待付款
|
||||
- value: done
|
||||
name: completed
|
||||
description: 已完成
|
||||
```
|
||||
|
||||
也支持 map 写法:
|
||||
|
||||
```yaml
|
||||
generation:
|
||||
models:
|
||||
enum_mappings:
|
||||
OrderStatus:
|
||||
pending: waitingForPayment
|
||||
done:
|
||||
name: completed
|
||||
description: 已完成
|
||||
```
|
||||
|
||||
兼容字段 `enum_key_mappings` 仍然可用。名称解析优先级为:
|
||||
|
||||
1. `enum_mappings`
|
||||
2. `enum_key_mappings`
|
||||
3. `x-enumNames`、`x-enum-names` 或 `x-enum-varnames`
|
||||
4. `x-enum-values`
|
||||
5. 根据 wire value 自动生成的名称
|
||||
|
||||
描述优先采用配置,其次是 `x-enumDescriptions`、
|
||||
`x-enum-descriptions` 和 `x-enum-values.description`。启用
|
||||
`enum_unknown_fallback: true` 后,生成器会添加稳定的 `unknown` 成员,并在
|
||||
枚举引用上应用 `JsonKey.unknownEnumValue`。
|
||||
|
||||
## 命名与类型映射
|
||||
|
||||
```yaml
|
||||
generation:
|
||||
mappings:
|
||||
models:
|
||||
UserDto: User
|
||||
properties:
|
||||
UserDto:
|
||||
user_id: id
|
||||
parameters:
|
||||
getUser:
|
||||
user_id: id
|
||||
operations:
|
||||
getUser: fetchUser
|
||||
"DELETE /api/v1/users/{id}": removeUser
|
||||
schemas:
|
||||
Money:
|
||||
type: Money
|
||||
import: package:money2/money2.dart
|
||||
types:
|
||||
string:uuid:
|
||||
type: UuidValue
|
||||
import: package:uuid/uuid_value.dart
|
||||
integer:int64: int
|
||||
imports:
|
||||
UuidValue: package:uuid/uuid_value.dart
|
||||
```
|
||||
|
||||
operation 映射键可以是 `operationId` 或 `METHOD /path`。schema 映射表示该
|
||||
schema 由外部实现,因此不会为其生成模型。外部类型必须提供生成用法所需的
|
||||
JSON 转换能力。
|
||||
|
||||
## 响应与传输
|
||||
|
||||
```yaml
|
||||
generation:
|
||||
api:
|
||||
cancel_token_support: true
|
||||
response_mode: http_response # body | http_response
|
||||
binary_response_mode: bytes # bytes | stream
|
||||
client:
|
||||
class_name: ApiClient
|
||||
file_name: api_client
|
||||
response_wrapper:
|
||||
mode: external_generic # passthrough | external_generic
|
||||
success_data_field: data
|
||||
detect_standard_envelope: true
|
||||
external_generic:
|
||||
import: package:your_network/your_network.dart
|
||||
class_name: BaseResult
|
||||
```
|
||||
|
||||
当 Retrofit annotation 无法表达已支持的 matrix、label、cookie、deepObject
|
||||
或 reserved-character 参数时,生成器会在私有 Retrofit delegate 前生成 typed
|
||||
transport adapter。`default` response 始终被视为错误响应。
|
||||
|
||||
## 过滤与生命周期
|
||||
|
||||
```yaml
|
||||
output:
|
||||
included_tags: [stores]
|
||||
excluded_paths: [/internal/**]
|
||||
included_operations: [getStore, "POST /api/v1/stores"]
|
||||
excluded_models: [Legacy*]
|
||||
clean_stale_files: true
|
||||
skip_if_unchanged: true
|
||||
manifest_path: ./.dart_tool/koi_swagger_parser/manifest.json
|
||||
```
|
||||
|
||||
过滤器支持精确值、`*`、`?`、`**` glob,或带 `regex:` 前缀的 Dart 正则。
|
||||
exclude 优先于 include。`included_models` 可把原本未被引用的 component 加为
|
||||
生成根。
|
||||
|
||||
manifest 只记录本生成器拥有的文件。仅当旧生成文件仍位于配置的 API/model
|
||||
输出根内,且内容仍与旧 manifest hash 相同时,stale cleanup 才会删除它。
|
||||
被修改的文件及旁边的手写文件会保留。
|
||||
|
||||
## 限制
|
||||
|
||||
当前版本明确不生成:
|
||||
|
||||
- Swagger/OpenAPI 2.0 客户端;
|
||||
- callbacks、webhooks 或 Link Object 调用链;
|
||||
- XML、Protobuf 或任意自定义 codec;
|
||||
- 完整 JSON Schema 2020-12;
|
||||
- server stub、mock server 或非 Dart 目标;
|
||||
- 可由外部接入的 renderer/template API。
|
||||
|
||||
不支持或存在信息损失的结构会产生结构化 warning/error,不会静默宣称完全
|
||||
支持。为新的 schema corpus 引入本生成器前请查看[兼容性](doc/zh-CN/COMPATIBILITY.md)。
|
||||
|
||||
## 文档
|
||||
|
||||
- [配置参考](doc/zh-CN/CONFIGURATION.md)
|
||||
- [兼容性矩阵](doc/zh-CN/COMPATIBILITY.md)
|
||||
- [诊断参考](doc/zh-CN/DIAGNOSTICS.md)
|
||||
- [架构](doc/zh-CN/ARCHITECTURE.md)
|
||||
- [从 swagger_generator_flutter 迁移](doc/zh-CN/MIGRATION.md)
|
||||
- [更新日志](doc/zh-CN/CHANGELOG.md)
|
||||
|
||||
## 开发
|
||||
|
||||
```bash
|
||||
dart pub get
|
||||
dart format .
|
||||
dart analyze
|
||||
dart test
|
||||
dart run tool/verify_generated_package.dart
|
||||
```
|
||||
|
||||
最后一条命令会创建临时 Dart 包,调用本生成器及其 build_runner 集成,并在
|
||||
生成的包内执行分析和运行时测试。
|
||||
|
||||
## 支持与贡献
|
||||
|
||||
请通过 [GitHub Issues](https://github.com/mrkoi-is/koi_swagger_parser/issues)
|
||||
提交可复现的问题和功能需求。请附带生成器版本、Dart 版本、最小 OpenAPI 文档、
|
||||
相关配置和诊断 code;分享前移除凭证和私有服务数据。
|
||||
|
||||
贡献代码时应增加聚焦的测试;行为变化时同步兼容性矩阵和配置参考。提交 PR 前
|
||||
请运行上述开发检查。
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT](LICENSE)
|
||||
Reference in New Issue
Block a user