{"id":50417914,"url":"https://github.com/angeloavv/dart_openapi_generator","last_synced_at":"2026-05-31T07:02:05.098Z","repository":{"id":356379032,"uuid":"1231706193","full_name":"AngeloAvv/dart_openapi_generator","owner":"AngeloAvv","description":"OpenAPI 3.x → Dart code generator for Flutter and Dart","archived":false,"fork":false,"pushed_at":"2026-05-07T20:39:43.000Z","size":144,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T21:15:22.176Z","etag":null,"topics":["build-runner","dart","flutter","generator","openapi"],"latest_commit_sha":null,"homepage":"https://docs.page/angeloavv/dart_openapi_generator","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AngeloAvv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-07T07:56:32.000Z","updated_at":"2026-05-07T20:39:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/AngeloAvv/dart_openapi_generator","commit_stats":null,"previous_names":["angeloavv/dart_openapi_generator"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/AngeloAvv/dart_openapi_generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngeloAvv%2Fdart_openapi_generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngeloAvv%2Fdart_openapi_generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngeloAvv%2Fdart_openapi_generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngeloAvv%2Fdart_openapi_generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AngeloAvv","download_url":"https://codeload.github.com/AngeloAvv/dart_openapi_generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngeloAvv%2Fdart_openapi_generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33722156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build-runner","dart","flutter","generator","openapi"],"created_at":"2026-05-31T07:02:04.099Z","updated_at":"2026-05-31T07:02:05.092Z","avatar_url":"https://github.com/AngeloAvv.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dart_openapi_generator\n\nOpenAPI 3.x → Dart code generator for Flutter and Dart. Point it at a spec (YAML or JSON, local file or HTTPS URL) and get Dio-based model classes and API client services — generated via `build_runner`, no JVM, no Mustache, no runtime annotation libraries in your dependency tree.\n\n## Packages\n\n| Package | pub.dev | Description |\n|---------|---------|-------------|\n| [`dart_openapi_generator_annotations`](packages/dart_openapi_generator_annotations/) | [![pub](https://img.shields.io/pub/v/dart_openapi_generator_annotations.svg)](https://pub.dev/packages/dart_openapi_generator_annotations) | `@OpenApiGenerator`, `LocalSpec`, `RemoteSpec`, `DateTimeConverter` — zero runtime deps beyond `meta` |\n| [`dart_openapi_generator`](packages/dart_openapi_generator/) | [![pub](https://img.shields.io/pub/v/dart_openapi_generator.svg)](https://pub.dev/packages/dart_openapi_generator) | `build_runner` builder (dev dependency only) |\n\n## Documentation\n\nFull documentation at **[docs.page/angeloavv/dart_openapi_generator](https://docs.page/angeloavv/dart_openapi_generator)**.\n\n## Quick Start\n\n```yaml\n# pubspec.yaml\ndependencies:\n  dart_openapi_generator_annotations: ^0.1.0\n  dio: ^5.0.0\n\ndev_dependencies:\n  dart_openapi_generator: ^0.1.0\n  build_runner: ^2.4.0\n```\n\n## Usage\n\nCreate a marker class in any Dart file and annotate it with `@OpenApiGenerator`:\n\n```dart\nimport 'package:dart_openapi_generator_annotations/dart_openapi_generator_annotations.dart';\n\n@OpenApiGenerator(\n  inputSpec: LocalSpec('openapi/api.yaml'),\n  outputDir: 'lib/generated',\n  clientName: 'MyApiClient',\n)\nclass $MyApp {}\n```\n\nThen run:\n\n```sh\ndart run build_runner build\n```\n\nThe generator writes all files directly into `lib/generated/`. No `part`/`part of` directives are used.\n\n## What Gets Generated\n\nFor a spec with a `User` schema and a `users` tag, the generator produces:\n\n```\nlib/generated/\n├── models/\n│   └── user.dart          ← final class User with fromJson / toJson / copyWith / == / hashCode\n├── services/\n│   └── users_api.dart     ← class UsersApi wrapping a Dio instance\n├── api_client.dart        ← MyApiClient with per-tag service accessors and auth interceptor factories\n└── generated.dart         ← barrel export\n```\n\n### Model classes\n\nEach `components/schemas` entry produces one file. Generated classes are `final` and carry no runtime dependencies:\n\n```dart\n// lib/generated/models/user.dart  (generated — do not edit)\nfinal class User {\n  final String id;\n  final String name;\n  final String email;\n  final UserRole? role;\n  final DateTime? createdAt;\n\n  User({\n    required this.id,\n    required this.name,\n    required this.email,\n    this.role,\n    this.createdAt,\n  });\n\n  factory User.fromJson(Map\u003cString, dynamic\u003e json) =\u003e User(\n        id: json['id'] == null\n            ? (throw ArgumentError.notNull('User.id'))\n            : json['id'] as String,\n        // ...\n      );\n\n  Map\u003cString, dynamic\u003e toJson() =\u003e {\n        'id': id,\n        // ...\n      };\n\n  User copyWith({String? id, /* ... */}) =\u003e User(id: id ?? this.id, /* ... */);\n\n  @override\n  bool operator ==(Object other) =\u003e /* ... */;\n\n  @override\n  int get hashCode =\u003e Object.hash(id, name, email, role, createdAt);\n}\n```\n\n### Service classes\n\nOne class per tag. Each method maps to one operation and accepts path parameters as positional arguments, query/header parameters as named arguments, plus optional Dio override params:\n\n```dart\n// lib/generated/services/users_api.dart  (generated — do not edit)\nclass UsersApi {\n  final Dio _dio;\n  const UsersApi(this._dio);\n\n  Future\u003cList\u003cUser\u003e\u003e listUsers({int? page, CancelToken? cancelToken, /* ... */}) async { /* ... */ }\n  Future\u003cUser\u003e createUser(User body, {CancelToken? cancelToken, /* ... */}) async { /* ... */ }\n  Future\u003cUser\u003e getUser(String id, {CancelToken? cancelToken, /* ... */}) async { /* ... */ }\n  Future\u003cvoid\u003e deleteUser(String id, {CancelToken? cancelToken, /* ... */}) async { /* ... */ }\n}\n```\n\n### API client barrel\n\nThe top-level client class exposes each tag as a named field and provides static auth interceptor factories derived from `securitySchemes`:\n\n```dart\nfinal client = MyApiClient(\n  baseUrl: 'https://api.example.com/v1',\n  interceptors: [\n    MyApiClient.bearerAuth('your-token'),\n  ],\n);\n\nfinal users = await client.users.listUsers();\nfinal user  = await client.users.getUser('abc');\n```\n\nAuth factories generated from `securitySchemes`:\n\n| Factory | Scheme type |\n|---------|-------------|\n| `MyApiClient.bearerAuth(token)` | `http` / `bearer` |\n| `MyApiClient.basicAuth(user, password)` | `http` / `basic` |\n| `MyApiClient.apiKeyAuth(key, headerName:)` | `apiKey` / `header` |\n| `MyApiClient.apiKeyQueryAuth(key, paramName:)` | `apiKey` / `query` |\n\n## Annotation Reference\n\n```dart\n@OpenApiGenerator(\n  inputSpec: LocalSpec('openapi/api.yaml'),   // required — local file path relative to package root\n  outputDir: 'lib/generated',                // required — output directory relative to package root\n  clientName: 'ApiClient',                  // optional — name of the generated top-level class (default: 'ApiClient')\n  skipIfSpecIsUnchanged: true,               // optional — skip generation on MD5 cache hit (default: true)\n  cachePath: '.dart_tool/dart_openapi_generator_cache', // optional — cache directory (default shown)\n  cleanOutput: true,                         // optional — delete previously generated files before writing (default: true)\n  dateTimeConverter: DateTimeConverter.iso8601, // optional — iso8601 (default) or timestamp\n  debugLogging: false,                       // optional — log every file written/deleted (default: false)\n)\nclass $MyApp {}\n```\n\n### `InputSpec` variants\n\n```dart\n// Local file (path relative to pubspec.yaml)\ninputSpec: LocalSpec('openapi/api.yaml')\n\n// Remote HTTPS URL — HTTPS required, optional auth headers\ninputSpec: RemoteSpec('https://petstore3.swagger.io/api/v3/openapi.json')\ninputSpec: RemoteSpec(\n  'https://example.com/api.json',\n  headers: {'Authorization': 'Bearer token'},\n)\n```\n\n### `DateTimeConverter`\n\n| Value | `fromJson` | `toJson` |\n|-------|-----------|---------|\n| `DateTimeConverter.iso8601` (default) | `DateTime.parse(v as String)` | `.toIso8601String()` |\n| `DateTimeConverter.timestamp` | `DateTime.fromMillisecondsSinceEpoch(v as int)` | `.millisecondsSinceEpoch` |\n\n## Schema Type Support\n\n| OpenAPI schema type | Generated Dart |\n|---------------------|----------------|\n| `object` | `final class` with named fields, `fromJson` / `toJson` / `copyWith` / `==` / `hashCode` |\n| `enum` (string, integer, number) | Dart `enum` with `fromJson` / `toJson` |\n| `allOf` | Flat-merged `final class` (properties from all `ObjectSchema` members combined) |\n| `oneOf` with discriminator | `sealed class` parent + one `final class` per variant, switch-expression `fromJson` |\n| Primitive (`string`, `integer`, `number`, `boolean`) | `typedef` alias |\n| Array top-level | `typedef` alias to `List\u003cT\u003e` |\n| `string` + `format: date-time` | `DateTime` (ISO 8601 or epoch per `dateTimeConverter`) |\n| `additionalProperties` | `Map\u003cString, T\u003e` field (`additionalProperties` on the class) |\n\n## Caching\n\nWhen `skipIfSpecIsUnchanged: true` (the default), the generator computes an MD5 cache key from:\n\n- Raw spec bytes\n- Generator version\n- Annotation fields that affect output (`outputDir`, `clientName`, `dateTimeConverter`, `cleanOutput`)\n\nOn a cache hit the build step is a no-op. Cache entries live under `cachePath` (default `.dart_tool/dart_openapi_generator_cache`) and are written atomically (temp-file rename) to survive concurrent `build_runner` invocations.\n\n## Repository Structure\n\n```\ndart_openapi_generator/\n├── packages/\n│   ├── dart_openapi_generator_annotations/  ← annotation types (runtime dep)\n│   │   └── lib/src/\n│   │       ├── open_api_generator.dart      ← @OpenApiGenerator\n│   │       ├── input_spec.dart              ← LocalSpec, RemoteSpec (sealed)\n│   │       └── date_time_converter.dart     ← DateTimeConverter enum\n│   └── dart_openapi_generator/              ← build_runner builder (dev dep)\n│       └── lib/src/\n│           ├── builder/                     ← OpenApiBuilder (build_runner entry)\n│           ├── parser/                      ← OpenAPI 3.x YAML/JSON parser\n│           ├── generator/                   ← ModelGenerator, ServiceGenerator, AggregatorGenerator\n│           ├── writer/                      ← FileWriter (format, clean, manifest)\n│           ├── spec_loader.dart             ← LocalSpecLoader, RemoteSpecLoader\n│           └── cache_manager.dart           ← MD5 cache keying + atomic writes\n├── example/                                 ← consumer project exercising v0.1.0 features\n│   ├── openapi/example_api.yaml\n│   └── lib/\n│       ├── main.dart                        ← @OpenApiGenerator marker + usage example\n│       └── generated/                       ← regenerated by CI\n├── docs/                                    ← docs.page MDX source\n└── pubspec.yaml                             ← pub workspace root\n```\n\n## Running Tests\n\n```sh\ndart test packages/dart_openapi_generator_annotations/test/\ndart test packages/dart_openapi_generator/test/\n```\n\nEnd-to-end validation with the example project:\n\n```sh\ncd example\ndart pub get\ndart run build_runner build --delete-conflicting-outputs\ndart analyze lib/generated/\n```\n\n## Contributing\n\n1. Fork the repository and create a feature branch.\n2. Keep `dart analyze` clean and `dart format` idempotent.\n3. Add or update tests for any changed behaviour. Run `dart test` in each affected package.\n4. Open a pull request describing what changed and why.\n\nBug reports and feature requests: [issue tracker](https://github.com/AngeloAvv/dart_openapi_generator/issues).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangeloavv%2Fdart_openapi_generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangeloavv%2Fdart_openapi_generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangeloavv%2Fdart_openapi_generator/lists"}