Files
mr.koi 454e6c51d7 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.
2026-07-31 16:47:39 +08:00

373 lines
10 KiB
Markdown

# koi_swagger_parser
[English](README.md) | [Chinese (Simplified)](README.zh-CN.md)
`koi_swagger_parser` is an OpenAPI 3.0/3.1 Dart and Flutter client generator
for projects that use Dio, Retrofit, Freezed, and json_serializable. It
separates document loading, `$ref` resolution, validation, an intermediate
representation (IR), rendering, and safe incremental writes.
Generated code follows a Koi-oriented layout:
```text
lib/src/
api/
api_client.dart
index.dart
v1/
index.dart
stores_api.dart
api_models/
api_models.dart
request/
result/
shared/
enums/
```
## Features
- Local JSON/YAML files, HTTP(S) documents, multiple root documents, and
local, relative, file, and remote `$ref` values.
- Component reference resolution, caching, cycle detection, deterministic
conflict handling, and dependency tracking.
- Retrofit APIs and Freezed/json_serializable request, response, shared,
enum, and union models.
- `enum_mappings`, legacy `enum_key_mappings`, `x-enumNames`,
`x-enum-varnames`, `x-enum-values`, descriptions, and optional unknown enum
fallback.
- Model, property, parameter, operation, schema, type, and import mappings
with collision diagnostics.
- OpenAPI path, query, header, and cookie parameters, including supported
style, explode, and `allowReserved` combinations.
- JSON, text, multipart, form-urlencoded, and binary requests; byte and
stream downloads.
- Multiple successful responses, 204, `2XX`, `default` and error responses,
response headers, and optional `HttpResponse<T>` results.
- Required, nullable, and absent-value semantics; read-only/write-only
projections; `additionalProperties`; `allOf`; and supported `oneOf`/`anyOf`
forms.
- Server variables and security metadata. Credentials remain the
responsibility of the host application's Dio interceptor or provider.
- Exact, glob, and regular-expression filters.
- A locked manifest, SHA-256 change detection, safe stale-file cleanup,
atomic writes, dry runs, and optional build_runner integration.
See the [compatibility matrix](doc/COMPATIBILITY.md) for precise boundaries.
## Requirements
- Dart SDK `^3.11.0`.
- An OpenAPI 3.0.x or 3.1.x document in JSON or YAML.
- A host Dart or Flutter project configured for Retrofit, Freezed, and
json_serializable when generating both APIs and models.
## Installation
Add the generator as a development dependency in the host project:
```bash
dart pub add --dev koi_swagger_parser
```
For a typical generated client, add these host runtime dependencies:
```bash
dart pub add dio retrofit freezed_annotation json_annotation
```
Add the matching code-generation tools:
```bash
dart pub add --dev build_runner retrofit_generator freezed json_serializable
```
For Flutter projects, use `flutter pub add` in place of `dart pub add` if that
is how the project manages dependencies.
## Quick start
1. Copy [the complete configuration template](koi_swagger_parser.example.yaml)
to `koi_swagger_parser.yaml` in the host project.
2. Set at least one OpenAPI source and the output directories:
```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. Preview the change set:
```bash
dart run koi_swagger_parser generate --all --dry-run
```
4. Generate the client:
```bash
dart run koi_swagger_parser generate --all
```
When `formatting.run_build_runner` is `false`, run build_runner separately:
```bash
dart run build_runner build --delete-conflicting-outputs
```
## CLI usage
```text
dart run koi_swagger_parser generate [options]
--all, -a Generate all enabled resources. Kept for command compatibility.
--config, -c Configuration file path.
--cwd Host project working directory.
--dry-run Parse and render without writing or deleting files.
--watch Start build_runner watch after generation.
--verbose, -v Print informational diagnostics and failure stack traces.
```
The loader searches the working directory for, in order:
1. `koi_swagger_parser.yaml`
2. `koi_swagger_parser.yml`
3. `generator_config.yaml`
4. `generator_config.yml`
When `--config` points to a file outside the current directory and `--cwd` is
not set, the configuration directory becomes the host project working
directory. Relative sources and output paths are resolved against the
configuration directory. `--cwd` changes where host-project commands run; it
does not change those path semantics.
## Library usage
The same pipeline is available as a 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());
}
}
```
On diagnostic errors, generation throws `KoiDiagnosticException`. Automation
should match diagnostic `code` values instead of message text. See
[Diagnostics](doc/DIAGNOSTICS.md).
## Enum mappings
Enum wire values can be mapped to stable Dart member names in configuration:
```yaml
generation:
models:
enum_unknown_fallback: true
enum_mappings:
OrderStatus:
- value: pending
name: waitingForPayment
description: Waiting for payment
- value: done
name: completed
description: Completed
```
Map syntax is also accepted:
```yaml
generation:
models:
enum_mappings:
OrderStatus:
pending: waitingForPayment
done:
name: completed
description: Completed
```
The legacy `enum_key_mappings` field remains supported. Name resolution uses
this precedence:
1. `enum_mappings`
2. `enum_key_mappings`
3. `x-enumNames`, `x-enum-names`, or `x-enum-varnames`
4. `x-enum-values`
5. A name derived from the wire value
Descriptions use configuration first, then `x-enumDescriptions`,
`x-enum-descriptions`, and `x-enum-values.description`. With
`enum_unknown_fallback: true`, the generator adds a stable `unknown` member
and applies `JsonKey.unknownEnumValue` to enum references.
## Naming and type mappings
```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 mapping keys accept either an `operationId` or `METHOD /path`.
Schema mappings mark a schema as externally implemented, so no model is
generated for it. The external type must provide the JSON conversion behavior
required by its generated usage.
## Responses and transport
```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
```
When Retrofit annotations cannot represent a supported matrix, label, cookie,
deep-object, or reserved-character parameter, the generator emits a typed
transport adapter in front of a private Retrofit delegate. A `default`
response is always treated as an error response.
## Filtering and lifecycle
```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
```
Filters accept exact values, `*`, `?`, and `**` globs, or Dart regular
expressions prefixed with `regex:`. Exclusions take precedence over
inclusions. `included_models` can add otherwise unreferenced components as
generation roots.
The manifest records only files owned by this generator. Stale cleanup removes
an old generated file only when it is still inside the configured API/model
roots and its content still matches the previous manifest hash. Modified files
and handwritten neighbors are preserved.
## Limitations
The current release intentionally does not generate:
- Swagger/OpenAPI 2.0 clients.
- Callbacks, webhooks, or Link Object call chains.
- XML, Protobuf, or arbitrary custom codecs.
- A complete JSON Schema 2020-12 implementation.
- Server stubs, mock servers, or non-Dart targets.
- A pluggable external renderer/template API.
Unsupported or lossy constructs produce structured warnings or errors; they
are not silently presented as fully supported. Consult
[Compatibility](doc/COMPATIBILITY.md) before adopting the generator for a new
schema corpus.
## Documentation
- [Configuration reference](doc/CONFIGURATION.md)
- [Compatibility matrix](doc/COMPATIBILITY.md)
- [Diagnostics reference](doc/DIAGNOSTICS.md)
- [Architecture](doc/ARCHITECTURE.md)
- [Migration from swagger_generator_flutter](doc/MIGRATION.md)
- [Changelog](CHANGELOG.md)
## Development
```bash
dart pub get
dart format .
dart analyze
dart test
dart run tool/verify_generated_package.dart
```
The final command creates a temporary Dart package, invokes this generator and
its build_runner integration, and then runs analysis and runtime tests in the
generated package.
## Support and contributing
Use [GitHub Issues](https://github.com/mrkoi-is/koi_swagger_parser/issues) for
reproducible bug reports and feature requests. Include the generator version,
Dart version, a minimal OpenAPI document, the relevant configuration, and
diagnostic codes. Remove credentials and private service data before sharing a
reproduction.
Contributions should include focused tests and update the compatibility matrix
and configuration reference when behavior changes. Run the development checks
above before opening a pull request.
## License
[MIT](LICENSE)