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:
@@ -0,0 +1,150 @@
|
||||
# 诊断
|
||||
|
||||
[English](../DIAGNOSTICS.md) | [简体中文](DIAGNOSTICS.md)
|
||||
|
||||
配置、加载、解析、渲染和生命周期问题统一表示为 `KoiDiagnostic`:
|
||||
|
||||
```dart
|
||||
class KoiDiagnostic {
|
||||
final String code;
|
||||
final DiagnosticSeverity severity; // info | warning | error
|
||||
final String message;
|
||||
final String? source;
|
||||
final String? location;
|
||||
}
|
||||
```
|
||||
|
||||
`code` 是稳定的机器可读标识;message 文案可能随版本改进。`source` 表示配置
|
||||
路径、文档 URL/文件或生成文件;`location` 通常是 source 内的 JSONPath、
|
||||
JSON Pointer 或其他逻辑位置。
|
||||
|
||||
## Severity 行为
|
||||
|
||||
- `info`:正常决策,例如跳过未变化的生成;
|
||||
- `warning`:输出仍然可靠,但发生改名、安全降级或明确省略的非阻塞能力;
|
||||
- `error`:继续执行可能产生无效客户端,生成器抛出
|
||||
`KoiDiagnosticException`。
|
||||
|
||||
CLI 默认输出 warning/error;`--verbose` 还会输出 info 和失败堆栈。
|
||||
|
||||
library 调用方可检查诊断:
|
||||
|
||||
```dart
|
||||
try {
|
||||
final result = await const KoiSwaggerParser().generate();
|
||||
for (final item in result.diagnostics) {
|
||||
print(item.format());
|
||||
}
|
||||
} on KoiDiagnosticException catch (error) {
|
||||
for (final item in error.diagnostics) {
|
||||
print(item.format());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
自动化应匹配 `code`,不要匹配 message 文本。需要区分上下文时再断言 `source`
|
||||
或 `location`。
|
||||
|
||||
## 常见 code
|
||||
|
||||
### 配置
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `config.missing_sources` | 添加至少一个启用的 `input.swagger_urls`。 |
|
||||
| `config.unknown_key` | 修正拼写或删除当前版本不认识的字段;warning。 |
|
||||
| `config.invalid_section` | 把 scalar/list 改成预期 YAML map。 |
|
||||
| `config.invalid_string` / `config.invalid_boolean` | 修正 YAML scalar 类型。 |
|
||||
| `config.invalid_string_list` | include/exclude filter 必须是字符串列表。 |
|
||||
| `config.invalid_filter_regex` | 修正 `regex:` 后的 Dart 表达式。 |
|
||||
| `config.no_outputs_enabled` | API/model 不能同时关闭。 |
|
||||
| `config.api_requires_models` | 当前 API renderer 依赖生成 model。 |
|
||||
| `config.unsupported_api_renderer` | 保持 `use_retrofit: true`;目前没有其他公开 API renderer。 |
|
||||
| `config.external_wrapper_import_required` | 添加 `external_generic.import`。 |
|
||||
| `config.mapping_target_collision` | 为 mapping source 设置不同的 Dart 目标名。 |
|
||||
| `config.import_mapping_conflict` | 同一映射 Dart 类型只能使用一个 import。 |
|
||||
| `config.conflicting_schema_mapping` | 同一 schema 不能既重命名又由外部类型替换。 |
|
||||
| `config.ambiguous_enum_mapping` | 使用类型明确、无歧义的 enum wire value。 |
|
||||
|
||||
### 文档与引用
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `openapi.missing_version` / `openapi.unsupported_version` | 提供 OpenAPI 3.0.x/3.1.x 文档。 |
|
||||
| `openapi.invalid_info` / `openapi.invalid_paths` | 修正文档对应关键结构。 |
|
||||
| `openapi.source_load_failed` / `openapi.source_http_error` | 检查文件路径、URL、访问权限和响应状态。 |
|
||||
| `openapi.unresolved_ref` | 本地 JSON Pointer 不存在。 |
|
||||
| `openapi.unresolved_external_ref` | 外部资源/fragment 不存在或无法加载。 |
|
||||
| `openapi.external_ref_not_bundled` | ref 归一化失败;检查前序 source/resolver 诊断。 |
|
||||
| `openapi.external_component_renamed` | 外部 component 冲突已确定性改名;warning。 |
|
||||
| `openapi.multisource_component_renamed` | root 间 component 冲突已确定性改名;warning。 |
|
||||
| `openapi.multisource_operation_conflict` | 两个 root 定义相同 method/path;删除或拆分其中一个。 |
|
||||
| `openapi.callbacks_not_supported` / `openapi.webhooks_not_supported` | 不生成反向调用 client;warning。 |
|
||||
| `openapi.links_not_supported` | 不生成 Link Object 调用关系;warning。 |
|
||||
|
||||
### Parameter、request 与 response
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `openapi.invalid_parameter_style` | 使用与 parameter location 匹配的 style。 |
|
||||
| `openapi.deep_object_requires_object` | deepObject parameter 必须使用 object schema。 |
|
||||
| `openapi.delimited_parameter_requires_array` | space/pipe-delimited parameter 必须使用 array schema。 |
|
||||
| `openapi.parameter_content_count` | Parameter Object `content` 必须恰有一个 media type。 |
|
||||
| `openapi.request_body_schema_missing` | 为选中的 request media type 添加 schema。 |
|
||||
| `openapi.unsupported_request_content_type` | 使用已支持 request codec 或手写 endpoint。 |
|
||||
| `openapi.unsupported_response_content_type` | 使用已支持 response codec 或手写 endpoint。 |
|
||||
| `openapi.success_response_missing` | 添加显式 2xx response;`default` 不是 success。 |
|
||||
| `openapi.multiple_success_response_types` | 多个成功 JSON body type 统一为 `Object?`;warning。 |
|
||||
| `openapi.mixed_success_media_types` | 单个生成方法无法安全 decode binary/stream + JSON success。 |
|
||||
| `openapi.path_parameter_forced_required` | 声明为 optional 的 path parameter 被强制为 required;warning。 |
|
||||
|
||||
### Schema 与命名
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `openapi.property_read_write_only` | property 不能同时 read-only/write-only。 |
|
||||
| `openapi.invalid_additional_properties` | 使用 boolean 或 Schema Object。 |
|
||||
| `openapi.property_name_collision` | 自动 suffix 避免了 Dart field collision;warning。 |
|
||||
| `openapi.operation_name_collision` | 自动 suffix 避免了 method collision;warning。 |
|
||||
| `openapi.operation_argument_name_collision` | parameter 与 body、cancel token 或其他参数冲突。 |
|
||||
| `openapi.duplicate_enum_member_name` | 多个 wire value 映射到同名,已添加 suffix。 |
|
||||
| `openapi.enum_member_name_sanitized` | enum member name 已转换为合法 Dart identifier。 |
|
||||
| `filter.required_model_excluded` | 选中 API 依赖被排除 model;包含该 model 或排除调用方。 |
|
||||
| `filter.model_pattern_unmatched` | `included_models` pattern 没有匹配 schema。 |
|
||||
|
||||
### Server 与 security
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `openapi.server_url_missing` | 添加非空 server URL。 |
|
||||
| `openapi.server_variable_default_missing` | 为每个 server variable 提供 default。 |
|
||||
| `openapi.server_variable_default_invalid` | 让 default 属于声明的 enum value。 |
|
||||
| `openapi.server_variable_unresolved` | 定义 server URL 中的每个 variable。 |
|
||||
| `openapi.unknown_security_scheme` | 在 components 中定义被引用 scheme。 |
|
||||
| `openapi.unsupported_security_scheme` | scheme 只在文档边界内保留或被拒绝。 |
|
||||
| `openapi.http_auth_requires_custom_interceptor` | 在宿主 Dio 层实现凭证注入;warning。 |
|
||||
|
||||
### 生成生命周期
|
||||
|
||||
| Code | 含义和处理 |
|
||||
|---|---|
|
||||
| `lifecycle.unchanged_skipped` | hash/file 一致,已安全跳过生成。 |
|
||||
| `lifecycle.manifest_invalid` | 旧 manifest 损坏;重建输出但不信任其删除列表。 |
|
||||
| `lifecycle.manifest_version_ignored` | manifest schema 不兼容,其删除列表被忽略。 |
|
||||
| `lifecycle.output_outside_managed_roots` | renderer 输出越过 API/model 根,已拒绝。 |
|
||||
| `lifecycle.duplicate_output_path` | 两个渲染文件以不同内容指向同一路径。 |
|
||||
| `lifecycle.stale_path_outside_roots` | 旧路径位于当前 root 外,因此保留。 |
|
||||
| `lifecycle.stale_file_modified` | stale 生成文件已被编辑,保留供人工处理。 |
|
||||
| `lifecycle.generated_file_missing` | 主生成文件在 fix/format/build 期间消失。 |
|
||||
| `lifecycle.control_file_not_stale` | lifecycle 控制文件永不作为 stale 输出处理。 |
|
||||
|
||||
## 设计原则
|
||||
|
||||
1. unresolved ref、非法 wire style 和不支持 codec 不会静默变成 `dynamic`;
|
||||
2. 安全且可编译的自动改名可以 warning 后继续;
|
||||
3. 不会破坏其他输出的不支持结构会 warning 后明确省略;
|
||||
4. stale cleanup 在 path containment 或 hash ownership 不确定时保留文件;
|
||||
5. 可用时诊断会带 component、operation、parameter 或文件上下文。
|
||||
|
||||
minor release 可以增加新 code。自动化应把未知 warning 视为需复核,把未知 error
|
||||
视为阻塞。
|
||||
Reference in New Issue
Block a user