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:
mr.koi
2026-07-31 16:47:39 +08:00
parent ea93f09154
commit 454e6c51d7
56 changed files with 14506 additions and 491 deletions
+33
View File
@@ -0,0 +1,33 @@
# Koi Swagger Parser example
This directory contains a small, self-contained OpenAPI 3.0 document and two
ways to generate Dart sources from it.
## Use the Dart API
From the package root, run:
```shell
dart run example/koi_swagger_parser_example.dart
```
The program writes generated files to a temporary directory, prints a summary,
and removes the directory in a `finally` block.
## Use the command-line interface
The included configuration writes output to `example/generated`:
```shell
dart run koi_swagger_parser generate \
--config example/koi_swagger_parser.yaml
```
Applications that compile the generated sources must add the packages used by
their selected generator preset, such as Dio, Retrofit, Freezed, and their
associated code generators. Run `build_runner` in the consuming application
after generation when Freezed or JSON serialization output is required.
The example configuration disables `build_runner` so that the generator itself
can be demonstrated without adding those application dependencies to this
package.
+26
View File
@@ -0,0 +1,26 @@
input:
swagger_urls:
- ./openapi.yaml
output:
base_dir: ./generated
api_dir: ./generated/api
models_dir: ./generated/models
split_by_tags: true
clean_stale_files: true
generation:
preset:
name: koi_flutter
models:
enum_unknown_fallback: true
enum_mappings:
PetStatus:
- value: pending
name: awaitingReview
description: Waiting for a store review
formatting:
run_dart_fix: false
run_dart_format: true
run_build_runner: false
+42 -18
View File
@@ -4,22 +4,24 @@ import 'package:koi_swagger_parser/koi_swagger_parser.dart';
import 'package:path/path.dart' as p;
Future<void> main() async {
final packageRoot = Directory.current.path;
final tempDir = await Directory.systemTemp.createTemp(
'koi_swagger_parser_example_',
);
final configFile = File(p.join(tempDir.path, 'koi_swagger_parser.yaml'));
await configFile.writeAsString('''
try {
final exampleDirectory = _findExampleDirectory();
final openApiPath = p.join(exampleDirectory.path, 'openapi.yaml');
final outputDirectory = p.join(tempDir.path, 'generated');
final configFile = File(p.join(tempDir.path, 'koi_swagger_parser.yaml'));
await configFile.writeAsString('''
input:
swagger_urls:
- url: ${p.join(packageRoot, 'test', 'fixtures', 'dba_openapi.json')}
enabled: true
- ${_yamlString(openApiPath)}
output:
base_dir: ${p.join(tempDir.path, 'lib', 'src')}
included_tags:
- stores
- materials
base_dir: ${_yamlString(outputDirectory)}
api_dir: ${_yamlString(p.join(outputDirectory, 'api'))}
models_dir: ${_yamlString(p.join(outputDirectory, 'models'))}
manifest_path: ${_yamlString(p.join(tempDir.path, 'manifest.json'))}
generation:
api:
@@ -27,17 +29,39 @@ generation:
mode: passthrough
formatting:
run_dart_format: false
run_dart_format: true
''');
final result = await const KoiSwaggerParser().generate(
configPath: configFile.path,
dryRun: true,
);
final result = await const KoiSwaggerParser().generate(
configPath: configFile.path,
);
print(
'loaded ${result.sourceDocuments.length} source(s), '
'parsed ${result.operationsCount} operation(s), '
'rendered ${result.modelsCount} model(s).',
print(
'Loaded ${result.sourceDocuments.length} source(s), '
'parsed ${result.operationsCount} operation(s), and '
'generated ${result.writtenFiles.length} file(s) for '
'${result.modelsCount} model(s):',
);
for (final file in result.writtenFiles) {
print(' ${p.relative(file, from: outputDirectory)}');
}
} finally {
await tempDir.delete(recursive: true);
}
}
Directory _findExampleDirectory() {
final scriptDirectory = File.fromUri(Platform.script).parent;
final workingDirectory = Directory(p.join(Directory.current.path, 'example'));
for (final directory in <Directory>[scriptDirectory, workingDirectory]) {
if (File(p.join(directory.path, 'openapi.yaml')).existsSync()) {
return directory;
}
}
throw StateError(
'Could not find example/openapi.yaml. Run this example from the package '
'root with "dart run example/koi_swagger_parser_example.dart".',
);
}
String _yamlString(String value) => "'${value.replaceAll("'", "''")}'";
+78
View File
@@ -0,0 +1,78 @@
openapi: 3.0.3
info:
title: Pet Store example
version: 1.0.0
servers:
- url: https://api.example.com/v1
tags:
- name: Pets
paths:
/pets:
get:
tags:
- Pets
operationId: listPets
summary: List pets
parameters:
- name: limit
in: query
required: false
schema:
type: integer
format: int32
minimum: 1
responses:
'200':
description: A list of pets
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
/pets/{petId}:
get:
tags:
- Pets
operationId: getPet
summary: Get a pet by ID
parameters:
- name: petId
in: path
required: true
schema:
type: string
responses:
'200':
description: The requested pet
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'404':
description: Pet not found
components:
schemas:
Pet:
type: object
required:
- id
- name
- status
properties:
id:
type: string
name:
type: string
status:
$ref: '#/components/schemas/PetStatus'
PetStatus:
type: string
enum:
- available
- pending
- sold
x-enumNames:
- available
- pendingReview
- sold